我有一个Java的现有代码,我想用Java 8编写 .
有人可以提供将此代码移植到Java 8的建议 .
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> result = new ArrayList();
Map<String, List<String>> map = new HashMap();
if (strs == null || strs.length == 0) return result;
for (String word: strs) {
char[] wordArr = word.toCharArray();
Arrays.sort(wordArr);
String sortedWord = new String(wordArr);
if (map.containsKey(sortedWord)) {
List<String> list = map.get(sortedWord);
list.add(word);
map.put(sortedWord, list);
} else {
List<String> list = new ArrayList();
list.add(word);
map.put(sortedWord, list);
}
}
return new ArrayList(map.values());
}
}
UPDATE - 我用过getOrDefault()
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> result = new ArrayList();
Map<String, List<String>> map = new HashMap();
if (strs == null || strs.length == 0) return result;
for (String word: strs) {
char[] wordArr = word.toCharArray();
Arrays.sort(wordArr);
String sortedWord = new String(wordArr);
List<String> list = map.getOrDefault(sortedWord, new ArrayList());
list.add(word);
map.put(sortedWord, list);
}
return new ArrayList(map.values());
}
}
还有别的办法吗?
6 Answers
这是我使用流可以提出的最佳解决方案:
注意:
从简单开始,我们使用实用方法Arrays.stream(array)从数组
strs
创建一个流:Stream#collect(collector)方法接受一个流并将其转换为标准集合类型(
Map
,List
等):在这种情况下,我们将使用Collectors.groupingBy(classifier) . 此收集器将您的流分类为'bins',其中bin标签由通过
classifier
lambda函数传递每个值的结果指定 . 返回类型是Map<K, List<V>>
(其中K
是标签类型,V
是我们流式传输的任何类型) - 与map
变量使用的形状相同:但是我们通过什么功能
.groupingBy()
?由于您希望按排序字符串进行分组,因此我们需要一个能够从常规字符串创建排序字符串的函数 . 我们将使用您现有的功能:为了流畅,我们用另一个流替换该函数* :(事实证明
char
s不能很好地流动)为了整洁,我已经将lambda函数重构为类中的静态方法:
由于我们只对一个只接受一个参数的函数进行单次调用,因此我们可以使用方法引用而不是lambda函数:
其余的与您现有的代码非常相似 . 使用Map#values()从数据集中剥离键,然后将结果
Collection
包装在_60415中:This answer provides a java-stream解决方案,我个人会继续 . 至于你目前的实现,你是非常接近,但
computeIfAbsent
将是更好的方法继续:我很确定你知道大多数代码的作用所以我只会通过引用大部分文档来解释上面的computeIfAbsent部分,因为它是最好的解释 .
下次我们尝试添加已经存在于 Map 中的键时,将返回与指定键关联的现有列表,并使用上面的
.add(word)
将该单词添加到其中 .你基本上是在寻找groupingBy收藏家:
首先,我们在调用
Arrays.stream(strs)
时创建一个Stream,然后使我们能够使用collect
执行缩减操作,此方法使用收集器,其中此收集器是groupingBy
.groupingBy
收集器的这种重载产生Map<K, List<T>>
,其中键是将分类函数应用于输入元素(即Arrays.stream(s.split("")).sorted().collect(joining())
)得到的值,其对应值是包含映射到分类函数下的关联键的输入元素的列表 .最后,我们调用
values()
来检索Collection<List<String>>
并将其传递给ArrayList
构造函数并返回 .读你可能会觉得有趣:
Collectors documentation
Streams documentation
Introduction to Java 8 Streams
Java 8: An Introduction to Streams
使用Optional和streams以及一些静态导入:
如果你想使用
Streams
参考其他答案,如果你想知道如何使用Map
操作来简化你的if / else,它是:它是
key
不在map
中,用empty list
添加它,然后得到list
和add
word
:来自Aomine的答案很好,但可以重写更短的内容: