获取年龄,想直接通过如下代码获取年龄的总和
但是这样是不支持的。问题在于map方法生成的是Stream
定义sum是没有意义的。Stream APi 还提供了原始类特化,专门用来处理数值流的方法。
Java 引入了三个原始类型特化接口来解决这个问题,IntStream ,DoubleStream,LongStream 分别将流元素转化为 int ,double,long,从而避免了暗含的装箱成本。每个接口都提供了进行数值计算的方法,比如sum,max方法等,还有在必要
时候,再把他们转化为对象流的方法。重点记住,特化的原因是解决装箱造成的复杂性。即类似于int和Integer的效率差异。
将流转化为特化流,常用的方法 mapToInt,mapToDouble,mapToLong,这些方法和前面说的map方法的工作方式一样,只是返回的是一个特化的数值流,而不是
stream
@Test
public void getUserInfoTest() {
List initStudentList = StudentEntity.createInitStudentList();
int sum = initStudentList.stream() //返回的是stream
.mapToInt(StudentEntity::getAge) //返回的是IntStream
.sum(); //调用IntStream 中定义的sum方法,求和;如果流是空,默认返回0
logger.info("年龄和是:{}",sum );
}
//将stream 转化为数值流
IntStream intStream = initStudentList.stream().mapToInt(StudentEntity::getAge);
//将数值流转化为Stream
Stream boxed = intStream.boxed();
对于不存在的值,可以使用OptionInt,OptionDouble,OptionLong
例如求最大值的时候, 会返回一个optionalInt
@Test
public void testOption() {
List initStudentList = StudentEntity.createInitStudentList();
OptionalInt maxOption = initStudentList.stream()
.mapToInt(StudentEntity::getAge)
.max();
//如果没有最大值,可以提供一个默认的
int max = maxOption.orElse(1);
logger.info("最大值是:{}", max);
}
加入要生成1 到 100 的所有数值,Java8 引入了可以用于IntStream 和LongStream的静态方法,生成范围是:
rang 和rangeClosed ,这两个方法都是第一个参数是起始值,第二个参数是结束值,但是range是不包含结束值,rangeClosed
包含结束值。
IntStream.of(5, 3, 2, 4, 1)
.filter(id -> id > 2)
.peek(value -> logger.info("element is:{}", value))
.mapToObj(String::valueOf)
.forEach(va -> logger.info("peek:{}", va));
@Test
public void testIntStream() {
// Objects.requireNonNull(action);
IntStream.of(5, 3, 2, 4, 1)
.filter(id -> id > 2)
.peek(value -> logger.info("element is:{}", value))
.mapToObj(String::valueOf)
.forEach(va -> logger.info("peek:{}", va));
IntStream.rangeClosed(0, 10)
.skip(5)
.forEach(id -> logger.info("skip之后:{}", id));
// skip之后:5
//skip之后:6
// skip之后:7
// skip之后:8
// skip之后:9
//skip之后:10
Long collect = StudentEntity.createInitStudentList().stream()
.map(StudentEntity::getAge)
.collect(Collectors.summingLong(Long::valueOf));
//直接转化为sum
int studentAgeSum = StudentEntity.createInitStudentList().stream()
.mapToInt(StudentEntity::getAge)
.sum();
//mapToInt 会从每个学生中提取年龄,并返回一个IntStream (而不是Stream),然后就可以调用IntStream中的sum方法,
//对年龄求和了。如果流是空的,那么sum=0;IntStream还可以返回其他方法,例如:max,min,average等。
//将原始流转化为一般流(每个int都会装箱为一个Integer),可以使用boxed
Stream boxed = StudentEntity.createInitStudentList().stream().mapToInt(StudentEntity::getAge)
.boxed();
//返回的是stream,而不是intStream
int maxValue = StudentEntity.createInitStudentList().stream()
.mapToInt(StudentEntity::getAge)
.max().orElse(1);
logger.info("最大值:{}", maxValue);
}
推荐一个讲解很全的博客:玩转Java8Stream(四、IntStream)
对于一些数字,可以用mapToInt 转化为数值流,完成数字的求和,最大最小,平均数,count 等;
同时可以通过boxed把数值流转化为stream
取值范围,可以对有限的数字,做相应的处理。