2

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
  • 21,685
  • 24
  • 196
  • 332

2 Answers2

11

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
  • 131,952
  • 11
  • 151
  • 228
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
  • 131,952
  • 11
  • 151
  • 228
GhostCat
  • 133,361
  • 24
  • 165
  • 234