java 8 之Streams 解说

2021年1月15日 19点热度 0条评论 来源: A_Beaver

java 8 之Streams 解说


java 8新增的集合streams操作,简化了我们显示的遍历集合操作行为,而且提供内置的并发功能

lazy operation,
void或者其他的value值则是eager operation
lazy operation做的目的是为了

      Streams的 api 中lazy operation类似我们常见的 建造者模式(Builder Pattern),以前我们是设置类的属性,这里我们设置的是行为。




import java.util.List;


 * @author sdcuike
 *         Created on 2016年6月10日 下午4:29:32
 *         It’s very easy to figure out whether an operation is eager or lazy: look at what it returns.
 *         If it gives you back a Stream, it’s lazy; if it gives you back another value or void, then it’s
 *         eager. This makes sense because the preferred way of using these methods is to form a
 *         sequence of lazy operations chained together and then to have a single eager operation
 *         at the end that generates your result.
 *         This whole approach is somewhat similar to the familiar builder pattern. In the builder
 *         pattern, there are a sequence of calls that set up properties or configuration, followed
 *         by a single call to a build method. The object being created isn’t created until the call
 *         to build occurs
 *         I’m sure you’re asking, “Why would we want to have the differentiator between lazy and
 *         eager options?” By waiting until we know more about what result and operations are
 *         needed, we can perform the computations more efficiently.
public class StreamDemo {

    public static void main(String[] args) {
        List<String> names = Lists.newArrayList("doctor", "lily", "who", "doctor who");
        List<String> result = -> {
            System.out.println("filter 1 :" + e);
            return e.startsWith("do");
        }).filter(e -> {
            System.out.println("filter 2 :" + e);
            return e.startsWith("doctor");

        System.out.println("result:" + result);



filter 1 :doctor
filter 2 :doctor
filter 1 :lily
filter 1 :who
filter 1 :doctor who
filter 2 :doctor who
result:[doctor, doctor who]

Streams的filter操作是lazy operation,而collect操作是
eager operation。



    此操作是eager operation,从流中产生某种类型的数值列表。

 List<String> list = Stream.of("a", "b", "c").collect(Collectors.toList());
        boolean equals = Arrays.asList("a", "b", "c").equals(list);
        Preconditions.checkState(equals); // true


List<String> mapOperation = Stream.of("a", "b", "doctor who").map(String::toUpperCase).collect(Collectors.toList());
        Preconditions.checkState(Arrays.asList("A", "B", "DOCTOR WHO").equals(mapOperation));




   map操作,我们之前也看到了,它将流中的数据从一个类型转换到其他类型(非流类型),但如果我们将流中的数据转变成了流该如何操作,这时候我们就用到了  flatMap  操作,它会将产生的流合并成一个流继续下面的操作。

  // flatMap lets you replace a value with a Stream and concatenates all the streams together.
        List<Integer> flatMapOperation = Stream.of(Arrays.asList(1, 2), Arrays.asList(3, 4)).flatMap(e ->;
        Preconditions.checkState(Arrays.asList(1, 2, 3, 4).equals(flatMapOperation));

5.max and min


   Integer max = Stream.of(1, 2, 66).max(Integer::compareTo).get();


  当你想要对集合中的数据处理后得到唯一的结果时,我们借助  reduce操作。

 int intValue = Stream.of(1, 2, 3).reduce(0, (acc, e) -> acc + e).intValue();
        Preconditions.checkState(intValue == 6);

看一下java doc的说明:

Open Declaration Integer identity, BinaryOperator<Integer> accumulator)

Performs a reduction on the elements of this stream, using the provided identity value and an associative accumulation function, and returns the reduced value. This is equivalent to: 

T result = identity;
     for (T element : this stream)
         result = accumulator.apply(result, element)
     return result;
but is not constrained to execute sequentially. 
The identity value must be an identity for the accumulator function. This means that for all t, accumulator.apply(identity, t) is equal to t. The accumulator function must be an associative function. 

This is a terminal operation.

identity the identity value for the accumulating function
accumulator an associative, non-interfering, stateless function for combining two values
the result of the reduction
Sum, min, max, average, and string concatenation are all special cases of reduction. Summing a stream of numbers can be expressed as: 
Integer sum = integers.reduce(0, (a, b) -> a+b);
Integer sum = integers.reduce(0, Integer::sum);
While this may seem a more roundabout way to perform an aggregation compared to simply mutating a running total in a loop, reduction operations parallelize more gracefully, without needing additional synchronization and with greatly reduced risk of data races.