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 Aggregate Operations - Reduction.
Based on the documentation, we can simply use:
LIST<T>.stream().collect(Collectors.groupingBy(POJO::GET_METHOD))
So that Collectors.groupingBy() 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.
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<Word> words = Arrays.asList(new Word("pool"), new Word("loop"),
                new Word("stream"), new Word("arc"), new Word("odor"),
                new Word("car"), new Word("rood"), new Word("meats"),
                new Word("fires"), new Word("fries"), new Word("night"),
                new Word("thing"), new Word("mates"), new Word("teams"));
        Map<String, List<Word>> anagrams = words.stream().collect(
                Collectors.groupingBy(Word::getKey));
        System.out.println(anagrams);
    }
}
This prints the following:
{door=[odor, rood], acr=[arc, car], ghint=[night, thing],
 aemrst=[stream], efirs=[fires, fries], loop=[pool, loop],
 aemst=[meats, mates, teams]}
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 Map<String, List<String>. Based on How to convert List to Map, I have the following:
List<String> words2 = Arrays.asList("pool", "loop", "stream", "arc",
        "odor", "car", "rood", "meats", "fires", "fries",
        "night", "thing", "mates", "teams");
words2.stream().collect(Collectors.toMap(w -> sortChars(w), w -> w));
But this code generates a key collision as it is a Map of 1-1.
Exception in thread "main" java.lang.IllegalStateException: Duplicate key pool
which makes sense... Is there a way to group them into the similar output as the first solution with groupingBy, but without using a POJO wrapping the values?
 
    