Which stream operations use CONCURRENT
, IMMUTABLE
and NONNULL
Spliterator characteristics? How does each of them help in those operations?
I'm not asking what those flags are, this can be found easly in the documantation. I'm asking which operations use them and how.
First, you should make a clear distinction that you are asking about Spliterator
characteristics here and these depend on the source of the Stream; because there are also ( CONCURRENT
, UNORDERED
and IDENTITY_FINISH
for Collectors
for example).
There is a comment in StreamOpFlag
saying:
// The following Spliterator characteristics are not currently used but a
// gap in the bit set is deliberately retained to enable corresponding
// stream flags if//when required without modification to other flag values.
//
// 4, 0x00000100 NONNULL(4, ...
// 5, 0x00000400 IMMUTABLE(5, ...
// 6, 0x00001000 CONCURRENT(6, ...
// 7, 0x00004000 SUBSIZED(7, ...
As far as I understand these are not a direct 1 to 1 mapping with the ones from Spliterator, but still they are not used.
At the moment (and I've searched the jdk-8 and 9 sources), neither are leveraged - but still are reported by some implementations of Spliterators ( Arrays
report IMMUTABLE
and ConcurrentHashMap
reports NONNULL
for example).
These flags could be used in the future on the other hand - if you know that a source can not contain null elements ( NONNULL
), obviously you can skip some null checks or define some state with a null. I can't think of any examples for CONCURRENT
or IMMUTABLE
, but there might be such.
For example under the current implementation for an UNORDERED
and CONCURRENT
collector (!= Spliterator
properties), the combiner
is not called when you do toConcurrentMap
. For example:
Set.of("one", "two", "das", "dasda")
.stream()
.parallel()
.collect(Collectors.toConcurrentMap(Function.identity(), String::length));
will not call the combiner
- since there is no need to.
Optimizations like these could be made for any of the 3 characteristics that you have mentioned. For example you can read this where StreamOpFlag.ORDERED
has changed the result of findFirst
in java 8 vs java 9
In Java 8, the stream operations use neither of these 3 characteristics. This can be checked by searching these constants in the Java sources.
However, the CONCURRENT
characteristic may affect the behaviour of parallel streams when you write your own collection. If you create a Spliterator
from a collection and not report the CONCURRENT
characteristic, then the spliterator will additionally have SIZED
and SUBSIZED
characteristics:
Collection<Integer> col = ...
Spliterator<Integer> s = Spliterators.spliterator(col, 0);
System.out.println(s.hasCharacteristics(Spliterator.SIZED)); // Prints true
System.out.println(s.hasCharacteristics(Spliterator.SUBSIZED)); // Prints true
But if you report the CONCURRENT
characteristic, then the spliterator is not SIZED
anymore:
Collection<Integer> col = ...
Spliterator<Integer> s = Spliterators.spliterator(col, Spliterator.CONCURRENT);
System.out.println(s.hasCharacteristics(Spliterator.SIZED)); // Prints false
System.out.println(s.hasCharacteristics(Spliterator.SUBSIZED)); // Prints false
Spliterators that are not SIZED
and SUBSIZED
are poorly parallelized, so when you write you own concurrent collection, it is better to write a custom spliterator and not rely on the default spliterator implementation.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.