/** Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.*********************/package java.util.stream;import java.util.HashSet;import java.util.LinkedHashSet;import java.util.Objects;import java.util.Set;import java.util.Spliterator;import java.util.concurrent.ConcurrentHashMap;import java.util.concurrent.atomic.AtomicBoolean;import java.util.function.IntFunction;/*** Factory methods for transforming streams into duplicate-free streams, using* {@link Object#equals(Object)} to determine equality.** @since 1.8*/final class DistinctOps {private DistinctOps() { }/*** Appends a "distinct" operation to the provided stream, and returns the* new stream.** @param <T> the type of both input and output elements* @param upstream a reference stream with element type T* @return the new stream*/static <T> ReferencePipeline<T, T> makeRef(AbstractPipeline<?, T, ?> upstream) {return new ReferencePipeline.StatefulOp<T, T>(upstream, StreamShape.REFERENCE,StreamOpFlag.IS_DISTINCT | StreamOpFlag.NOT_SIZED) {<P_IN> Node<T> reduce(PipelineHelper<T> helper, Spliterator<P_IN> spliterator) {// If the stream is SORTED then it should also be ORDERED so the following will also// preserve the sort orderTerminalOp<T, LinkedHashSet<T>> reduceOp= ReduceOps.<T, LinkedHashSet<T>>makeRef(LinkedHashSet::new, LinkedHashSet::add,LinkedHashSet::addAll);return Nodes.node(reduceOp.evaluateParallel(helper, spliterator));}@Override<P_IN> Node<T> opEvaluateParallel(PipelineHelper<T> helper,Spliterator<P_IN> spliterator,IntFunction<T[]> generator) {if (StreamOpFlag.DISTINCT.isKnown(helper.getStreamAndOpFlags())) {// No-opreturn helper.evaluate(spliterator, false, generator);}else if (StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {return reduce(helper, spliterator);}else {// Holder of null state since ConcurrentHashMap does not support null valuesAtomicBoolean seenNull = new AtomicBoolean(false);ConcurrentHashMap<T, Boolean> map = new ConcurrentHashMap<>();TerminalOp<T, Void> forEachOp = ForEachOps.makeRef(t -> {if (t == null)seenNull.set(true);elsemap.putIfAbsent(t, Boolean.TRUE);}, false);forEachOp.evaluateParallel(helper, spliterator);// If null has been seen then copy the key set into a HashSet that supports null values// and add nullSet<T> keys = map.keySet();if (seenNull.get()) {// TODO Implement a more efficient set-union view, rather than copyingkeys = new HashSet<>(keys);keys.add(null);}return Nodes.node(keys);}}@Override<P_IN> Spliterator<T> opEvaluateParallelLazy(PipelineHelper<T> helper, Spliterator<P_IN> spliterator) {if (StreamOpFlag.DISTINCT.isKnown(helper.getStreamAndOpFlags())) {// No-opreturn helper.wrapSpliterator(spliterator);}else if (StreamOpFlag.ORDERED.isKnown(helper.getStreamAndOpFlags())) {// Not lazy, barrier required to preserve orderreturn reduce(helper, spliterator).spliterator();}else {// Lazyreturn new StreamSpliterators.DistinctSpliterator<>(helper.wrapSpliterator(spliterator));}}@OverrideSink<T> opWrapSink(int flags, Sink<T> sink) {Objects.requireNonNull(sink);if (StreamOpFlag.DISTINCT.isKnown(flags)) {return sink;} else if (StreamOpFlag.SORTED.isKnown(flags)) {return new Sink.ChainedReference<T, T>(sink) {boolean seenNull;T lastSeen;@Overridepublic void begin(long size) {seenNull = false;lastSeen = null;downstream.begin(-1);}@Overridepublic void end() {seenNull = false;lastSeen = null;downstream.end();}@Overridepublic void accept(T t) {if (t == null) {if (!seenNull) {seenNull = true;downstream.accept(lastSeen = null);}} else if (lastSeen == null || !t.equals(lastSeen)) {downstream.accept(lastSeen = t);}}};} else {return new Sink.ChainedReference<T, T>(sink) {Set<T> seen;@Overridepublic void begin(long size) {seen = new HashSet<>();downstream.begin(-1);}@Overridepublic void end() {seen = null;downstream.end();}@Overridepublic void accept(T t) {if (!seen.contains(t)) {seen.add(t);downstream.accept(t);}}};}}};}}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。