Home > Net >  Are mergeFunction parameters being provided in a deterministic order in the toMap collector?
Are mergeFunction parameters being provided in a deterministic order in the toMap collector?

Time:10-20

I have two lists that I want to concatenate in a single list and then use Collectors.toMap in order to remove duplicates based on a certain field. There cannot be duplicates within the same list, only between the lists.

When it comes to resolving the collisions of values with the same key, I want to prioritize the items from the first list.

I can provide (a, b) -> a as the mergeFunction which only works if the parameters are being passed in order inside the mergeFunction parameter of Collectors.toMap but the documentation is unclear about it.

Are mergeFunction parameters guaranteed to be passed in the same order as the list?

CodePudding user response:

To begin with, the stream should be ordered, which is not always the case.

If you're creating the stream, let's say concatenating two streams produced from your lists (which would be ordered) Stream.concat(list1.stream(),list2.stream()) then your stream would be ordered.

And in case when collector toMap() consumes an ordered stream, then it would respect the encounter, unless you don't relax this constraint yourself by applying unordered().

Here's a quote from the API documentation:

Ordering

Whether or not a stream has an encounter order depends on the source and the intermediate operations. ...

If a stream is ordered, most operations are constrained to operate on the elements in their encounter order. ...

If a stream is ordered, repeated execution of identical stream pipelines on an identical source will produce an identical result; if it is not ordered, repeated execution might produce different results. ...

If you stumbled up on the phrase "most operations", then you should know that the only operations that might not respect the encounter order of the stream are forEach() and peek().

collect() operation does respect the encounter order (if any) unless it's applied on a parallel stream by providing a Collector which specifies the characteristic Collector.Characteristics.UNORDERED (relaxing ordering constraint might improve performance while running in parallel).

Note that Collector returned by toMap() is not unordered, the only characteristics it specifies is IDENTITY_FINISH.

  • Related