java8 新特性 - Stream

原创 2016年08月30日 14:39:05

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

面试必知的java8新特性-stream

面试必知的java8新特性-stream java作为开发语言中的元老已经度过了很多年,最新的java8为我们带来了一些新特性,这些特性可以在以后的工作中为我们的开发提供更多...
  • agzhchren
  • agzhchren
  • 2016年12月17日 22:35
  • 867

《Java8 Stream介绍》

《Java8 Stream介绍》1、为什么需要 StreamStream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同...
  • u010412719
  • u010412719
  • 2016年12月08日 21:14
  • 646

Java8新特性——StreamAPI(二)

1. 收集器简介收集器用来将经过筛选、映射的流进行最后的整理,可以使得最后的结果以不同的形式展现。collect方法即为收集器,它接收Collector接口的实现作为具体收集器的收集方法。Collec...
  • u010425776
  • u010425776
  • 2016年08月28日 17:06
  • 4376

java8新特性(六):Stream多线程并行数据处理

将一个顺序执行的流转变成一个并发的流只要调用 parallel()方法 public static long parallelSum(long n){     return Stream.iter...
  • sunjin9418
  • sunjin9418
  • 2016年11月12日 22:29
  • 4051

Java8新特性之Stream API

在Java8中引进的Stream API是使用lambda的API之一。就像SQL如何帮助你在数据库中形象地查询数据,Stream在Java集合计算上提供了一个形象的声明式的高层抽象来表示计算。形象的...
  • u013291394
  • u013291394
  • 2016年09月22日 22:03
  • 3691

java8十大新特性浅谈

本文将Java8的新特新逐一列出,并将使用简单的代码示例来指导你如何使用默认接口方法,lambda表达式,方法引用以及多重Annotation,之后你将会学到最新的API上的改进,比如流,函数式接口,...
  • youzhouliu
  • youzhouliu
  • 2016年06月10日 23:02
  • 2558

JAVA8 分页工具

使用JAVA8的API可以实现分页,在数据量相对稳定的情况下,可以查出所有数据,配合缓存使用import java.util.ArrayList; import java.util.List; imp...
  • levelmini
  • levelmini
  • 2016年12月23日 17:37
  • 702

Java8新特性——Stream

1、Stream在Java8中被定义为泛型接口 2、Stream接口代表数据流。 3、Stream不是一个数据结构,不直接存储数据。 4、Stream通过管道操作数据。 5、创建Stream接...
  • skeeing
  • skeeing
  • 2016年06月27日 16:29
  • 195

java8新特性-- stream

它的出现让集合处理起来更简洁!List evens = new ArrayList(); for (final Integer num : nums) { if (num % 2 == 0) ...
  • hwsdau
  • hwsdau
  • 2017年12月12日 17:21
  • 25

Java8新特性(三)------Stream

Ø  基础讲解   在java8中Stream被定义为泛型接口,这个接口代表的是数据流,但是Stream并不是一个数据结构,不直接进行数据的存储。Stream主要是通过管道来操作数据。   Str...
  • u010955843
  • u010955843
  • 2016年05月30日 16:03
  • 360
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:java8 新特性 - Stream
举报原因:
原因补充:

(最多只允许输入30个字)