Java8 Stream 基本类型特化流

2020-10-09 15:32:30 浏览数 (1)

一、 基本类型特化流(数值流)

  • 在下面这段对流的操作的代码中,其实隐藏着一个问题: 装箱成本,每个原始类型都必须装箱成一个包装类型,如:
代码语言:javascript复制
Stream<Integer> integerStream = Stream.of(1, 2, 3);
Integer sum = integerStream.reduce(0, Integer::sum);
  • 为了避免不必要的拆箱和装箱,Java8引入了三个原始类型特化流接口: IntStream, LongStreamDoubleStream,将流中的元素特化为int, longdouble,避免暗含的装箱成本。并且,在这三个特化接口中,提供了常用的数值规约方法,可以方便地进行数值相关的操作,如min, max, sum等。如果需要将基本类型特化流再转换成引用类型流,也有相应的方法支持。
  • 引用类型流映射成值类型流
    • 常用方法是mapToInt(), mapToLong()mapToDouble,以及flatMapToXxx...
    • 上述方法的返回值不再是Stream<T>,而是相应的数值类型流,如IntStream
代码语言:javascript复制
Stream<Integer> integerStream = Stream.of(1, 2, 3);IntStream intStream = integerStream.mapToInt(x -> x);
// 求和
int intSum = intStream.sum();
// 计算最大值
OptionalInt intMax = integerStream.mapToInt(x -> x).max();
// 计算最小值
OptionalInt intMin = integerStream.mapToInt(x -> x).min();
  • 数值类型流转换成引用类型流
    • 使用.boxed()装箱方法
      • boxed()方法实际上内部调用的都是mapToObj()
代码语言:javascript复制
IntStream intStream = integerStream.mapToInt(x -> x);
Stream<Integer> boxedIntegerStream = intStream.boxed();
Stream<Long> boxedLongStream = LongStream.range(1, 10).boxed();

二、 关于OptionalInt

  • 在介绍数值流的时候,可以注意到数值流提供的几个规约方法的返回值:
    • sum()返回的是int,因为sum存在默认值0.
    • max()min()的返回值都是OptionalInt,没有默认值,因为设置默认值为0是一种错误的做法。而对于这三种特化流,有三个参数化的Optional类:OptionalInt, OptionalLongOptionalDouble
代码语言:javascript复制
// 注意range(1,1)生成的是一个空的流
OptionalInt optionalInt = IntStream.range(1, 1).max();
// 空的流无法获取到最大值
optionalInt.ifPresent(x -> System.out.println("最大值为:"   x));
// 当无结果时,返回一个默认值
System.out.println("默认最大值:"   optionalInt.orElse(1));
代码语言:javascript复制
默认最大值:1

三、 数值范围

  • 为了方便地生成一定范围内的数字,Java8提供了可以作用于IntStreamLongStream的范围方法: range(start,end)rangeClose(start,end),区别是rangeClose()会包含end这个值。
代码语言:javascript复制
// 生成1~100,并求和
System.out.println(IntStream.rangeClosed(1, 100).sum());

欢迎在评论区留下你看文章时的思考,及时说出,有助于加深记忆和理解,还能和像你一样也喜欢这个话题的读者相遇。

0 人点赞