• Java8IntStream数值流的常用操作以及与装箱和拆箱的关系


    场景

    Java8新特性-Stream对集合进行操作的常用API:

    https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/126070657

    前面讲Stream的常用api的使用。

    在Stream中元素都是对象,那么当我们操作一个数字流的时候就要考虑拆箱和装箱。

    Java中拆箱与装箱

    自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱

    ,反之将Integer对象转换成int类型值,这个过程叫做拆箱。因为这里的装箱和拆箱是自动进行的非人为转换,

    所以就称作为自动装箱和拆箱。原始类型byte,short,char,int,long,float,double和boolean对应的封装类为

    Byte,Short,Character,Integer,Long,Float,Double,Boolean。

    IntStream

    在Stream里元素都是对象,那么,当我们操作一个数字流的时候就不得不考虑一个问题,拆箱和装箱。

    虽然自动拆箱不需要我们处理,但依旧有隐含的成本在里面。Java8引入了3个原始类型特化流接口来解决这个问题:

    IntStream,DoubleStream,LongStream, 分别将流中的元素特化为int、long、doub,从而避免了暗含的装箱成本。

    每个接口都带来了进行常用数值归约的新方法,比如求和sum,求最大值max。此外还有必要时再把他们转换回对象流的方法。

    这些特化的原因就是装箱造成的复杂性--类似int和Integer之间的效率差异。

    原因

    1、只有装箱类型才能作为泛型参数,这就解释了为什么在Java中想要一个包含整型值的列表List<int>,实际得到的却是一个包含

    整型对象的列表List<Integer>。

    2、由于装箱类型是对象,因此在内存中存在额外开销,比如,整型在内存中占用4字节,整型对象要占用16字节。

    这一情况在数组中更严重,整型数组中的每个元素只占用基本类型的内存,而整型对象数组中,每个元素是内存中

    的一个指针,指向Java堆中的某个对象。在最坏的情况下,同样大小的数组,Integer[]要比int[]多占用6倍内存。

    注:

    博客:
    https://blog.csdn.net/badao_liumang_qizhi
    关注公众号
    霸道的程序猿
    获取编程相关电子书、教程推送与免费下载。

    实现

    1、创建IntStream流

            //创建IntStream流
            IntStream intStream = IntStream.of(1, 2, 3, 4, 5, 6);

    2、range、rangeClosed将指定范围的元素添加到流

            //将指定范围内的元素都添加到int流中
            //range不包含最后一个元素
            IntStream range = IntStream.range(1, 10);
            range.forEach(System.out::println);
            //rangeClosed包含最后一个元素
            IntStream intStream1 = IntStream.rangeClosed(1, 10);
            intStream1.forEach(System.out::println);

    3、iterate根据指定规则生成一串Int流

            //指定生成int流中int元素的生成函数,前者的生成函数没有入参,后者会将前一次的调用结果作为下一次调用生成函数的入参
            //根据指定规则,生成一串int流,需使用limit限制元素数量
            IntStream.iterate(1, x -> x * 2).limit(10).forEach(System.out::println);//1 2 4 8 16 32 64 128 256 512

    4、合并流concat

            //合并流concat
            IntStream.concat(IntStream.range(1, 5), IntStream.range(8, 13)).forEach(System.out::println);

    5、summaryStatistics统计各种值

            //构造模拟数据
            Album album1 = Album.builder()
                    .albumName("album1")
                    .trackList(new ArrayList<Track>() {{
                        this.add(Track.builder().trackName("a").length(60f).build());
                        this.add(Track.builder().trackName("b").length(70f).build());
                        this.add(Track.builder().trackName("c").length(80f).build());
                        this.add(Track.builder().trackName("d").length(90f).build());
                    }})
                    .build();
    
            //使用对基本类型进行特殊处理的方法mapToDouble,将每首曲目映射为曲目长度,该方法返回一个DoubleStream对象
            //它包含一个summaryStatistics方法,这个方法能计算出各种各样的统计值(最大值、最小值、平均值、总和)
            DoubleSummaryStatistics doubleSummaryStatistics = album1.getTrackList().stream()
                    .mapToDouble(track -> track.getLength())
                    .summaryStatistics();
            //max:90.000000,min:60.000000,ave:75.000000,sum:300.000000
            System.out.printf("max:%f,min:%f,ave:%f,sum:%f",doubleSummaryStatistics.getMax(),doubleSummaryStatistics.getMin(),doubleSummaryStatistics.getAverage(),doubleSummaryStatistics.getSum());

    6、将数值流转换为对象流

            //boxed将数值流转换为对象流
            //使用数值流进行计算,但经常需要回归到对象,可以使用boxed方法
            DoubleStream doubleStream = album1.getTrackList().stream()
                    .mapToDouble(track -> track.getLength());
            Stream<Double> boxed = doubleStream.boxed();
            boxed.forEach(System.out::println);

    7、IntStream的api与Stream的api基本一样,具体可参照上面博客,或者自己查看api

    DoubleStream和LongStream的用法与IntStream的用法类似。



     

  • 相关阅读:
    文件下载
    python生成pdf
    python保存文件到数据库
    html 表格边线设置
    形态学函数cvMorphologyEx
    图像的形态学梯度
    opencv图像二值化的函数cvThreshold()。 cvAdaptiveThreshol
    自适应二值化的经典方法------大律法
    基于局部阈值化的图像二值化
    边缘检测常见算法
  • 原文地址:https://www.cnblogs.com/badaoliumangqizhi/p/16805406.html
Copyright © 2020-2023  润新知