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

▼魔方 西西 提交于 2019-12-04 15:13:04

As @Holger described in Java 8 is not maintaining the order while grouping , Collectors.groupingBy() returns a HashMap, which does not guarantee order.

Here is what you can do:

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

Would return a LinkedHashMap<Integer, List<MyEntity>>. The order will also be maintained as the list used by collector is ArrayList.

collect(Collectors.groupingBy()) returns a new Map which overwrites the variable to your previous 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. (Never assume this will always be the case across different versions and brands of Java!)

But the main issue is that you're storing Integer as keys. 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). 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!)

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). The correct way to do this is to specify the Map that preserve the order inside the Collectors.groupingBy:

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.

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. So sort and get from first map which is myid and put in finalMap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!