第五章(5)数值流 (去装箱化)

本文介绍Java 8中如何使用数值流特化提高处理效率,包括映射到数值流、转换为对象流及处理空流时的默认值等关键概念。

      我们之前学了规约reduce,那么统计所有菜的总热量应该这么做:

List<Dish> menu = Arrays.asList( new Dish("pork", false, 800, Dish.Type.MEAT), 
				   new Dish("beef", false, 700, Dish.Type.MEAT), 
				   new Dish("chicken", false, 400, Dish.Type.MEAT), 
				   new Dish("french fries", true, 530, Dish.Type.OTHER), 
				   new Dish("rice", true, 350, Dish.Type.OTHER), 
				   new Dish("season fruit", true, 120, Dish.Type.OTHER),
				   new Dish("pizza", true, 550, Dish.Type.OTHER),
				   new Dish("prawns", false, 300, Dish.Type.FISH), 
				   new Dish("salmon", false, 450, Dish.Type.FISH) );
		
		int count = menu.parallelStream().map(Dish::getCalories).reduce(0, Integer::sum);
		System.out.println(count);

这段代码虽然可以得到正确的结果,但是他还是存在着问题,那就是Integer的拆箱工作,会多少影响一点效率。

     那么java8为了解决这一问题,专门提供了原始类型流特化:IntStream,DoubleStream,LongStream。分别将流中的元素特化为int、long和double,从而避免了暗含的装箱成本。每个接口都带来了进行常用数值归约的新方法,比如对数值流求和的sum,找到最大元素的max。此外还有在必要时再把它们转换回对象流的方法。要记住的是,这些特化的原因并不在于流的复杂性,而是装箱造成的复杂性——即类似int和Integer之间的效率差异。

1.映射到数值流

    将流转换为特化版本的常用方法是mapToInt、mapToDouble和mapToLong。与map的工作方式是一样的,比如下面我们使用数值流来统计所有菜的热量。

int count = menu.parallelStream().mapToInt(Dish::getCalories).sum();
System.out.println(count);

如果流是空的,那么sum方法默认返回0 

2.转换为对象流(装箱)

有时候,你需要把IntStream或DoubleStream等转换为Stream<Integer>,那该怎么玩呢?

IntStream intStream = menu.stream().mapToInt(Dish::getCalories);
Stream<Integer> stream = intStream.boxed();

3.默认值OptionalInt

上面我们举得第一个例子使用sum对数值流求和如果流是空的那么默认返回0,这是没有任何问题的,那么再试想一个情况,我们使用max求最大值得时候,当流是空的的时候,再返回0,那么就不对了,所以如果求诸如最大值最小值的操作的时候,那么返回结果都必须为OptionalInt(或OptionalDouble,OptionalLong):

IntStream intStream = menu.stream().mapToInt(Dish::getCalories);
OptionalInt maxval = intStream.max();
System.out.println(maxval.getAsInt());

现在,如果没有最大值的话,你就可以显式处理OptionalInt去定义一个默认值了:

int max = maxval.orElse(1); //如果没有最大值的话,显式提供一个默认最大值

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值