java 8 之Streams 解说

java 8 之Streams 解说

    基本概念


java 8新增的集合streams操作,简化了我们显示的遍历集合操作行为,而且提供内置的并发功能
      Streams操作中,如果操作产生的结果还是 stream lazy operation, 但结果如果是 void或者其他的value值则是eager operation lazy operation做的目的是为了 操作效率
      Streams的 api 中lazy operation类似我们常见的 建造者模式(Builder Pattern),以前我们是设置类的属性,这里我们设置的是行为。

    代码示例:

 
package com.doctor.stream;

import java.util.List;
import java.util.stream.Collectors;

import com.google.common.collect.Lists;

/**
 * @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 = names.stream().filter(e -> {
            System.out.println("filter 1 :" + e);
            return e.startsWith("do");
        }).filter(e -> {
            System.out.println("filter 2 :" + e);
            return e.startsWith("doctor");
        }).collect(Collectors.toList());

        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。



基本操作

1.collect(toList())

    此操作是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

2.map

  我们经常需要将数据从一种形式转换到另一种形式的操作函数,而map操作就可以对流中的数据应用此函数,从而产生包含新值的数据流。


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));

3.filter

  可参考前面的代码例子。主要和以前我们写的if条件判断功能一样,过滤数据流中的数据功能。

4.flatMap

   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 -> e.stream()).collect(Collectors.toList());
        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();
        Preconditions.checkState(max.equals(66));

6.reduce

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

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


看一下java doc的说明:

Open Declaration Integer java.util.stream.Stream.reduce(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.

Parameters:
identity the identity value for the accumulating function
accumulator an associative, non-interfering, stateless function for combining two values
Returns:
the result of the reduction
@apiNote
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);
or: 
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.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dreamer who

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值