使用collect保留Java流中的顺序 [英] Preserve order in Java stream with collect

查看:480
本文介绍了使用collect保留Java流中的顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个问题,我需要在执行字符串列表并使用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,只需从entrySetmap创建一个流,然后收集到列表中即可.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆