Reputation: 123
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. I want my collection list to be descending order not ascending order.
Upvotes: 7
Views: 18035
Reputation: 124
Map<String, List<TargetVaRResponsePTF>> statusMap = ptfDetails.stream().collect(Collectors.groupingBy(item -> {
if (item.getStatus().equalsIgnoreCase("closed") && !item.isHasError()) {
return "Completed";
} else if (item.getStatus().equalsIgnoreCase("closed") && item.isHasError()) {
return "CompletedWithError";
} else if (item.getStatus().equalsIgnoreCase("running")) {
return "Running";
} else if (item.getStatus().equalsIgnoreCase("waiting")) {
return "Waiting";
} else if (item.getStatus().equalsIgnoreCase("error")) {
return "Error";
}
System.out.println("none");
return "none";
}, ConcurrentHashMap::new, Collectors.toList()));
Upvotes: 0
Reputation: 21
There is an example in Collectors groupingby method javadoc. which u can use TreeMap to sort the result.
Map<City, Set<String>> namesByCity
* = people.stream().collect(
* groupingBy(Person::getCity,
* TreeMap::new,
* mapping(Person::getLastName,
* toSet())));
so i think u can try this following code.
myid = myData.stream().collect(Collectors.groupingBy(MyEntity::getDataId,TreeMap::new, toList()));
Upvotes: 0
Reputation: 2230
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.
Upvotes: 17
Reputation: 9543
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.
Upvotes: 4
Reputation: 120858
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()
))
Upvotes: 9
Reputation: 2147
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
Upvotes: 0