Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Collectors.groupingBy()---is List ordered?

Tags:

For the Collectors.groupingBy() that returns Map<K,List<T>> is it implied that the List<T> is in order that the stream is evaluated?

I see no explicit description of the ordering of the list, whereas the concurrent version explicitly states no ordering. If it weren't ordered somehow, I'd expect it to be a Collection though, and I don't see what other ordering it could possibly be, other than order received.

I'm hoping it's guaranteed that the last value in each list is the last value received for that group.

like image 735
Joel Avatar asked Aug 26 '16 18:08

Joel


People also ask

How does Collector groupingBy work?

groupingBy. Returns a Collector implementing a cascaded "group by" operation on input elements of type T , grouping elements according to a classification function, and then performing a reduction operation on the values associated with a given key using the specified downstream Collector .

What does collectors toList do in Java?

The toList() method of Collectors Class is a static (class) method. It returns a Collector Interface that gathers the input data onto a new list. This method never guarantees type, mutability, serializability, or thread-safety of the returned list but for more control toCollection(Supplier) method can be used.

How does Groupby work in Java 8?

In Java 8, you retrieve the stream from the list and use a Collector to group them in one line of code. It's as simple as passing the grouping condition to the collector and it is complete. By simply modifying the grouping condition, you can create multiple groups.

What is the use of collectors in Java 8?

collect() is one of the Java 8's Stream API's terminal methods. It allows us to perform mutable fold operations (repackaging elements to some data structures and applying some additional logic, concatenating them, etc.) on data elements held in a Stream instance.


2 Answers

The documentation for groupingBy() says:

Implementation Requirements:

This produces a result similar to:

groupingBy(classifier, toList()); 

The documentation for toList() says:

Returns:

a Collector which collects all the input elements into a List, in encounter order

So, to answer your question, as long as your stream has a defined encounter order, you're guaranteed to get ordered lists.


EDIT: As @Holger points out, groupingBy() would also have to respect encounter order to preserve toList()'s ordering constraint. The fact that it does is strongly implied in this note:

Implementation Note:

...If preservation of the order in which elements are presented to the downstream collector is not required, using groupingByConcurrent(Function, Collector) may offer better parallel performance.

like image 86
shmosel Avatar answered Oct 27 '22 07:10

shmosel


I did a real test, I init a ArrayList<TimeBased> with this order:

{"1", "2019-03-22 10:20:03", "1"}, {"2", "2019-03-22 10:30:03", "2"}, {"2", "2019-03-22 11:20:03", "3"}, {"1", "2019-03-22 11:20:15", "4"}, {"3", "2019-03-22 11:35:03", "5"}, {"2", "2019-03-22 12:20:03", "6"} 

and groupingBy first and second column, but the result was:

id  birth                        number 1   Fri Mar 22 10:20:03 CST 2019 1 1   Fri Mar 22 11:20:15 CST 2019 4 2   Fri Mar 22 12:20:03 CST 2019 6 2   Fri Mar 22 11:20:03 CST 2019 3 2   Fri Mar 22 10:30:03 CST 2019 2 3   Fri Mar 22 11:35:03 CST 2019 5 

so you see, the order is unexpected(date column order confused).

and after i do this(add LinkedList::new):

Map<Integer, Map<Date, List<TimeBased>>> grouped =                 timeBasedBeans.stream().collect(groupingBy(TimeBased::getId, groupingBy(TimeBased::getPeriod,                         LinkedHashMap::new, toList()))); 

then the order is right:

id  birth                        number 1   Fri Mar 22 10:20:03 CST 2019 1 1   Fri Mar 22 11:20:15 CST 2019 4 2   Fri Mar 22 10:30:03 CST 2019 2 2   Fri Mar 22 11:20:03 CST 2019 3 2   Fri Mar 22 12:20:03 CST 2019 6 3   Fri Mar 22 11:35:03 CST 2019 5 
like image 40
nazavoya Avatar answered Oct 27 '22 08:10

nazavoya