title: Java Map replaceAll with multiple String matches
body: <p>I have the following program that I would like to replace all occurrences of a string where a word exists as a key in a map with its corresponding value.</p>
  
  <p>I have implemented 4 methods. Each of them perform roughly the same function but in a different way. The output for the first 3 are incorrect as the next replacement overrides the result of the previous. The fourth works, but only because I am replacing single characters in the whole string. This is very inefficient anyways, because I am only checking a substring of the entire string.</p>
  
  <p>Is there a way to safely replace all occurrences without overwriting the previous replacements?</p>
  
  <p>I noticed that Apache has a <code>StringUtils.replaceEach()</code> method, but I would prefer to use a map.</p>
  
  <p><strong>Output:</strong></p>
  
  <pre><code>Apple BApplenApplenApple CApplentApplelope DApplete Apple BApplenApplenApple CApplentApplelope DApplete
  Apple BApplenApplenApple CApplentApplelope DApplete Apple BApplenApplenApple CApplentApplelope DApplete
  Apple BApplenApplenApple CApplentApplelope DApplete Apple BApplenApplenApple CApplentApplelope DApplete
  Apple Banana Cantalope Date Apple Banana Cantalope Date
  </code></pre>
  
  <p><strong>ReplaceMap.java</strong></p>
  
  <pre><code>import java.util.Collection;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.regex.Matcher;
  import java.util.regex.Pattern;
  
  public class ReplaceMap {
      private static Map&lt;String, String&gt; replacements;
  
      static {
          replacements = new HashMap&lt;String, String&gt;();
          replacements.put("a", "Apple");
          replacements.put("b", "Banana");
          replacements.put("c", "Cantalope");
          replacements.put("d", "Date");
      }
  
      public ReplaceMap() {
          String phrase = "a b c d a b c d";
  
          System.out.println(mapReplaceAll1(phrase, replacements));
          System.out.println(mapReplaceAll2(phrase, replacements));
          System.out.println(mapReplaceAll3(phrase, replacements));
          System.out.println(mapReplaceAll4(phrase, replacements));
      }
  
      public String mapReplaceAll1(String str, Map&lt;String, String&gt; replacements) {
          for (Map.Entry&lt;String, String&gt; entry : replacements.entrySet()) {
              str = str.replaceAll(entry.getKey(), entry.getValue());
          }
  
          return str;
      }
  
      public String mapReplaceAll2(String str, Map&lt;String, String&gt; replacements) {
          for (String key : replacements.keySet()) {
              str = str.replaceAll(Pattern.quote(key),
                      Matcher.quoteReplacement(replacements.get(key)));
          }
  
          return str;
      }
  
      public String mapReplaceAll3(String str, Map&lt;String, String&gt; replacements) {        
          String regex = new StringBuilder("(")
              .append(join(replacements.keySet(), "|")).append(")").toString();
          Matcher matcher = Pattern.compile(regex).matcher(str);
  
          while (matcher.find()) {
              str = str.replaceAll(Pattern.quote(matcher.group(1)),
                      Matcher.quoteReplacement(replacements.get(matcher.group(1))));
          }
  
          return str;
      }
  
      public String mapReplaceAll4(String str, Map&lt;String, String&gt; replacements) {        
          StringBuilder buffer = new StringBuilder();
          String regex = new StringBuilder("(")
              .append(join(replacements.keySet(), "|")).append(")").toString();
          Pattern pattern = Pattern.compile(regex);
  
          for (int i = 0, j = 1; i &lt; str.length(); i++, j++) {
              String s = str.substring(i, j);
              Matcher matcher = pattern.matcher(s);
  
  
              if (matcher.find()) {
                  buffer.append(s.replaceAll(Pattern.quote(matcher.group(1)),
                              Matcher.quoteReplacement(replacements.get(matcher.group(1)))));
              } else {
                  buffer.append(s);
              }
          }
  
  
          return buffer.toString();
      }
  
      public static String join(Collection&lt;String&gt; s, String delimiter) {
          StringBuilder buffer = new StringBuilder();
          Iterator&lt;String&gt; iter = s.iterator();
          while (iter.hasNext()) {
              buffer.append(iter.next());
              if (iter.hasNext()) {
                  buffer.append(delimiter);
              }
          }
          return buffer.toString();
      }
  
      public static void main(String[] args) {
          new ReplaceMap();
      }
  }
  </code></pre>