简体   繁体   English

Collectors.groupingBy()返回按升序排序的结果java

[英]Collectors.groupingBy() returns result sorted in ascending order java

I am sending result in descending order but I get output with ascending order 我按降序发送结果但是我按升序输出

List<myEntity> myData = new ArrayList<>();
Map<Integer,List<myEntity>> myid = new LinkedHashMap<>();

try {
    myData = myService.getData(id); 
    myid = myData.stream().collect(Collectors.groupingBy(myEntity::getDataId)); 

Here mydata is sorted by desc order but after creating collections by group data id my list get sorted with ascending order. 这里mydata按desc顺序排序,但在按组数据id创建集合后,我的列表按升序排序。 I want my collection list to be descending order not ascending order. 我希望我的收藏列表是降序而不是升序。

As @Holger described in Java 8 is not maintaining the order while grouping , Collectors.groupingBy() returns a HashMap, which does not guarantee order. 由于Java 8中描述的@Holger在分组时不维护顺序 ,因此Collectors.groupingBy()返回一个HashMap,它不保证顺序。

Here is what you can do: 这是你可以做的:

myid = myData.stream()
.collect(Collectors.groupingBy(MyEntity::getDataId,LinkedHashMap::new, toList()));

Would return a LinkedHashMap<Integer, List<MyEntity>> . 将返回LinkedHashMap<Integer, List<MyEntity>> The order will also be maintained as the list used by collector is ArrayList. 订单也将保留,因为收集器使用的列表是ArrayList。

collect(Collectors.groupingBy()) returns a new Map which overwrites the variable to your previous LinkedHashMap . collect(Collectors.groupingBy())返回一个新的Map ,它将变量覆盖到之前的LinkedHashMap Your initial assignment is therefore futile. 因此,您的初始任务是徒劳的。 The exact type returned is undefined by the specs but in my test run it returned a HashMap . 返回的确切类型未在规范中定义,但在我的测试运行中它返回了一个HashMap (Never assume this will always be the case across different versions and brands of Java!) (永远不要假设在不同版本和品牌的Java中总是如此!)

But the main issue is that you're storing Integer as keys. 但主要问题是你将Integer存储为键。 If the values of those keys is smaller than the modulus of the table inside the HashMap , they will just appear ordered (because the hashCode of an Integer is just it;s value). 如果这些键的值小于HashMap中表的模数,它们将只显示有序(因为IntegerhashCode就是它; s值)。 When I tested with 1000 Integer values of 0..999, the hashtable (the array as part of the inner workings of HashMap ) appeared to be of size 2048. (Again, undocumented so don't assume it!) 当我使用1000个Integer数值0..999进行测试时,散列表(作为HashMap内部工作的一部分的数组)看起来大小为2048.(同样,没有文档,所以不要假设它!)

In summary , the reason you see the results in ascending order is because of an implementation artifact, not because there's a specific reason. 总之 ,您看到结果按升序排列的原因是由于实现工件,而不是因为有特定原因。

Collectors.groupingBy returns a HashMap without any order as such (as to why you see "some order" is explained here ). Collectors.groupingBy返回一个没有任何顺序的HashMap这里为什么你看到“某个顺序”)。 The correct way to do this is to specify the Map that preserve the order inside the Collectors.groupingBy : 正确的方法是在Collectors.groupingBy指定保留顺序的Map

myData.stream()
      .collect(Collectors.groupingBy(
          MyEntity::getDataId,
          LinkedHashMap::new,
          Collectors.toList()     

))

You need reverse order of map. 你需要相反的地图顺序。 So In java 8 , i solved with this. 所以在java 8 ,我解决了这个问题。

myData = myService.getData(id);
myid = myData.stream().collect(Collectors.groupingBy(myEntity::getDataId));

Map<Integer, List<myEntity>> finalMap = new LinkedHashMap<>();
myid.entrySet().stream()
        .sorted(Map.Entry.<Integer, List<myEntity>>comparingByKey()
                .reversed())
        .forEachOrdered(e -> finalMap.put(e.getKey(), e.getValue()));
System.out.println("FINAL RESULT : " + finalMap);

Entryset gives us Integers of this map of myid . Entryset给我们Integers这个地图的myid So sort and get from first map which is myid and put in finalMap 所以从第一张地图中排序获取 ,这是myid放入 finalMap

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM