Java8新特性Stream的完全使用指南

java stream 作为属性 java stream of_多线程

limit(long maxSize)

limit方法会对流进行顺序截取,从第1个元素开始,保留最多maxSize个元素

Stream stringStream = Stream.of("-2", "-1", "0", "1", "2", "3");

//截取前3个元素,subStringStream -> ("-2", "-1", "0")

Stream subStringStream = stringStream.limit(3);

skip(long n)

skip方法用于跳过前n个元素,如果流中的元素数量不足n,则返回一个空的流

Stream stringStream = Stream.of("-2", "-1", "0", "1", "2", "3");

//跳过前3个元素,subStringStream -> ("1", "2", "3")

Stream subStringStream = stringStream.skip(3);

forEach

forEach方法的作用跟普通的for循环类似,不过这个可以支持多线程遍历,但是不保证遍历的顺序

Stream stringStream = Stream.of("-2", "-1", "0", "1", "2", "3");

//单线程遍历输出元素

stringStream.forEach(System.out::println);

//多线程遍历输出元素

stringStream.parallel().forEach(System.out::println);

forEachOrdered

forEachOrdered方法可以保证顺序遍历,比如这个流是从外部传进来的,然后在这之前调用过parallel方法开启了多线程执行,就可以使用这个方法保证单线程顺序遍历

Stream stringStream = Stream.of("-2", "-1", "0", "1", "2", "3");

//顺序遍历输出元素

stringStream.forEachOrdered(System.out::println);

//多线程遍历输出元素,下面这行跟上面的执行结果是一样的

//stringStream.parallel().forEachOrdered(System.out::println);

toArray

toArray有一个无参和一个有参的方法,无参方法用于把流中的元素转换成Object数组

Stream stringStream = Stream.of("-2", "-1", "0", "1", "2", "3");

Object[] objArray = stringStream.toArray();

有参方法toArray(IntFunction generator)支持把流中的元素转换成指定类型的元素数组

Stream stringStream = Stream.of("-2", "-1", "0", "1", "2", "3");

String[] strArray = stringStream.toArray(String[]::new);

reduce

reduce有三个重载方法,作用是对流内元素做累进操作

第一个reduce(BinaryOperator accumulator)

accumulator 为累进操作的具体计算

单线程等下如下代码

boolean foundAny = false;

T result = null;

for (T element : this stream) {

if (!foundAny) {

foundAny = true;

result = element;

}

else

result = accumulator.apply(result, element);

}

return foundAny ? Optional.of(result) : Optional.empty();

Stream numStream = Stream.of(-2, -1, 0, 1, 2, 3);

//查找最小值

Optional min = numStream.reduce(BinaryOperator.minBy(Integer::compareTo));

//输出 -2

System.out.println(min.get());

//过滤出大于5的元素流

numStream = Stream.of(-2, -1, 0, 1, 2, 3).filter(num -> num > 5);

//查找最小值

min = numStream.reduce(BinaryOperator.minBy(Integer::compareTo));

//输出 Optional.empty

System.out.println(min);

第二个reduce(T identity, BinaryOperator accumulator)

identity 为累进操作的初始值

accumulator 同上

单线程等价如下代码

T result = identity;

for (T element : this stream)

result = accumulator.apply(result, element)

return result;

Stream numStream = Stream.of(-2, -1, 0, 1, 2, 3);

//累加计算所有元素的和,sum=3

int sum = numStream.reduce(0, Integer::sum);

第三个reduce(U identity, BiFunction accumulator, BinaryOperator combiner)

identity和accumulator同上

combiner用于多线程执行的情况下合并最终结果

Stream numStream = Stream.of(-2, -1, 0, 1, 2, 3);

int sum = numStream.parallel().reduce(0, (a, b) -> {

System.out.println("accumulator执行:" + a + " + " + b);

return a + b;

}, (a, b) -> {

System.out.println("combiner执行:" + a + " + " + b);

return a + b;

});

System.out.println("最终结果:"+sum);

输出:

accumulator执行:0 + -1

accumulator执行:0 + 1

accumulator执行:0 + 0

accumulator执行:0 + 2

accumulator执行:0 + -2

accumulator执行:0 + 3

combiner执行:2 + 3

combiner执行:-1 + 0

combiner执行:1 + 5

combiner执行:-2 + -1

combiner执行:-3 + 6

最终结果:3

collect

collect有两个重载方法,主要作用是把流中的元素作为集合转换成其他Collection的子类,其内部实现类似于前面的累进操作

第一个collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)

supplier 需要返回开始执行时的默认结果

accumulator 用于累进计算用

combiner 用于多线程合并结果

单线程执行等价于如下代码

R result = supplier.get();

for (T element : this stream)

accumulator.accept(result, element);

return result;

第二个collect(Collector super T, A, R> collector)

collector其实是对上面的方法参数的一个封装,内部执行逻辑是一样的,只不过JDK提供了一些默认的Collector实现

Stream numStream = Stream.of(-2, -1, 0, 1, 2, 3);

List numList = numStream.collect(Collectors.toList());

Set numSet = numStream.collect(Collectors.toSet());

min

min方法用于计算流内元素的最小值

Stream numStream = Stream.of(-2, -1, 0, 1, 2, 3);

Optional min = numStream.min(Integer::compareTo);

max

min方法用于计算流内元素的最大值

Stream numStream = Stream.of(-2, -1, 0, 1, 2, 3);

Optional max = numStream.max(Integer::compareTo);

count

count方法用于统计流内元素的总个数

Stream numStream = Stream.of(-2, -1, 0, 1, 2, 3);

//count=6

long count = numStream.count();

anyMatch

anyMatch方法用于匹配校验流内元素是否有符合指定条件的元素

Stream numStream = Stream.of(-2, -1, 0, 1, 2, 3);

//判断是否包含正数,hasPositiveNum=true

boolean hasPositiveNum = numStream.anyMatch(num -> num > 0);

allMatch

allMatch方法用于匹配校验流内元素是否所有元素都符合指定条件

Stream numStream = Stream.of(-2, -1, 0, 1, 2, 3);

//判断是否全部是正数,allNumPositive=false

boolean allNumPositive = numStream.allMatch(num -> num > 0);

noneMatch

noneMatch方法用于匹配校验流内元素是否都不符合指定条件

Stream numStream = Stream.of(-2, -1, 0, 1, 2, 3);

//判断是否没有小于0的元素,noNegativeNum=false

boolean noNegativeNum = numStream.noneMatch(num -> num < 0);

findFirst

findFirst方法用于获取第一个元素,如果流是空的,则返回Optional.empty

Stream numStream = Stream.of(-2, -1, 0, 1, 2, 3);

//获取第一个元素,firstNum=-2

Optional firstNum = numStream.findFirst();

findAny

findAny方法用于获取流中的任意一个元素,如果流是空的,则返回Optional.empty,因为可能会使用多线程,所以不保证每次返回的是同一个元素

Stream numStream = Stream.of(-2, -1, 0, 1, 2, 3);

Optional anyNum = numStream.findAny();

总结

到此这篇关于Java8新特性Stream的完全使用指南就介绍到这了