Вот лучшее решение, которое я мог бы придумать, используя потоки:
public class Solution {
private static String sortString(String str) {
char[] chars = str.toCharArray();
Arrays.sort(chars);
return new String(chars);
}
public List<List<String>> groupAnagrams(String[] strs) {
if (strs == null) {
return new ArrayList<>();
}
return new ArrayList<>(Arrays.stream(strs)
.collect(Collectors.groupingBy(Solution::sortString))
.values());
}
}
Примечания:
Начиная с простого, мы создаем поток из массива strs
с помощью служебного метода Arrays.stream(array)
:
Arrays.stream(strs);
Метод Stream#collect(collector)
принимает поток и преобразует его в стандартный тип коллекции (Map
, List
и т. Д..):
Arrays.stream(strs)
.collect(...);
В этом случае мы будем использовать Collectors.groupingBy(classifier)
.Этот сборщик сортирует ваш поток в «бины», причем метка бина определяется результатом передачи каждого значения через функцию classifier
lambda.Тип возвращаемого значения - Map<K, List<V>>
(где K
- это тип метки, а V
- это любой тип, который мы передаем в потоковом режиме) - та же самая форма, которую вы использовали для переменной map
:
Arrays.stream(strs)
.collect(Collectors.groupingBy(...));
Но какую функцию мы передаем .groupingBy()
?Поскольку вы хотите группировать по отсортированной строке, нам нужна функция, которая будет создавать отсортированную строку из обычной.Мы собираемся использовать вашу существующую функцию для этого:
Arrays.stream(strs)
.collect(Collectors.groupingBy(str -> {
char[] chars = word.toCharArray();
Arrays.sort(chars);
return new String(chars);
}));
В целях обеспечения потоковой передачи мы заменим эту функцию на другой stream *: ( Оказывается, char
s не передается нормально )
В интересах аккуратности я реорганизовал лямбда-функцию в статический метод для вашего класса:
private static String sortString(String str) {
char[] chars = str.toCharArray();
Arrays.sort(chars);
return new String(chars);
}
Arrays.stream(strs)
.collect(Collectors.groupingBy(str -> {
return Solution.sortString(str);
}));
Поскольку мы делаем один вызов функции, которая принимает только один параметр, мы можем использовать ссылку на метод вместо лямбда-функции:
Arrays.stream(strs)
.collect(Collectors.groupingBy(Solution::sortString));
Остальноеочень похоже на ваш существующий код.Используя Map#values()
, уберите ключи из набора данных, затем оберните полученный Collection
в ArrayList
:
new ArrayList<>(Arrays.stream(strs)
.collect(Collectors.groupingBy(Solution::sortString))
.values());