JAVA8使用笔记(二)

操作符

  • reduce

    1 、元素求和操作

1
2
3
4
5
6
7
8
9
// 普通的for-each求和方式
public void sumReduce(){
List<Integer> testList = Arrays.asList(1,3,4,5,6);
int sum = 0;
for (Integer integer : testList) {
sum += integer;
}
System.out.println(sum);
}
1
2
3
4
5
// reduce 进行求和操作
int tempSum = testList.stream()
.reduce(0, (a, b) -> a + b);
System.out.println(tempSum);
// 输出19

reduce接受两个参数:
1.一个初始值,这里给的是0,
2.一个BinaryOperator 来将两个进行组合产生新的值。这里我们用的是(a,b)-> a+b进行求和

reduce还有一个重载的方法,他不接受初始值,但会返回一个Optional对象

1
2
3
4
5
6
Optional<Integer> optional = testList.stream()
.reduce((a, b) -> a * b);
optional.ifPresent(p -> {
System.out.println(p);
});
// 输出 360
  1. 最大值和最小值
    如果我们希望能够在给定的集合中求出最大值的话。我们可以这样写,reduce操作会针对流中的元素进行比对,并产生一个新的最大值,指导整个流消耗完。如果要计算最小值得话需要Integer:min来替换Integer:max就好了
1
2
3
4
5
//max
testList.stream()
.reduce(Integer::max)
.ifPresent(m -> System.out.println(m));
// 输出 6
1
2
3
4
testList.stream()
.reduce(Integer::min)
.ifPresent(m -> System.out.println(m));
// 输出1
1
2
3
4
5
// 当然我们可以使用三位运算
testList.stream()
.reduce((x,y)-> x< y? x:y)
.ifPresent(y-> System.out.println(y));
// 输出1
1
2
3
4
5
// 使用Integer::compareTo比较操作
testList.stream()
.reduce(Integer::compareTo)
.ifPresent(x-> System.out.println(x));
// 输出-1

注: stream并不适合做并行操作,如果需要并行求和时候,可以将stream()换成parallelStream()

3.数值流操作

1
2
3
4
5
6
// 求和操作
Integer sum1 = testList.stream()
.map(d -> d * 10)
.reduce(0, Integer::sum);
System.out.println(sum1);
//输出190

上面的代码我们知道了reduce的求和操作,但是我们发现reduce对元素类型进行了装箱再进行求和操作。如果我们想进行原始类型流的转换我们可以试一试下面的方法。

1
2
3
4
5
6
//求和
int sum2 = testList.stream()
.mapToInt(d -> d * 10)
.sum();
System.out.println(sum2);
//输出190

这段代码我们知道我们可以通过mapToInt对原始类型的流进行求和操作。当然不仅有mapToInt,还有mapToDouble、mapToLong。

1
2
3
4
5
6
7
IntStream intStream = testList.stream()
IntStream intStream = testList.stream()
.mapToInt(d -> d * 10);
OptionalInt max = intStream.max();
int asInt = max.getAsInt();
System.out.println(asInt);
//输出60

mapToInt等对流的操作返回的是一个IntStream流,如果你要进行最大操作,可以使用max(),他返回的是一个OptionalInt,他属于Optional类特别的版本:OptionalInt、OptionalLong、OptionalDouble

1
2
3
4
5
int max1 = testList.stream()
.mapToInt(d -> d * 10)
.max()
.orElse(100);
System.out.println(max1);

如上,如果你不知道有没有最大值的话 ,你想给他定义一个默认最大值的话,可以利用orElse对其进行操作

数值范围

Java8引入了可以用于IntStream和LongStream可以帮助生成数值的范围range和rangeClose。这两个方法第一个参数接受起始值,第二个参数接受结束值。但是range是不包含结束值,而rangeClosed则包含结束值。

1
2
3
4
5
6
7
8
9
long count = IntStream.range(1, 10)
.count();
System.out.println(count);
//输出9
long count1 = IntStream.rangeClosed(1, 10)
.count();
System.out.println(count1);
//输出10