Используя Java 8, каков наиболее сжатый способ создания отсортированного и сгруппированного списка строк

Использование Java 8, что является наиболее кратким способом создания отсортированного и сгруппированного списка строк? Покажите старый способ и новый способ, используя Lambdas и структуру Collections and Streams.

Вы можете показать использование сторонних библиотек (популярных) для старого (или нового) способа.

Однако я предлагаю использовать ванильную Java, потому что в ней отображаются изменения, которые язык изменяет в Java 8, в таблицу для задачи.

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

Он будет отсортирован и сгруппирован таким образом, чтобы...

Учитывая этот список: "Пиво", "Яблоко", "Банан", "Ананас", "Манго", "Синяя ягода"

A Map будет выпущен, содержащий первую букву в качестве ключа. Значения на карте будут отсортированы List всех слов, начинающихся с этого ключа (буквы):

  • : значения: [ "Ананас", "Яблоко" ]
  • : значения B: [ "Банан", "Пиво", "Синяя ягода" ]
  • : значения M: [ "Mango" ]

Ответ 1

Используя Java, без помощи сторонних библиотек, существует старый способ и новый способ. Просто сортировка была простой с Collections.sort(..).

Проблема со старым способом заключалась в том, что для группировки значений требуется много кода.

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

Старая 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); 

Новая 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);

Новая Java 8 с исходными данными уже как "поток"

Как было предложено @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);

Ответ 2

С популярной сторонней Guava библиотекой, совместимой с Java 6:

TreeMultimap<Character, String> multimap = TreeMultimap.create();
for (String string : list) {
  multimap.put(string.charAt(0), string);
}
return Multimaps.asMap(ImmutableListMultimap.copyOf(multimap));

Это дедуплицирует строки, поэтому альтернативная версия, которая позволяет дублировать строки:

ImmutableListMultimap.Builder<Character, String> builder = 
  ImmutableListMultimap.builder();
for (String string : Ordering.natural().sortedCopy(list)) {
  builder.put(string.charAt(0), string);
}
return Multimaps.asMap(builder.build());