4

I have ordered list of LocalDateTime and I need to split it on midnight of specific date. The order of elements in two new lists should not be changed.

List<LocalDateTime> l = Arrays.asList(LocalDateTime.of(2017,10,24,7,0,0),LocalDateTime.of(2017,10,24,8,0,0),LocalDateTime.of(2017,10,25,7,0,0),LocalDateTime.of(2017,10,25,9,0,0));

Does Collectors.partitioningBy provide a guarantee that the order will be preserved?

l.stream().collect(Collectors.partitioningBy(t-> t.isAfter(LocalDateTime.of(2017,10,25,0,0,0))))

Output:

{false=[2017-10-24T07:00, 2017-10-24T08:00], true=[2017-10-25T07:00, 2017-10-25T09:00]}
leon01
  • 317
  • 3
  • 12
  • 1
    No, it doesn't. It _probably will_ preserve the order in simplest cases, like single-thread iterating stream from an ordered source, but stream by itself doesn't guarantee you any particular ordering (unless you ask it to, of course), and neither does a Collector. – M. Prokhorov Oct 25 '17 at 13:27
  • 1
    If the input list is ordered, a binary search would be much more efficient than `Collectors.partitioningBy`, and once you find the index of the split date, you can create two sub-lists of the original list. – Eran Oct 25 '17 at 13:29
  • 2
    @MProkhorov: streams *will* maintain the encounter order, if they have one, even if the processing order might be different. That’s an important property of streams. See [How to ensure order of processing in java8 streams?](https://stackoverflow.com/a/29218074/2711488) – Holger Oct 25 '17 at 18:16

1 Answers1

7

The documentation of the built-in collectors explicitly mentions when a Collector is an unordered collector, e.g. for toSet() or groupingByConcurrent(…). All collectors not specified to be unordered will preserve the encounter order, if the stream is ordered and they don’t have a downstream collector that is itself unordered.

partitioningBy(predicate) is equivalent to partitioningBy(predicate, toList()) and hence, will maintain the encounter order.

A counter-example would be partitioningBy(predicate, toSet()) which does not preserve any order and likewise, a stream that itself is unordered, e.g. hashSet.stream() .collect(partitioningBy(predicate)), does not make any guarantees about the result order.

Holger
  • 285,553
  • 42
  • 434
  • 765