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


    场景

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

    Java8新特性-Stream对集合进行操作的常用API_霸道流氓气质的博客-CSDN博客_javalist.stream

    前面讲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,实际得到的却是一个包含

    整型对象的列表List

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

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

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

    注:

    博客:
    霸道流氓气质的博客_CSDN博客-C#,架构之路,SpringBoot领域博主
    关注公众号
    霸道的程序猿
    获取编程相关电子书、教程推送与免费下载。

    实现

    1、创建IntStream流

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

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

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

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

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

    4、合并流concat

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

    5、summaryStatistics统计各种值

    1.         //使用对基本类型进行特殊处理的方法mapToDouble,将每首曲目映射为曲目长度,该方法返回一个DoubleStream对象
    2.         //它包含一个summaryStatistics方法,这个方法能计算出各种各样的统计值(最大值、最小值、平均值、总和)
    3.         DoubleSummaryStatistics doubleSummaryStatistics = album1.getTrackList().stream()
    4.                 .mapToDouble(track -> track.getLength())
    5.                 .summaryStatistics();
    6.         //max:90.000000,min:60.000000,ave:75.000000,sum:300.000000
    7.         System.out.printf("max:%f,min:%f,ave:%f,sum:%f",doubleSummaryStatistics.getMax(),doubleSummaryStatistics.getMin(),doubleSummaryStatistics.getAverage(),doubleSummaryStatistics.getSum());

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

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

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

     

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



     

  • 相关阅读:
    C语言-字符串排序
    矩阵分析与应用(21)
    基于Bert迁移学习点击未知弹框
    Quarto 入门教程 (2):如何使用并编译出不同文档
    Final IK⭐一、简介及关键脚本 FullBodyBipedIK 讲解
    Python获取浮点数后小数位的个数
    Java常用日志框架--JUL
    【687. 最长同值路径】
    东华大学 2022 oj c++ 无超纲写法 素数表
    【sciter】: 基于 sciter 封装通知栏组件
  • 原文地址:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/127403261