使用collect保留Java流中的顺序 [英] Preserve order in Java stream with collect
问题描述
我遇到了一个问题,我需要在执行字符串列表并使用java流api中的collect
方法执行的操作中保留顺序.
I am running into a bit of an issue where I need order preserved in an operation being performed on a list of strings and using the collect
method from the java streams api.
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"]
.
The problem with the above code is if I process a list such as ["blah", "blah", "yep"]
, it returns ["yep", "blah (2 times)"]
where I need it to return ["blah (2 times)", "yep"]
.
我已经在这里查看过这篇文章,并被认为如果我在已经订购的数据结构上使用流,那么可以确保订购:
I looked at this post here already and was lead to believe if I am using a stream on an already ordered data structure then order would be ensured: How to ensure order of processing in java8 streams?
我认为我需要将groupingBy
更改为toMap
,并且截至目前,我正在阅读该文档.任何精通该主题的人都请提供一些指示.
I'm thinking I need to change groupingBy
to toMap
and as of right now I am reading through that documentation. Anybody who is well versed in the subject matter already please offer some pointers.
更新:
感谢用户@Aominè,这是使用groupingBy的正确方法
Thanks to the user @Aominè, this is the correct way to do it using groupingBy
.collect(groupingBy(Function.identity(),LinkedHashMap::new, summingInt(e->1)))
推荐答案
您需要收集到LinkedHashMap
以获得预期的结果.另外,您不必在groupingBy
之后从流管道中单独执行另一个forEach
,只需从entrySet
和map
创建一个流,然后收集到列表中即可.
You’ll need to collect to a LinkedHashMap
to get the expected result. Also, you don’t have to do another forEach
separately from the stream pipeline after the groupingBy
, just create a stream from the entrySet
and map
then collect to list.
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());
这篇关于使用collect保留Java流中的顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!