Java 8之基本类型优化

在Java中, 泛型必须使用引用类型, 而不能使用基本类型。 所以要表示基本类型的列表或者数组时, 必须使用对应基本类型的引用类型, 如
int对应Integerlong对应Long等, 在基本类型与引用类型可以自动地装箱与拆箱, 但是会有一些性能损失。

在Java 8的Stream API中提供了of方法,如果传入基本类型的参数,内部其实得到的是一个引用类型的Stream。如下面代码

1
2
// 得到的是Integer类型的 Stream
Stream<Integer> stream = Stream.of(1, 2, 3);

因此, Java 8的提供了一些专门针对基本类型优化的API,如 IntStreamLongStreamDoubleStream, 应该优先使用它们。

定义

定义基本类型的Stream, 可以使用IntStreamLongStreamDoubleStream的接口静态方法ofrangeempty, 下面为例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 创建一个空的 IntStream
IntStream empty = IntStream.empty();

// 创建包含基本类型1, 2, 3的 IntStream
IntStream intStream = IntStream.of(1, 2, 3);

// 创建一个包含1到9的 IntStream
IntStream range = IntStream.range(1, 10);

// 创建一个包含1到10的 IntStream
IntStream rangeClosed = IntStream.rangeClosed(1, 10);

// 创建一个包含3的 IntStream
IntStream generated = IntStream.generate(() -> 3);

// 得到一个无限循环的 IntStream, 值为 1, 3, 5, 7 ...
IntStream infinite = IntStream.iterate(1, operand -> operand + 2);

也可以基于 int 数组创建 IntStream, 如

1
2
3
4
5
int[] array = new int[]{1, 2, 3, 4, 5};
// 包含整个数组的IntStream
IntStream arrayStream = Arrays.stream(array);
// 包含数组的索引位置2开始,4结束(不包含)的IntStream
IntStream rangeArray = Arrays.stream(array, 2, 4);

使用

基本类型的Stream,内部使用的都是与基本类型相关的接口函数来进行操作, 进而避免装箱成相应的引用类型, IntStream 主要有以下几个操作方法

filter方法

filter方法于过滤Stream中的数据,它接收一个 IntPredicate 接口, 它是一个 int -> boolean 的接口函数, 例子代码如下

1
2
// 输出 2, 4, 6
IntStream.of(1, 2, 3, 4, 5, 6, 7).filter(elem -> elem % 2 == 0).forEach(System.out::println);

map 方法

map方法主要是对Stream的元素进行某种映射,转换成另一个基本类型的值, 它接收一个 IntUnaryOperator 接口, 它是一个 int -> int 的函数接口,例子代码如下:

1
2
// 输出 10, 20, 30, 40, 50, 60, 70
IntStream.of(1, 2, 3, 4, 5, 6, 7).map(elem -> elem * 10).forEach(System.out::println);

mapToObj 方法

mapToObj 方法主要是将Stream中的元素进行装箱操作, 转换成一个引用类型的值, 它接收一个 IntFunction 接口, 它是一个 int -> R 的函数接口, 例子代码如下:

1
2
// 输出a1, a2, a3, a4, a5, a6, a7
IntStream.of(1, 2, 3, 4, 5, 6, 7).mapToObj(elem -> "a" + elem).forEach(System.out::println);

mapToLong 方法

mapToLong 方法是将Stream中的 元素转换成基本类型long, 它接收一个 IntToLongFunction 接口, 它是一个 int -> long 的函数接口, 例子代码如下

1
2
// 输出 100, 200, 300, 400, 500, 600, 700
IntStream.of(1, 2, 3, 4, 5, 6, 7).mapToLong(elem -> elem * 100L).forEach(System.out::println);

mapToDouble 方法

mapToDouble 方法是将Stream中的 元素转换成基本类型double, 它接收一个 IntToDoubleFunction接口, 它是一个 int -> double 的函数接口, 例子代码如下

1
2
// 输出 1.1, 2.1, 3.1, 4.1, 5.1, 6.1, 7.1
IntStream.of(1, 2, 3, 4, 5, 6, 7).mapToDouble(elem -> elem + 0.1).forEach(System.out::println);

min 方法

min 方法获取Stream中最小的元素, 它返回 OptionalInt 类型, 它是一个int版的Optional, 同样是为了避免拆箱装箱操作。 示例代码如下

1
2
// 输出 1
System.out.println(IntStream.of(1, 2, 3, 4).min().getAsInt());

summaryStatistics 方法

summaryStatistics 方法主要是获取Stream中元素的统计信息, 它返回 IntSummaryStatistics, 示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
IntSummaryStatistics summary = IntStream.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).summaryStatistics();
// 输出 1
System.out.println(summary.getMin());
// 输出 10
System.out.println(summary.getMax());
// 输出 55
System.out.println(summary.getSum());
// 输出 10
System.out.println(summary.getCount());
// 输出 5.5
System.out.println(summary.getAverage());

此外, 还有 flatMapdistinctsortedpeeklimitskipforEachreducecollectanyMatchallMatchnoneMatch等方法, 与Stream的方法都差不多。

猜你喜欢

转载自blog.csdn.net/ryuenkyo/article/details/89010920