java8 新特性 - Stream

Stream

Stream 就目前的使用场景来说更多的是针对集合(Collection)提供更多更便利的聚合操作。以前大部分需要利用遍历完成的工作,现在都提供了非常便利的接口。最重要的是Stream背后是并行化设计,所以效率有很大的提高。

简介

1. 数据源 (如何初始化Stream)
2. 数据转换
3. 获取结果

案例 : 我们初始化一部分数据,需求是按照年龄从大到小给男性排序,若是java8之前的做法大概是:

1. 取出所有男性玩家赋值给新的集合
2. 自定义一个comparator
3. 排序

总体来说十几行代码是必须的。其中还不乏内部类这种生涩的语法,使用起来并不是特别方便。

利用Stream :

List<Student> result = sourcedata.stream(). 
filter(e -> e.getSex() == 'M').
sorted( (Student s1, Student s2) -> (s1.getAge() - (s2.getAge())) ).
// sorted( (s1, s2) -> (s1.getAge() - (s2.getAge())) ).
collect(Collectors.toList());   

最终不过 5行代码。由此我们开始学习Stream。

数据源

所谓的数据源就是如何获取一个Stream对象,最常见的方式莫过于从集合Collection和数组Array中生成Stream:

1. Collections.Stream()
2. Arrays.stream(T array) or Stream.of(T array)

Stream 转换成其他数据结构:

1. List<T> list = stream.collect(Collections.toList());

当然还有很多。

数据操作

Stream 的背后是fork/join框架,所以支持并行化操作。

流的操作类型 分为两种:

  • Intermediate : 转换操作 可以有很多,大多是过滤和映射,排序工作。特别注意的是此类操作并非立即开始执行,我们可以把此类操作理解成一种状态,它会一直保留到最后,知道终止操作时才会正在开始执行。这个很关键,如果简单分析一下上述的排序例子,我们会以为至少执行了两遍Iterator操作,filter一次,sort一次,其实并没有。这也是Stream性能高的原因之一。

    map, filter, distinct, peek, limit, skip, parrallel, sequential …

  • Terminal : 终止操作 只会有一个,大多会返回数据,这种操作开始后就会正在遍历数据并进行所有的复合处理。

    forEach, toArray, reduce, collect, min, max ,count, anyMatch, findFirst…

细节API学习

具体请看详细代码。

package streams;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.OptionalDouble;
import java.util.stream.Collectors;

/**
 * @author wangzhiping movingwzp@gmail.com
 * @date 201/08/19 15:20
 * @brief learning the new feature of java8 - stream
 *
 * 把函数式风格引入了java
 */
public class Stream {
    public static void main(String[] args) {
        List<Student> sourcedata = getData();

        // 需求1 : M(男性) W(女性) 按照从小到大给男性排序
        // before java8
        List<Student> datanew = new ArrayList<Student>();
        for (Student s : sourcedata) {
            if (s.getSex() == 'M') {
                datanew.add(s);
            }
        }
        Collections.sort(datanew, new Comparator<Student>() {

            @Override
            public int compare(Student o1, Student o2) {
                // TODO Auto-generated method stub
                return o1.getAge() - o2.getAge();
            }
        });
        //showData(datanew);

        // java8 in stream
        List<Student> result = sourcedata.stream(). 
                               filter(e -> e.getSex() == 'M').
                               sorted( (Student s1, Student s2) -> (s1.getAge() - (s2.getAge())) ).
                               // sorted( (s1, s2) -> (s1.getAge() - (s2.getAge())) ).
                               collect(Collectors.toList());
        //showData(result);

        // learning strem api in detail
        // problem 1 - 男性平均年龄
        OptionalDouble resultage  = sourcedata.stream().
                                    filter(e -> e.getSex() == 'M').
                                    mapToInt(e -> e.getAge()).
                                    average();
        System.out.println(resultage);

        // reduce :  提供一个初始种子和运算规则,依照运算规则,依次跟第一个,第二个。。。元素进行组合,返回结果 包括:sum max min
        int resultagetwo = sourcedata.stream().
                           filter(e -> e.getSex() == 'M').
                           mapToInt(e -> e.getAge()).
                           reduce(0, Integer::max);
        System.out.println(resultagetwo);

        // map : 获取所有人的名字大写
        List<String> resultname = sourcedata.stream().
                        map(e -> e.getName().toUpperCase()).
                        sorted().
                        collect(Collectors.toList());
        System.out.println(resultname); 


        // forEach 遍历每一个元素并做相应的修改,并行状态下无法保证遍历的元素次序,多线程安全
        sourcedata.stream().forEach(e -> e.setName("new name"));
        showData(sourcedata);
    }
    private static void showData(List<Student> data) {
        for (Student s : data) {
            System.out.println(s);
        }
    }

    private static List<Student> getData() {
        List<Student> result = new ArrayList<Student>();
        result.add(new Student("wang1", 22, 'M'));
        result.add(new Student("wang2", 35, 'W'));
        result.add(new Student("wang3", 12, 'M'));
        result.add(new Student("wang4", 52, 'W'));
        result.add(new Student("zhang1", 35, 'M'));
        result.add(new Student("zhang2", 21, 'W'));
        result.add(new Student("zhang4", 34, 'M'));
        result.add(new Student("li3", 12, 'W'));
        result.add(new Student("li4", 23, 'M'));
        result.add(new Student("li9", 34, 'W'));
        result.add(new Student("li1", 16, 'M'));
        return result;
    }
}

github 代码链接:
https://github.com/codesscholar/java8/tree/master/src/streams

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值