我遇到了一个小问题,我需要在对字符串列表执行的操作中保留顺序,并使用java streams中的collect
方法。
public List<String> countOccurrences(ArrayList<String> messages) {
List<String> stackedMessages = new LinkedList<>();
HashMap<String, Integer> messageOccurrences =
messages.stream()
.collect(groupingBy(Function.identity(), summingInt(e -> 1)));
messageOccurrences.forEach((key, value) -> {
String appendString = value == 1 ? "" : " (" + value + " times)";
stackedMessages.add(key + appendString);
});
return stackedMessages;
}
上面代码的问题是,如果我处理一个像["blah", "blah", "yep"]
这样的列表,它会返回["yep", "blah (2 times)"]
,而我需要它返回["blah (2 times)", "yep"]
。
我已经看过这篇文章了,我相信如果我在已经排序的数据结构上使用流,那么顺序就会得到保证:How to ensure order of processing in java8 streams?
我认为我需要将groupingBy
更改为toMap
,目前我正在阅读该文档。任何已经精通这个主题的人都可以提供一些建议。
更新:
感谢用户@Aominè,这是使用groupingBy的正确方法
.collect(groupingBy(Function.identity(),LinkedHashMap::new, summingInt(e->1)))
发布于 2018-06-06 02:05:55
您需要收集到LinkedHashMap
才能获得预期的结果。此外,您不必在groupingBy
之后从流管道单独执行另一个forEach
,只需从entrySet
和map
创建一个流,然后收集到列表即可。
return messages.stream()
.collect(groupingBy(Function.identity(), LinkedHashMap::new, summingInt(e -> 1)))
.entrySet()
.stream()
.map(e -> e.getKey()+(e.getValue() == 1 ? "" : " (" + e.getValue() +" times)"))
.collect(toList());
https://stackoverflow.com/questions/50706034
复制相似问题