title: Efficiently checking for substrings and replacing them - can I improve performance here?
body: <p>I need to examine millions of strings for abbreviations and replace them with the full version.  Due to the data, only abbreviations terminated by a comma should be replaced.  Strings can contain multiple abbreviations.</p>
  
  <p>I have a lookup table that contains Abbreviation->Fullversion pairs, it contains about 600 pairs.</p>
  
  <p>My current setup looks like something this.  On startup I create a list of ShortForm instances from a csv file using Jackson and hold them in a singleton:</p>
  
  <pre><code>public static class ShortForm{
      public String fullword;
      public String abbreviation;
  }
  
  List&lt;ShortForm&gt; shortForms = new ArrayList&lt;ShortForm&gt;();
  //csv code ommited
  </code></pre>
  
  <p>And some code that uses the list</p>
  
  <pre><code>for (ShortForm f: shortForms){
      if (address.contains(f.abbreviation+","))
          address = address.replace(f.abbreviation+",", f.fullword+",");
  }
  </code></pre>
  
  <p>Now this works, but it's <em>slow</em>.  Is there a way I can speed it up?  The first step is to load the ShortForm objects with commas in place, but what else could I do?</p>
  
  <p>====== <em>UPDATE</em>
  Changed code to work the other way around.  Splits strings into words and checks a set to see if the string is an abbreviation. </p>
  
  <pre><code>    StringBuilder fullFormed = new StringBuilder();
      for (String s: Splitter.on(" ").split(add)){
          if (shortFormMap.containsKey(s))
              fullFormed.append(shortFormMap.get(s));
          else
              fullFormed.append(s);
          fullFormed.append(" ");
      }
  
      return fullFormed.toString().trim();
  </code></pre>
  
  <p>Testing shows this to be over 13x faster that the original approach.  Cheers davecom!</p>