当前位置: 首页 > 知识库问答 >
问题:

分组后,流不保留顺序

琴刚豪
2023-03-14

我有一个可用的列表名,我正在按blockIndex属性对这些列表进行排序和分组,如下所示:

availableSeats.stream()
                .sorted(Comparator.comparing(SeatedTicketAssignment::getBlockIndex))
                .collect(Collectors.groupingBy(SeatedTicketAssignment::getBlockIndex))
                .forEach((block, blockAssignments) -> {
                     //Rest of the code
                } 

问题是分组的结果不按block Index排序。

共有3个答案

宗弘扬
2023-03-14

由于groupingBy收集器不需要排序输入,因此您可以在收集后对组进行排序。这将比先排序项目更快,无论如何,假设组比项目少:

availableSeats.stream()
        .collect(Collectors.groupingBy(SeatedTicketAssignment::getBlockIndex))
        .entrySet().stream()
        .sorted(Comparator.comparing(Map.Entry::getKey))
        .forEach(mapEntry -> {
             //Rest of the code
        } 
充栋
2023-03-14

不幸的是,Stream API实现没有意识到这样一个事实,即您传递的流已经按照您需要的内容进行了排序,因此“分组”实际上是微不足道的。因此,它使用了与此SO答案基本相似的默认方式,即为组创建一个Map并用流的元素填充它。默认情况下,使用的Map实现是HashMap(请参阅此处的html" target="_blank">代码),它有利于性能原因,但不利于您的目标,因为HashMap不会保留键的顺序而不是第一次排序。

Group By在Stream API中仅作为“收集器”实现,这似乎有点不走运,因此您不能先分组,然后在一行中进行排序。但这似乎是有意的:没有完全实现结果就无法实现Group By,因此它不能偷懒,因此必须是收集器。@Rogue为LinkedHashMap提供了一个很好的技巧,但对我来说,它是绑定到实现细节的。尽管如此,我会再写几行代码和第一组,然后按键对列表的条目(即实际分组的HashMap)进行排序。很可能会更快。

吕征
2023-03-14

请记住,收集器#groupingBy(Function)将返回一个HashMap,它不保证顺序。如果您希望排序按照聚合标识(您的i%2==0结果)显示的顺序,那么您可以使用LinkedHashMap

.collect(Collectors.groupingBy(i -> i % 2 == 0, LinkedHashMap::new, Collectors.toList()))

将返回LinkedHashMap

 类似资料:
  • 假设我有一个包含3个应用程序的流——一个源、处理器和接收器。 我需要保留从源收到的消息的顺序。当我收到消息A,B,C,D,我必须将它们作为A,B,C,D.发送到接收器(我不能将它们作为B,A,C,D)发送。 如果每个应用程序只有一个实例,那么一切都将按顺序运行,并且顺序将被保留。 如果我每个应用程序有 10 个实例,则消息 A、B、C、D 可能会在不同的实例中同时处理。我不知道这些消息的顺序是什么

  • 问题内容: Java Set是否保留顺序?有一种方法将Set返回给我,并且假定数据是有序的,但是遍历Set时,数据是无序的。有没有更好的方法来解决这个问题?是否需要更改方法以返回Set以外的内容? 问题答案: 该Set接口不提供任何订购保证。 它的子接口代表根据某种标准排序的集合。在Java 6中,有两个实现的标准容器。他们是和。 除了SortedSet接口之外,还有类。它记住元素插入到集合中的顺

  • 包含由管道分隔的数字列表的文件可以有重复项。需要编写map reduce程序,在原始输入顺序中列出不重复的数字。我可以删除重复项,但不保留输入顺序。

  • Java集是否保持顺序?一个方法返回一个集合给我,假设数据是有序的,但是在集合上迭代,数据是无序的。有更好的方法来管理这个吗?这个方法需要改变来返回集合以外的东西吗?

  • 问题内容: 我在pandas数据框上使用来删除没有特定列的最小值的所有行。像这样: 但是,如果我不止这两列,其他列(例如在我的示例中)将被删除。我可以使用保留这些列,还是必须找到一种不同的方式删除行? 我的数据如下: 并应以如下形式结束: 但是我得到的是: 我一直在浏览文档,找不到任何东西。我试过了: 但是这些都不起作用(我在最后一个中意识到,语法是在创建组后进行聚合的)。 问题答案: 方法1:使

  • 问题内容: 我正在创建一个JavaScript对象,如下所示 之后,我将它们如下 上面的方法是否按照对象先前的顺序对它们进行了字符串化处理?字符串化后,它们将按照以前的顺序排列为0,1,2 .... 9吗? 问题答案: 文档中没有任何内容可以明确确认数组项的顺序已保留。但是,文档指出,对于非数组属性,不能保证顺序: 非数组对象的属性不能保证以任何特定顺序进行字符串化。不要依赖于字符串化中同一对象内