fjwl 844 0 2017-11-22 23:26:03 编程技术

java 8中的流(Stream)

之前因为工作原因经常需要对查询的数据库的数据集合进行筛选或者排序之类的操作,今天看了下jdk8特性,根据stream可以自动满足这些操作。

流是Java API的新成员,它允许你以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现)

Java 8中的Stream API可以让你写出这样的代码:

 声明性——更简洁,更易读

 可复合——更灵活

 可并行——性能更好

首先看一下使用流和不使用流的区别,需求: 把集合中年龄小于等于20的人的名字取出来并排序
不使用流:

//传统JDK排序抽取数据
        // 把集合中年龄小于等于20的人的名字取出来并排序
        // 第一步:取年龄 <= 20的用户
        List<User> tmpList = new ArrayList<>();
        for (User u : list) {
            if (u.getAge() <= 20){
                tmpList.add(u);
            }
        }
        // 第二步:排序
        Collections.sort(tmpList, new Comparator<User>() {
            public int compare(User u1, User u2) {
                return u1.getName().compareTo(u2.getName());
            }
        });
        // 第三步
        List<String> userNames = new ArrayList<>();
        for(User u : tmpList){
            userNames.add(u.getName());
        }

jdk8流新特性
 

//JDK流新特性
        //为了利用多核架构并行执行这段代码,只需要把stream()换成parallelStream():
        List<String> userNames = list.stream()
                .filter(userJdk8 -> userJdk8.getAge() <= 20)
                .sorted(Comparator.comparing(User::getName))
                .map(User::getName)
                .collect(Collectors.toList());
        System.out.println(userNames.toString());

 

流与集合的区别:

集合与流之间的差异就在于什么时候进行计算。集合是一个内存中的数据结构,它包含数据结构中目前所有的值——集合中的每个元素都得先算出来才能添加到集合中。(你可以往集合里加东西或者删东西,但是不管什么时候,集合中的每个元素都是放在内存里的,元素都得先算出来才能成为集合的一部分。)相比之下,流则是在概念上固定的数据结构(你不能添加或删除元素),其元素则是按需计算的。 从另一个角度来说,流就像是一个延迟创建的集合:只有在消费者要求的时候才会计算值。以质数为例,要是想创建一个包含所有质数的集合,那这个程序算起来就没完没了了,因为总有新的质数要算,然后把它加到集合里面。而流的话,仅仅从流中提取需要的值,而这些值——在用户看不见的地方,只会按需生成。
流只能被消费一次,如果被消费多次,则会抛出异常:

java.lang.IllegalStateException: stream has already been operated upon or closed

如下代码所示: 这段代码的意思是遍历 lists 集合

List<String> lists = Arrays.asList("java8","lambda","stream");
        Stream<String> stringStream = lists.stream();
        Consumer<String> consumer = (x) -> System.out.println(x);
        stringStream.forEach(consumer);
        //stream has already been operated upon or closed
        stringStream.forEach(consumer);

之前测试类完整代码,更多stream参考jdk8API在线文档
 

package com.yeyue;

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

/**
 * @ClassName: JDK8Test
 * @Description: jdk8流的作用 此例是把集合中年龄小于等于20的人的名字取出来并排序
 * @author: xiaoboLi
 * @date: 2017/11/22 14:32
 * @Copyright: 2017 All rights reserved.
 */
public class JDK8Test {
    public static void main(String[] args) {
        List<User> list = new ArrayList<>();
        User user = new User(11, "zhangsan",  1);
        list.add(user);
        user = new User(19, "lisi",  1);
        list.add(user);
        user = new User(10, "wanger",  0);
        list.add(user);
        user = new User(7, "wangmazi",  0);
        list.add(user);
        user = new User(25, "hanmeimei",  0);
        list.add(user);
        user = new User(30, "lilei",  0);
        list.add(user);
        //传统JDK排序抽取数据
        // 把集合中年龄小于等于20的人的名字取出来并排序
        // 第一步:取年龄 <= 20的用户
        List<User> tmpList = new ArrayList<>();
        for (User u : list) {
            if (u.getAge() <= 20){
                tmpList.add(u);
            }
        }
        // 第二步:排序
        Collections.sort(tmpList, new Comparator<User>() {
            public int compare(User u1, User u2) {
                return u1.getName().compareTo(u2.getName());
            }
        });
        // 第三步
        List<String> userNames = new ArrayList<>();
        for(User u : tmpList){
            userNames.add(u.getName());
        }
        System.out.println(userNames.toString());

        //JDK流新特性
        //为了利用多核架构并行执行这段代码,只需要把stream()换成parallelStream():
        userNames = list.stream()
                .filter(userJdk8 -> userJdk8.getAge() <= 20)
                .sorted(Comparator.comparing(User::getName))
                .map(User::getName)
                .collect(Collectors.toList());
        System.out.println(userNames.toString());

        //取小于20岁的人员信息并且根据年龄升序排序
        List<User> aList = list.stream()
                .filter(userJdk8 -> userJdk8.getAge() <= 20)
                .sorted(Comparator.comparing(User::getAge))
                .collect(Collectors.toList());
        for (User u : aList) {
            System.out.println(u.getName());
        }
    }
}

class User {
    private int age;
    private String name;
    private int sex;

    public User(int age, String name, int sex) {
        this.age = age;
        this.name = name;
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getSex() {
        return sex;
    }

    public void setSex(int sex) {
        this.sex = sex;
    }
}