java-stream-内部类
一、概述
按网上的说法,内部类分为4种:
1,成员内部类,类似于对象的成员变量;需要通过外部类对象创建;
2,静态内部类,类似于类的static变量;直接通过类创建;
3,局部内部类,类似于方法(作用域)中的局部变量;只能在方法内部声明创建;
4,匿名内部类,类似于子类型;好像只能跟在new 父类型(){ 重写(实现)其方法 };
二、stream中的内部类
1,静态内部类
public abstract class SelfPipeline<P_IN, P_OUT> extends SelfPipelineHelper<P_OUT> implements SelfStream<P_OUT> {
......
static class SelfHead<P_IN, P_OUT> extends SelfPipeline<P_IN, P_OUT> {
SelfHead(Iterator<?> source) {
super(source);
}
@Override
final SelfSink<P_IN> opWrapSink(SelfSink<P_OUT> sink) {
throw new UnsupportedOperationException();
}
}
......
}
public SelfStream<T> selfStream() { Iterator<T> listIterator = super.iterator(); return new SelfPipeline.SelfHead<>(listIterator); }
静态内部类(SelfHead)直接通过外部类型(SelfPipeline)创建;
因为该静态内部类没有使用外部类的私有静态变量或方法,所以完全可以使用单独的java类实现,如下:
public class SelfHead<P_IN, P_OUT> extends SelfPipeline<P_IN, P_OUT> { SelfHead(Iterator<?> source) { super(source); } @Override final SelfSink<P_IN> opWrapSink(SelfSink<P_OUT> sink) { throw new UnsupportedOperationException(); } }
public SelfStream<T> selfStream() { Iterator<T> listIterator = super.iterator(); //return new SelfPipeline.SelfHead<>(listIterator); return new SelfHead<>(listIterator); }
所以,静态内部类的意义更多的是表明与外部类的关系,同时也省去了一个java文件;
静态内部类SelfPipeline.SelfStatelessOp也是同样的道理;
2,局部内部类
public class SelfReduceOpsFactory { public static <T, I> SelfTerminalOp<T, I> makeRef(SelfCollector<? super T, I> collector) { Supplier<I> supplier = Objects.requireNonNull(collector).supplier(); BiConsumer<I, ? super T> accumulator = collector.accumulator(); // 局部内部类的定义:在方法内部 class ReducingSink extends SelfBox<I> implements SelfTerminalSink<T, I> { @Override public void begin(long size) { state = supplier.get(); } @Override public void accept(T t) { accumulator.accept(state, t); } } /* 1,局部内部类ReducingSink的使用:只能在该方法(作用域)内使用;不能在外部new出来,但是如下示例可以通过SelfReduceOp.makeSink()方法得到他的对象以在外部使用; 2,SelfReduceOp和ReducingSink的组合由方法确定,而不是程序员自由组合(可能导致混乱); 3,SelfReduceOp是匿名内部类,下面会介绍到; */ return new SelfReduceOp<T, I, ReducingSink>() { @Override public ReducingSink makeSink() { return new ReducingSink(); } }; } private static abstract class SelfBox<U> { U state; SelfBox() { } public U get() { return state; } } private static abstract class SelfReduceOp<T, R, S extends SelfTerminalSink<T, R>> implements SelfTerminalOp<T, R> { SelfReduceOp() { } // SelfReduceOp可以是固定的,但是ReducingSink类型和对象方法定义可以是变化的 public abstract S makeSink(); @Override public <P_IN> R evaluateSequential(SelfPipelineHelper<T> helper, Iterator<P_IN> iterator) { S reducingSink = makeSink(); S wrappedReducingSink = helper.wrapAndCopyInto(reducingSink, iterator); return wrappedReducingSink.get(); } } }
局部内部类主要和方法相关联,局部内部类的定义代码是写死的,类中一些涉及到的参数(方法的入参)是灵活的,尤其是lambda参数就更灵活了;
3,匿名内部类
如上2中的:
return new SelfReduceOp<T, I, ReducingSink>() { @Override public ReducingSink makeSink() { return new ReducingSink(); } };
匿名内部类的对象可以重写方法,即类的定义代码是灵活的;
三、总结
thisOp.终结操作{ "ReduceOp工厂"生产一个ReduceOp; thisOp评估这个ReduceOp{ ReduceOp反评估thisOp(但是转化为了SelfPipelineHelper -> thisOpHelper){ ReduceOp生成一个ReduceSink(在"ReduceOp工厂"生产ReduceOp的方法中定义的局部内部类); thisOpHelper再次反操作ReduceSink{ } } } }
相当于:
对象A.方法(对象B){
对象B.方法(对象A){
对象A.方法(对象B){
.......
}
}
}
总结下来,thisOp不太适合做这个收尾的工作,因为thisOp也就是MapOp,他有自己的事情要做;
所以,解耦出一个新的Op,也就是ReduceOp,所有的终结详情操作都放到这个Op中;
ReduceOp不需要和前面的MapOp、FilterOp组成双向链表,他提供的ReducingSink需要和前面的MapSink、FilterSink组成单向链表;
终结操作Op(ReduceOp)需要引用thisOp,去构造sink链;