首页 > 编程语言 >java-stream-内部类

java-stream-内部类

时间:2022-09-19 14:37:40浏览次数:63  
标签:java 内部 stream ReduceOp ReducingSink return new public

一、概述

按网上的说法,内部类分为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链;

 

标签:java,内部,stream,ReduceOp,ReducingSink,return,new,public
From: https://www.cnblogs.com/seeall/p/16696862.html

相关文章

  • 深入浅出 JavaScript 中的 this
    笔者最近在看你不知道的JavaScript上卷,里面关于this的讲解个人觉得非常精彩。JavaScript中的this算是一个核心的概念,有一些同学会对其有点模糊和小恐惧,究其原因,现在......
  • Javascript 字符串
    JavaScript字符串您能够使用单引号或双引号字符串长度内建属性length可返回字符串的长度:vartxt="ABCDEFGHIJKLMNOPQRSTUVWXYZ";varsln=txt.length;特殊......
  • Java 方法
    方法的命名规则1.方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符。例如:addPerson。2.下划线可能出现在JUnit测试方法名称中用......
  • JavaScript作用域
    JavaScript作用域在JavaScript中,对象和函数同样也是变量。在JavaScript中,作用域为可访问变量,对象,函数的集合。JavaScript函数作用域:作用域在函数内修改。......
  • java.io.IOException: 设备未就绪。
    java.io.IOExceptionjava.io.IOException:设备未就绪。 atjava.base/java.io.WinNTFileSystem.canonicalize0(NativeMethod) atjava.base/java.io.WinNTFileSystem.ca......
  • JavaScript基础第四天
    函数函数可以实现代码复用,提高开效率function执行任务的代码块函数声明语法function函数名(){函数体}//例如functionfun(){console.log('hello')}......
  • javascript基础第五天
    对象对象(object):JavaScript的一种数据类型对象的特点:无序的数据的集合可以详细描述某个事物对象的使用let对象名={}//例如letperson={}对象有......
  • javascript中的数组细节
    push:给数组添加一个元素至末尾 shift:给数组删除一个元素从头部splice:删除指定位置的元素leta=[1,2,3,4,5]a.splice(2,2)//从索引2开始,删除2个位置的元素//......
  • java中的System.currentTimeMillis()是什么?时间的单位转换以及方法的使用
    在开发过程中,通常很多人都习惯使用newDate()来获取当前时间。newDate()所做的事情其实就是调用了System.currentTimeMillis()。如果仅仅是需要或者毫秒数,那么完全可以使......
  • JavaScript 对象
    JavaScript 对象JavaScript对象是拥有属性和方法的数据。在JavaScript中,几乎所有的事物都是对象。对象也是一个变量,但对象可以包含多个值(多个变量),每个值以 name:val......