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链;

 

posted @ 2022-09-19 14:23  seeAll  阅读(153)  评论(0编辑  收藏  举报