java8之Stream

Stream  (流) :数据通道,用于操作数据源(数组、集合等)所生成的元素序列。

1、 Stream 自己不会存储数据

2、Stream不会改变源对象,返回的是一个持有操作结果的新的Stream.

3、Stream是延迟执行的(等到需要结果的时候才会执行)。

Stream的三个步骤:

1、创建Stream

 //1.可以通过Collection系列集合提供的stream()获取串行流 或paralleStream()获取并行流
        List<String> list = new ArrayList<>();
        Stream<String> stream = list.stream();

        //2.通过Arrays中的静态方法获取 stream() 获取数组流
        Book[] books = new Book[10];
        Stream<Book> stream1 = Arrays.stream(books);

        //3.通过Stream类中的静态方法 of() 创建流
        Stream<Book> stream2 = Stream.of(books);

        //4.创建无限流(无穷尽)
        //迭代
        Stream<Integer> stream3 = Stream.iterate(0,x->x+2);
//        stream3.forEach(System.out::println);
        stream3.limit(10).forEach(System.out::println);//只取前10个

        //生成
        Stream.generate(()->Math.random()).limit(5).forEach(System.out::println);

2、中间操作

package com.example.pojo;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;

import java.io.Serializable;
import java.util.Date;
import java.util.Objects;

public class Book implements Serializable{

    private static final long serialVersionUID = -5682718161792139284L;
    private Integer id;
    private String name;
    private String author;
    @JsonIgnore
    private Float price;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date publicationDate;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public Float getPrice() {
        return price;
    }

    public void setPrice(Float price) {
        this.price = price;
    }

    public Date getPublicationDate() {
        return publicationDate;
    }

    public void setPublicationDate(Date publicationDate) {
        this.publicationDate = publicationDate;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Book book = (Book) o;
        return Objects.equals(id, book.id) &&
                Objects.equals(name, book.name) &&
                Objects.equals(author, book.author) &&
                Objects.equals(price, book.price) &&
                Objects.equals(publicationDate, book.publicationDate);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, author, price, publicationDate);
    }
}
 //筛选与切片
        //filter:接收Lambda, 从流中排除某些元素
        //limit(n):截断流,使其元素不超过给定数量,返回前n个元素组成的流
        //skip(n):跳过元素,返回去掉了前n个的流,元素个数不足n个返回空流。与limit(n)互补
        //distinct:筛选, 通过流所生成元素的hashCode()和equals()方法去除重复元素。
        Book[] books = new Book[10];
        //中间操作:多个中间操作可连接起来形成一个流水线,但中间操作不会立即执行任何处理,除非流水线上触发终止操作时才会一次性全部处理,称为“随性求值”
//        内部迭代,迭代操作由Stream API 完成
        List<Book> bookList = (List<Book>) Arrays.asList(books).stream()
                .filter(e -> e.getPrice()>10f).limit(2);
        //终止操作:一次性执行全部操作, 即: 随性求值
        bookList.forEach(System.out::println);

        List<Book> bookList2 = (List<Book>) Arrays.asList(books).stream()
                .filter(e -> {
                    System.out.println("Stream API 的中间操作");
                    return e.getPrice()>10f;
                }).limit(2);//limit 一但发现了指定数据的数据就返回不继续筛选。
        bookList2.forEach(System.out::println);

        List<Book> bookList3 = (List<Book>) Arrays.asList(books).stream()
                .filter(e -> {
                    System.out.println("Stream API 的中间操作");
                    return e.getPrice()>10f;
                }).skip(2);
        bookList3.forEach(System.out::println);

        //去重,Book必须重写hashCode()和equals()方法
        List<Book> bookList4 = (List<Book>) Arrays.asList(books).stream()
                .distinct();
        bookList4.forEach(System.out::println);
 public static Stream<Character> filterCharacter(String str){
        List<Character> list = new ArrayList<>();
        for(Character c : str.toCharArray()){
            list.add(c);
        }
        return list.stream();
    }
 //映射
        //map: 接收Lambda, 将元素转换成其它形式可提取信息。接收一个函数作为参数,该函数会被应用到每个元素上并将其映射成一个新元素
        //flatMap: 接收一个函数作为参数,将流中每一个值都换成另一个流,然后把所有流连接成一个流
        List<String> list = Arrays.asList("aaa","bbb","ccc","ddd","eee");

        list.stream()
                .map(str -> str.toUpperCase())  //都转换成大写
                .forEach(System.out::println);

        Book[] books = new Book[10];
        Arrays.stream(books)
                .map(e->e.getName())//取出所有书名组成一个新的数组
                .forEach(System.out::println);

        Arrays.stream(books)
                .map(Book::getName)//取出所有书名组成一个新的数组
                .forEach(System.out::println);

        Stream<Stream<Character>> stream = list.stream().map(StreamTest::filterCharacter);
        stream.forEach(e -> e.forEach(System.out::println));

        Stream<Character> stream1 = list.stream().flatMap(StreamTest::filterCharacter);
        stream1.forEach(System.out::println);
 //排序
        //sorted: 自然排序 (Comarable)
        //sorted(Comparator com): 定制排序
        List<String> list = Arrays.asList("aaa","fff","bbb","ccc","ddd","eee");

        list.stream().sorted().forEach(System.out::println);

        Book[] books = new Book[10];
        List<Book> bookList = (List<Book>) Arrays.asList(books).stream()
                .sorted((e1,e2) -> {
                    if(e1.getPrice().equals(e2.getPrice())){
                        return e1.getName().compareTo(e2.getName());
                    }else{
                        return e1.getPrice().compareTo(e2.getPrice());//升序
//                        return -e1.getPrice().compareTo(e2.getPrice());//降序
                    }
                });
        bookList.forEach(System.out::println);

3、终止操作

package com.example.enums;

import java.util.Objects;
import java.util.stream.Stream;

public enum Status {

    HAVING(1,"有货"),
    NON(2,"无货"),
    ;

    private final Integer type;
    private final String name;

    Status(Integer type, String name) {
        this.type = type;
        this.name = name;
    }

    public static  Status of(Integer type){
        Objects.requireNonNull(type,"是否有货");
        return Stream.of(values()).filter(bean->bean.type.equals(type))
                .findAny()
                .orElseThrow(() -> new IllegalArgumentException("是否有货为:"+ type + "的是否有货类型在枚举中不存在"));
    }
}
package com.example.pojo;

import com.example.enums.Status;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;

import java.io.Serializable;
import java.util.Date;
import java.util.Objects;

public class Book implements Serializable{

    private static final long serialVersionUID = -5682718161792139284L;
    private Integer id;
    private String name;
    private String author;
    @JsonIgnore
    private Float price;
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date publicationDate;

    private Status status;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public Float getPrice() {
        return price;
    }

    public void setPrice(Float price) {
        this.price = price;
    }

    public Date getPublicationDate() {
        return publicationDate;
    }

    public void setPublicationDate(Date publicationDate) {
        this.publicationDate = publicationDate;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Book book = (Book) o;
        return Objects.equals(id, book.id) &&
                Objects.equals(name, book.name) &&
                Objects.equals(author, book.author) &&
                Objects.equals(price, book.price) &&
                Objects.equals(publicationDate, book.publicationDate) &&
                status == book.status;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name, author, price, publicationDate, status);
    }

}
//查找与匹配
        //allMatch:检查是否匹配所有元素
        //anyMatch:检查是否匹配至少一个元素
        //noneMatch:检查是否没有匹配所有元素
        //findFirst:返回第一个元素
        //findAny:返回当前流中的任意元素
        //count:返回当前流中的总个数
        //max:返回流中的最大值
        //min:返回流中的最小值
        Book[] books = new Book[10];
        List<Book> bookList = (List<Book>) Arrays.asList(books);
        Boolean b = bookList.stream().allMatch(e->e.getStatus().equals(Status.HAVING));

        Boolean b1 = bookList.stream().anyMatch(e->e.getStatus().equals(Status.HAVING));

        Boolean b2 = bookList.stream().noneMatch(e->e.getStatus().equals(Status.NON));

        Optional<Book> op = bookList.stream()
                .sorted((e1,e2) -> -e1.getPrice().compareTo(e2.getPrice()))
                .findFirst();
        System.out.println(op.get());

        Optional<Book> op2 = bookList.stream()  //串行:一个一个找
                .filter(e -> e.getStatus().equals(Status.HAVING))
                .findAny();
        System.out.println(op2.get());

        Optional<Book> op3 = bookList.parallelStream() //并行:多头同时找
                .filter(e -> e.getStatus().equals(Status.HAVING))
                .findAny();
        System.out.println(op3.get());

        Long count = bookList.stream().count();

        Optional<Book> op4 = bookList.stream()
                .max((e1,e2) -> e1.getPrice().compareTo(e2.getPrice()));
        System.out.println(op4.get());
        Optional<Float> op5= bookList.stream()
                .map(Book::getPrice)
                .min(Float::compare);
        System.out.println(op5.get());
//        归约  : 将流中元素反复结合起来得到一个值
        //reduce(T identity,BinaryOperator)
        //reduce(BinaryOperator)

        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);

        Integer sum = list.stream().reduce(0,(x,y)->x+y);
        System.out.println(sum);

        Book[] books = new Book[10];
        List<Book> bookList = (List<Book>) Arrays.asList(books);
        Optional<Float> sum2 = bookList.stream()
                .map(Book::getPrice)
                .reduce(Float::sum);
        System.out.println(sum2.get());
//收集
        //collect: 将流转换为其他形式,接收一个Collector接口的实现,用于给Stream中的元素做汇总的方法
        Book[] books = new Book[10];
        List<Book> bookList = (List<Book>) Arrays.asList(books);
        List<String> booknames = bookList.stream()
                .map(Book::getName)
                .distinct()
                .collect(Collectors.toList());
        booknames.forEach(System.out::println);

        Set<String> booknames2 = bookList.stream()
                .map(Book::getName)
                .collect(Collectors.toSet());
        booknames2.forEach(System.out::println);

        HashSet<String> booknames3 = bookList.stream()
                .map(Book::getName)
                .collect(Collectors.toCollection(HashSet::new));
        booknames3.forEach(System.out::println);

        //总数
        Long count = bookList.stream()
                .collect(Collectors.counting());

        //平均数
        Double avg = bookList.stream().collect(Collectors.averagingDouble(Book::getPrice));

        //总和
        Double sum = bookList.stream().collect(Collectors.summingDouble(Book::getPrice));

        //最大值
        Optional<Book> max = bookList.stream()
                .collect(Collectors.maxBy((e1,e2)->Float.compare(e1.getPrice(),e2.getPrice())));

        //最小值
        Optional<Book> min = bookList.stream()
                .collect(Collectors.minBy((e1,e2)->Float.compare(e1.getPrice(),e2.getPrice())));

        //分组
        Map<Status,List<Book>> map = bookList.stream()
                .collect(Collectors.groupingBy(Book::getStatus));

        //多级分组
        Map<Status,Map<String,List<Book>>> map2 = bookList.stream()
                .collect(Collectors.groupingBy(Book::getStatus,Collectors.groupingBy(e -> {
                    if(e.getPrice()<10f){
                        return "秒杀";
                    }else if(e.getPrice()<20f){
                        return "促销";
                    }else{
                        return "现货";
                    }

                })));

        //分区
        Map<Boolean,List<Book>> map3 = bookList.stream()
                .collect(Collectors.partitioningBy(e->e.getPrice()<20f));


        DoubleSummaryStatistics summaryStatistics = bookList.stream().collect(Collectors.summarizingDouble(Book::getPrice));
        System.out.println(summaryStatistics.getMax());
        System.out.println(summaryStatistics.getAverage());
        System.out.println(summaryStatistics.getCount());
        System.out.println(summaryStatistics.getSum());
        System.out.println(summaryStatistics.getMin());


        String str = bookList.stream()
                .map(Book::getName)
                .collect(Collectors.joining(","));
        System.out.println(str);
原文地址:https://www.cnblogs.com/mingforyou/p/14725603.html