3

i have List with simple object:

private String unit;
private Double value;

List looks like that:

f, 1.0;
ml, 15.0;
g, 9.0

I have created a simple function where I want to group this values and put them to the map with unit as a key, and list of objects as value, but I want to save the order like in my original list. This is my current solution:

myList.stream()
    .collect(groupingBy(MyObject::getUnit));

But after that my map is sorted alphabetically this way: f, g, ml instead of f, ml, g. Is there any alternative for groupingBy to fix it?

Naman
  • 27,789
  • 26
  • 218
  • 353

2 Answers2

12

The issue is that groupingBy puts things into some map, probably a HashMap, which has no guaranteed ordering.

Use the groupingBy overload which takes a Supplier<M> mapFactory, to get a map with an ordering guarantee, e.g.

myList.stream()
    .collect(groupingBy(MyObject::getUnit,
                        LinkedHashMap::new,
                        Collectors.toList()));
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
1

The javadoc for groupingBy() says:

There are no guarantees on the type, mutability, serializability, or thread-safety of the Map or List objects returned.

And then, the Map interface itself doesn't give any guarantee about the order of keys!

Thus: you either have to use another grouping method (that allows you to force a LinkedHashMap or a TreeMap), or to step back, and to rethink your whole approach. You could for example sort your list after it was pulled together.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
GhostCat
  • 137,827
  • 25
  • 176
  • 248