Saint Hill Saint Hill - 1 month ago 7
Java Question

Using Java 8, what is the most concise way of creating a sorted AND grouped list of Strings

Using Java 8, what is the most concise way of creating a sorted AND grouped list of Strings? Show the old way and the new way using Lambdas and the Collections and Streams framework.

You can show using 3rd party libraries (popular ones) for the old (or new) way.

However, I suggest that vanilla Java be used because that shows the changes that the language changes in Java 8 bring to the table for the task.

Input: List<String>
Output: Map<Character<List<String>>
The key of map is 'A' to 'Z'
Each list in the map are sorted.


It will be sorted and grouped such that ...

Given this list: "Beer", "Apple", "Banana", "Ananas", "Mango", "Blue Berry"

A
Map
will produced containing the first letter as the key. The values in the map will be a sorted
List
of all the words beginning with that key (letter):


  • key: A values: ["Ananas","Apple"]

  • key: B values: ["Banana","Beer","Blue Berry"]

  • key: M values: ["Mango"]


Answer

Using Java, with no help from 3rd party libraries, there is the old way and the new way. Just sorting used to be easy with Collections.sort(..).

The challenge with the old way was that a lot of code was required to group the values.

 - Input: List<String>
 - Output: Map<Character,<List<String>>
 - The key of map is 'A' to 'Z'
 - Each list in the map are sorted.

Old Java

List<String> keywords = Arrays.asList("Apple", "Ananas", "Mango", "Banana", "Beer"); 
Map<Character, List<String>> result = new HashMap<Character, List<String>>(); 
for(String k : keywords) {   
    char firstChar = k.charAt(0);     
    if(!result.containsKey(firstChar)) {     
        result.put(firstChar, new  ArrayList<String>());   
    }     
    result.get(firstChar).add(k); 
} 
for(List<String> list : result.values()) {   
    Collections.sort(list); 
}
System.out.println(result); 

New Java 8

List<String> keywords = Arrays.asList("Apple", "Ananas", "Mango", "Banana", "Beer");

Map<Character, List<String>> result = keywords.stream()
     .sorted()
     .collect(Collectors.groupingBy(it -> it.charAt(0)));

System.out.println(result);

New Java 8 with source data already as a 'Stream'

As suggested by @KevinO

 Map<Character, List<String>> result = Stream
      .of( "Apple", "Ananas", "Mango", "Banana","Beer")
      .sorted()
      .collect(Collectors.groupingBy(it -> it.charAt(0)))

System.out.println(result);