归档
使用示例
https://github.com/zengxf/small-frame-demo/blob/master/jdk-demo/simple-demo/src/main/java/test/new_features/jdk1_8/stream/TestStream.java 基础方法使用测试:test_base()
JDK 版本
openjdk version "17" 2021 - 09 - 14
OpenJDK Runtime Environment ( build 17 + 35 - 2724 )
OpenJDK 64 - Bit Server VM ( build 17 + 35 - 2724 , mixed mode, sharing)
原理
数据结构
Head ( List) < - > filter < - > map < - > skip < - > peek < - > sorted < - > limit < - > forEach
Head ( List) - > filter - > map - > skip - > peek - > sorted - > limit - > forEach
类结构
java.util.stream.ReferencePipeline.Head
static class Head < E_IN, E_OUT> extends ReferencePipeline < E_IN, E_OUT> {
Head ( Spliterator < ? > source, int sourceFlags, boolean parallel) {
super ( source, sourceFlags, parallel) ;
}
}
java.util.stream.ReferencePipeline.StatelessOp
abstract static class StatelessOp < E_IN, E_OUT>
extends ReferencePipeline < E_IN, E_OUT>
{
StatelessOp ( AbstractPipeline < ? , E_IN, ? > upstream, StreamShape inputShape, int opFlags) {
super ( upstream, opFlags) ;
assert upstream. getOutputShape ( ) == inputShape;
}
}
java.util.stream.ReferencePipeline
abstract class ReferencePipeline < P_IN, P_OUT>
extends AbstractPipeline < P_IN, P_OUT, Stream < P_OUT> >
implements Stream < P_OUT>
{
ReferencePipeline ( Spliterator < ? > source, int sourceFlags, boolean parallel) {
super ( source, sourceFlags, parallel) ;
}
ReferencePipeline ( AbstractPipeline < ? , P_IN, ? > upstream, int opFlags) {
super ( upstream, opFlags) ;
}
abstract Sink < E_IN> opWrapSink ( int flags, Sink < E_OUT> sink) ;
}
java.util.stream.AbstractPipeline
abstract class AbstractPipeline < E_IN, E_OUT, S extends BaseStream < E_OUT, S > >
extends PipelineHelper < E_OUT> implements BaseStream < E_OUT, S >
{
private final AbstractPipeline sourceStage;
private final AbstractPipeline previousStage;
private AbstractPipeline nextStage;
private int depth;
private Spliterator < ? > sourceSpliterator;
private boolean parallel;
AbstractPipeline ( Supplier < ? extends Spliterator < ? > > source, int sourceFlags, boolean parallel) {
this . previousStage = null ;
this . sourceSupplier = source;
this . sourceStage = this ;
this . sourceOrOpFlags = sourceFlags & StreamOpFlag . STREAM_MASK ;
this . combinedFlags = ( ~ ( sourceOrOpFlags << 1 ) ) & StreamOpFlag . INITIAL_OPS_VALUE ;
this . depth = 0 ;
this . parallel = parallel;
}
AbstractPipeline ( AbstractPipeline < ? , E_IN, ? > previousStage, int opFlags) {
if ( previousStage. linkedOrConsumed)
throw new IllegalStateException ( MSG_STREAM_LINKED ) ;
previousStage. linkedOrConsumed = true ;
previousStage. nextStage = this ;
this . previousStage = previousStage;
this . sourceOrOpFlags = opFlags & StreamOpFlag . OP_MASK ;
this . combinedFlags = StreamOpFlag . combineOpFlags ( opFlags, previousStage. combinedFlags) ;
this . sourceStage = previousStage. sourceStage;
if ( opIsStateful ( ) )
sourceStage. sourceAnyStateful = true ;
this . depth = previousStage. depth + 1 ;
}
}
java.util.stream.Sink.ChainedReference
abstract static class ChainedReference < T , E_OUT> implements Sink < T > {
protected final Sink < ? super E_OUT> downstream;
public ChainedReference ( Sink < ? super E_OUT> downstream) {
this . downstream = Objects . requireNonNull ( downstream) ;
}
}
调用链
xxList.stream()
default Stream < E > stream ( ) {
return StreamSupport . stream ( spliterator ( ) , false ) ;
}
@Override
default Spliterator < E > spliterator ( ) {
return Spliterators . spliterator ( this , 0 ) ;
}
public static < T > Spliterator < T > spliterator ( Collection < ? extends T > c,
int characteristics) {
return new IteratorSpliterator < > ( Objects . requireNonNull ( c) ,
characteristics) ;
}
java.util.stream.StreamSupport
public static < T > Stream < T > stream ( Spliterator < T > spliterator, boolean parallel) {
Objects . requireNonNull ( spliterator) ;
return new ReferencePipeline. Head < > ( spliterator,
StreamOpFlag . fromCharacteristics ( spliterator) ,
parallel) ;
}
stream.filter()
java.util.stream.ReferencePipeline
@Override
public final Stream < P_OUT> filter ( Predicate < ? super P_OUT> predicate) {
Objects . requireNonNull ( predicate) ;
return new StatelessOp < P_OUT, P_OUT> ( this , StreamShape . REFERENCE ,
StreamOpFlag . NOT_SIZED ) {
@Override
Sink < P_OUT> opWrapSink ( int flags, Sink < P_OUT> sink) {
return new Sink. ChainedReference < P_OUT, P_OUT> ( sink) {
@Override
public void begin ( long size) {
downstream. begin ( - 1 ) ;
}
@Override
public void accept ( P_OUT u) {
if ( predicate. test ( u) )
downstream. accept ( u) ;
}
} ;
}
} ;
}
stream.map()
java.util.stream.ReferencePipeline
@Override
public final < R > Stream < R > map ( Function < ? super P_OUT, ? extends R > mapper) {
Objects . requireNonNull ( mapper) ;
return new StatelessOp < P_OUT, R > ( this , StreamShape . REFERENCE ,
StreamOpFlag . NOT_SORTED | StreamOpFlag . NOT_DISTINCT ) {
@Override
Sink < P_OUT> opWrapSink ( int flags, Sink < R > sink) {
return new Sink. ChainedReference < P_OUT, R > ( sink) {
@Override
public void accept ( P_OUT u) {
downstream. accept ( mapper. apply ( u) ) ;
}
} ;
}
} ;
}
stream.skip()
java.util.stream.ReferencePipeline
@Override
public final Stream < P_OUT> skip ( long n) {
if ( n < 0 )
throw new IllegalArgumentException ( Long . toString ( n) ) ;
if ( n == 0 )
return this ;
else
return SliceOps . makeRef ( this , n, - 1 ) ;
}
java.util.stream.SliceOps
public static < T > Stream < T > makeRef ( AbstractPipeline < ? , T , ? > upstream,
long skip, long limit) {
. . .
long normalizedLimit = limit >= 0 ? limit : Long . MAX_VALUE ;
return new ReferencePipeline. StatefulOp < T , T > ( upstream, StreamShape . REFERENCE ,
flags ( limit) ) {
. . .
@Override
Sink < T > opWrapSink ( int flags, Sink < T > sink) {
return new Sink. ChainedReference < > ( sink) {
long n = skip;
long m = normalizedLimit;
@Override
public void begin ( long size) {
downstream. begin ( calcSize ( size, skip, m) ) ;
}
@Override
public void accept ( T t) {
if ( n == 0 ) {
if ( m > 0 ) {
m-- ;
downstream. accept ( t) ;
}
}
else {
n-- ;
}
}
@Override
public boolean cancellationRequested ( ) {
return m == 0 || downstream. cancellationRequested ( ) ;
}
} ;
}
} ;
}
stream.peek()
java.util.stream.ReferencePipeline
@Override
public final Stream < P_OUT> peek ( Consumer < ? super P_OUT> action) {
Objects . requireNonNull ( action) ;
return new StatelessOp < P_OUT, P_OUT> ( this , StreamShape . REFERENCE , 0 ) {
@Override
Sink < P_OUT> opWrapSink ( int flags, Sink < P_OUT> sink) {
return new Sink. ChainedReference < P_OUT, P_OUT> ( sink) {
@Override
public void accept ( P_OUT u) {
action. accept ( u) ;
downstream. accept ( u) ;
}
} ;
}
} ;
}
stream.sorted()
java.util.stream.ReferencePipeline
@Override
public final Stream < P_OUT> sorted ( ) {
return SortedOps . makeRef ( this ) ;
}
java.util.stream.SortedOps
static < T > Stream < T > makeRef ( AbstractPipeline < ? , T , ? > upstream) {
return new OfRef < > ( upstream) ;
}
java.util.stream.SortedOps.OfRef
private static final class OfRef < T > extends ReferencePipeline. StatefulOp < T , T > {
private final boolean isNaturalSort;
private final Comparator < ? super T > comparator;
OfRef ( AbstractPipeline < ? , T , ? > upstream) {
super ( upstream, StreamShape . REFERENCE ,
StreamOpFlag . IS_ORDERED | StreamOpFlag . IS_SORTED ) ;
this . isNaturalSort = true ;
@SuppressWarnings ( "unchecked" )
Comparator < ? super T > comp = ( Comparator < ? super T > ) Comparator . naturalOrder ( ) ;
this . comparator = comp;
}
@Override
public Sink < T > opWrapSink ( int flags, Sink < T > sink) {
Objects . requireNonNull ( sink) ;
if ( StreamOpFlag . SORTED . isKnown ( flags) && isNaturalSort)
return sink;
else if ( StreamOpFlag . SIZED . isKnown ( flags) )
return new SizedRefSortingSink < > ( sink, comparator) ;
else
return new RefSortingSink < > ( sink, comparator) ;
}
}
java.util.stream.SortedOps.RefSortingSink
private static final class RefSortingSink < T > extends AbstractRefSortingSink < T > {
private ArrayList < T > list;
RefSortingSink ( Sink < ? super T > sink, Comparator < ? super T > comparator) {
super ( sink, comparator) ;
}
@Override
public void begin ( long size) {
. . .
list = ( size >= 0 ) ? new ArrayList < > ( ( int ) size) : new ArrayList < > ( ) ;
}
@Override
public void end ( ) {
list. sort ( comparator) ;
downstream. begin ( list. size ( ) ) ;
if ( ! cancellationRequestedCalled) {
list. forEach ( downstream:: accept ) ;
}
else {
for ( T t : list) {
if ( downstream. cancellationRequested ( ) ) break ;
downstream. accept ( t) ;
}
}
downstream. end ( ) ;
list = null ;
}
@Override
public void accept ( T t) {
list. add ( t) ;
}
}
java.util.stream.SortedOps.AbstractRefSortingSink
private abstract static class AbstractRefSortingSink < T > extends Sink. ChainedReference < T , T > {
protected final Comparator < ? super T > comparator;
AbstractRefSortingSink ( Sink < ? super T > downstream, Comparator < ? super T > comparator) {
super ( downstream) ;
this . comparator = comparator;
}
}
stream.limit()
java.util.stream.ReferencePipeline
@Override
public final Stream < P_OUT> limit ( long maxSize) {
if ( maxSize < 0 )
throw new IllegalArgumentException ( Long . toString ( maxSize) ) ;
return SliceOps . makeRef ( this , 0 , maxSize) ;
}
stream.forEach()
java.util.stream.ReferencePipeline
@Override
public void forEach ( Consumer < ? super P_OUT> action) {
evaluate ( ForEachOps . makeRef ( action, false ) ) ;
}
java.util.stream.ForEachOps
final class ForEachOps {
public static < T > TerminalOp < T , Void > makeRef ( Consumer < ? super T > action,
boolean ordered) {
Objects . requireNonNull ( action) ;
return new ForEachOp. OfRef < > ( action, ordered) ;
}
abstract static class ForEachOp < T >
implements TerminalOp < T , Void > , TerminalSink < T , Void >
{
private final boolean ordered;
protected ForEachOp ( boolean ordered) {
this . ordered = ordered;
}
@Override
public < S > Void evaluateSequential ( PipelineHelper < T > helper,
Spliterator < S > spliterator) {
return helper. wrapAndCopyInto ( this , spliterator) . get ( ) ;
}
static final class OfRef < T > extends ForEachOp < T > {
final Consumer < ? super T > consumer;
OfRef ( Consumer < ? super T > consumer, boolean ordered) {
super ( ordered) ;
this . consumer = consumer;
}
@Override
public void accept ( T t) {
consumer. accept ( t) ;
}
}
}
}
java.util.stream.AbstractPipeline
final < R > R evaluate ( TerminalOp < E_OUT, R > terminalOp) {
assert getOutputShape ( ) == terminalOp. inputShape ( ) ;
if ( linkedOrConsumed)
throw new IllegalStateException ( MSG_STREAM_LINKED ) ;
linkedOrConsumed = true ;
return isParallel ( )
? terminalOp. evaluateParallel ( this , sourceSpliterator ( terminalOp. getOpFlags ( ) ) )
: terminalOp. evaluateSequential ( this , sourceSpliterator ( terminalOp. getOpFlags ( ) ) ) ;
}
private Spliterator < ? > sourceSpliterator ( int terminalFlags) {
Spliterator < ? > spliterator = null ;
if ( sourceStage. sourceSpliterator != null ) {
spliterator = sourceStage. sourceSpliterator;
sourceStage. sourceSpliterator = null ;
}
. . .
. . .
. . .
return spliterator;
}
@Override
final < P_IN, S extends Sink < E_OUT> > S wrapAndCopyInto ( S sink, Spliterator < P_IN> spliterator) {
copyInto ( wrapSink ( Objects . requireNonNull ( sink) ) , spliterator) ;
return sink;
}
@Override
final < P_IN> void copyInto ( Sink < P_IN> wrappedSink, Spliterator < P_IN> spliterator) {
Objects . requireNonNull ( wrappedSink) ;
if ( ! StreamOpFlag . SHORT_CIRCUIT . isKnown ( getStreamAndOpFlags ( ) ) ) {
wrappedSink. begin ( spliterator. getExactSizeIfKnown ( ) ) ;
spliterator. forEachRemaining ( wrappedSink) ;
wrappedSink. end ( ) ;
}
else {
copyIntoWithCancel ( wrappedSink, spliterator) ;
}
}
@Override
final < P_IN> Sink < P_IN> wrapSink ( Sink < E_OUT> sink) {
Objects . requireNonNull ( sink) ;
for ( AbstractPipeline p = AbstractPipeline . this ; p. depth > 0 ; p = p. previousStage) {
sink = p. opWrapSink ( p. previousStage. combinedFlags, sink) ;
}
return ( Sink < P_IN> ) sink;
}
@Override
final < P_IN> boolean copyIntoWithCancel ( Sink < P_IN> wrappedSink, Spliterator < P_IN> spliterator) {
@SuppressWarnings ( { "rawtypes" , "unchecked" } )
AbstractPipeline p = AbstractPipeline . this ;
while ( p. depth > 0 ) {
p = p. previousStage;
}
wrappedSink. begin ( spliterator. getExactSizeIfKnown ( ) ) ;
boolean cancelled = p. forEachWithCancel ( spliterator, wrappedSink) ;
wrappedSink. end ( ) ;
return cancelled;
}
java.util.stream.ReferencePipeline
@Override
final boolean forEachWithCancel ( Spliterator < P_OUT> spliterator, Sink < P_OUT> sink) {
boolean cancelled;
do { } while ( ! ( cancelled = sink. cancellationRequested ( ) ) && spliterator. tryAdvance ( sink) ) ;
return cancelled;
}
java.util.Spliterators.IteratorSpliterator
@Override
public boolean tryAdvance ( Consumer < ? super T > action) {
if ( action == null ) throw new NullPointerException ( ) ;
if ( it == null ) {
it = collection. iterator ( ) ;
est = ( long ) collection. size ( ) ;
}
if ( it. hasNext ( ) ) {
action. accept ( it. next ( ) ) ;
return true ;
}
return false ;
}
总结
排序会创建临时集合,用于收集元素 流的双向链是为创建 Sink 单向链做准备