title: Java 8 Stream function to group a List of anagrams into a Map of Lists
body: <p>Java 8 is about to be released... While learning about Streams, I got into a scenario about grouping anagrams using one of the new ways. The problem I'm facing is that I can't find a way to group Strings objects using the map/reduce functions. Instead, I had to create a similar way as documented at <a href="http://docs.oracle.com/javase/tutorial/collections/streams/reduction.html" rel="nofollow noreferrer">Aggregate Operations - Reduction</a>.</p>
  <p>Based on the documentation, we can simply use:</p>
  <pre class="lang-java prettyprint-override"><code>LIST&lt;T&gt;.stream().collect(Collectors.groupingBy(POJO::GET_METHOD))
  </code></pre>
  <p>So that <code>Collectors.groupingBy()</code> will aggregate the keys of the map based on the method used. However, this approach is too seems to be cumbersome to wrap a simple String presentation.</p>
  <pre class="lang-java prettyprint-override"><code>public class AnagramsGrouping {
      static class Word {
          public String original;
  
          public Word(String word) {
              original = word;
          }
  
          public String getKey() {
              char[] characters = input.toCharArray();
              Arrays.sort(characters);
              return new String(characters);
          }
  
          public String toString() {
              return original;
          }
      }
  
      public static void main(String[] args) {
          List&lt;Word&gt; words = Arrays.asList(new Word(&quot;pool&quot;), new Word(&quot;loop&quot;),
                  new Word(&quot;stream&quot;), new Word(&quot;arc&quot;), new Word(&quot;odor&quot;),
                  new Word(&quot;car&quot;), new Word(&quot;rood&quot;), new Word(&quot;meats&quot;),
                  new Word(&quot;fires&quot;), new Word(&quot;fries&quot;), new Word(&quot;night&quot;),
                  new Word(&quot;thing&quot;), new Word(&quot;mates&quot;), new Word(&quot;teams&quot;));
  
          Map&lt;String, List&lt;Word&gt;&gt; anagrams = words.stream().collect(
                  Collectors.groupingBy(Word::getKey));
  
          System.out.println(anagrams);
      }
  }
  </code></pre>
  <p>This prints the following:</p>
  <pre><code>{door=[odor, rood], acr=[arc, car], ghint=[night, thing],
   aemrst=[stream], efirs=[fires, fries], loop=[pool, loop],
   aemst=[meats, mates, teams]}
  </code></pre>
  <p>Instead, I'm looking for a simpler and more direct solution that uses the new map/reduce functions to accumulate the results into the similar interface <code>Map&lt;String, List&lt;String&gt;</code>. Based on <a href="https://stackoverflow.com/a/20887747/433814">How to convert List to Map</a>, I have the following:</p>
  <pre class="lang-java prettyprint-override"><code>List&lt;String&gt; words2 = Arrays.asList(&quot;pool&quot;, &quot;loop&quot;, &quot;stream&quot;, &quot;arc&quot;,
          &quot;odor&quot;, &quot;car&quot;, &quot;rood&quot;, &quot;meats&quot;, &quot;fires&quot;, &quot;fries&quot;,
          &quot;night&quot;, &quot;thing&quot;, &quot;mates&quot;, &quot;teams&quot;);
  
  words2.stream().collect(Collectors.toMap(w -&gt; sortChars(w), w -&gt; w));
  </code></pre>
  <p>But this code generates a key collision as it is a Map of 1-1.</p>
  <pre><code>Exception in thread &quot;main&quot; java.lang.IllegalStateException: Duplicate key pool
  </code></pre>
  <p>which makes sense... Is there a way to group them into the similar output as the first solution with <code>groupingBy</code>, but without using a POJO wrapping the values?</p>