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.
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 .
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.
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.
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.
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 aList
, 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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With