3.Stream流(最重要)

3.Stream流(最重要)

3.1概述

Java8的Stream使用的是函数式编程榄式,如同它的名字一样,它可以被用来对集合成数组进行链状流式的操作。可以更方便的让我们对集合或数组操作。

3.2 案例数据准备

Author

package com.tian;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.util.List;

@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class Author {
    private Long id;
    private String name;
    private Integer age;
    private String intro;
    private List<Book> books;
}

Book

package com.tian;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;



@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class Book {
    private Long id;
    private String name;
    private String category;
    private Integer score;
    private String intro;


}

StreamDemo

package com.tian;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class StreamDemo {
    public static void main(String[] args) {
        List<Author> authors = getAuthors();
        System.out.println(authors);
    }

    private static List<Author> getAuthors(){
        Author author = new Author(1L, "zhangsan1", 33, "张三", null);
        Author author2 = new Author(2L, "zhangsan2", 15, "张三", null);
        Author author3 = new Author(3L, "zhangsan3", 14, "张三", null);
        Author author4 = new Author(3L, "zhangsan4", 14, "张三", null);
        List<Book> book1 = new ArrayList<Book>();
        List<Book> book2 = new ArrayList<Book>();
        List<Book> book3 = new ArrayList<Book>();
        book1.add(new Book(1L,"光明1","哲学",88,"光明与黑暗的战斗"));
        book1.add(new Book(2L,"光明2","哲学",77,"光明与黑暗的战斗"));
        book2.add(new Book(3L,"光明3","哲学",66,"光明与黑暗的战斗"));
        book2.add(new Book(3L,"光明3","哲学",55,"光明与黑暗的战斗"));
        book2.add(new Book(4L,"光明4","哲学",44,"光明与黑暗的战斗"));
        book3.add(new Book(5L,"光明5","哲学",33,"光明与黑暗的战斗"));
        book3.add(new Book(6L,"光明6","哲学",22,"光明与黑暗的战斗"));
        book3.add(new Book(6L,"光明6","哲学",11,"光明与黑暗的战斗"));
        author.setBooks(book1);
        author2.setBooks(book2);
        author3.setBooks(book3);
        author4.setBooks(book3);
        ArrayList<Author> authorList = new ArrayList<Author>(Arrays.asList(author, author2, author3, author4));
        return authorList;

    }
}

3.3 快速入门

        List<Author> authors = getAuthors();
        //打印所有年龄小于18的作家的名字,并且要注意去重
        authors.stream()//把集合转换成流
                .distinct() //去重
                .filter(author -> author.getAge()<18) //筛选年龄小于18的
                .forEach(author -> System.out.println(author.getName())); //打印
  //zhangsan2
  //zhangsan3
//必须要有终结操作 这里就是forEach
创建流

单列集合 集合对象.stream()

 List<Author> authors = getAuthors();
 authors.stream()

数组 Arrays.stream(数组)或者使用Stream.of来创建

    Integer[] arr={1,2,3,4,5};
        Stream<Integer> stream = Arrays.stream(arr);
        stream.distinct()
                .filter(integer -> integer%2==0)
                .forEach(integer -> {
            System.out.println(integer);
        });
// 2 4
//了解即可
Stream<Integer> arr1 = Stream.of(arr);
arr1.distinct().forEach();

双列集合:转换成单列集合再创建

  Map<String, Integer> map = new HashMap<>();
        map.put("张三1",18);
        map.put("张三2",19);
        map.put("张三3",20);
        Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
        Stream<Map.Entry<String, Integer>> stream1 = entrySet.stream();
        stream1.distinct()
                .filter(stringIntegerEntry -> stringIntegerEntry.getValue()>19)
                .forEach(stringIntegerEntry -> System.out.println(stringIntegerEntry.getKey()+"---"+stringIntegerEntry.getValue()));
            //张三3---20
filter操作
 //打印所有姓名长度大于1的作家的名字
        authors.stream()
                .filter(author -> author.getName().length()>1)
                .forEach(author -> System.out.println(author));
map

可以把对流中的元素进行计算或转换

//打印所有作家的姓名
//  authors.stream().forEach(author -> System.out.println(author.getName()));
//参数Author 返回值String
List<Author> authors = getAuthors();            
authors.stream()
    .map(author -> author.getName())
    .forEach(s -> System.out.println(s));

	
authors.stream()
    .map(author -> author.getAge())
    .map(age->age+10)
    .forEach(age-> System.out.println(age));

}
distinct

去重

注意:distinct方达是依赖object的equals方法来判断是否是相同对象的。所以需要注意重写equals方法。

 //打印所有作家名称 并不能重复
        List<Author> authors = getAuthors();
        authors.stream()
                .distinct()
                .forEach(author -> System.out.println(author));
sorted

可以对流中的元素进行排序

# 如果调用了空参的sorted()方法 需要流中的元素必须实现Comparable
    


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Objects;

@Data
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
public class Author implements Comparable<Author>{
    private Long id;
    private String name;
    private Integer age;
    private String intro;
    private List<Book> books;


    @Override
    public int compareTo(Author o) {
        return o.getAge()-this.getAge();//降序
    }
}

    List<Author> authors = getAuthors();
        //对流中的元素按照年龄进行降序排序,并且要求不能有重复的元素
        authors.stream()
                .distinct()
                .sorted()
                .forEach(author -> System.out.println(author.getAge()));

# 有参的sorted()方法
 //对流中的元素按照年龄进行降序排序,并且要求不能有重复的元素
        authors.stream()
                .distinct()
                .sorted((o1, o2) -> o2.getAge()-o1.getAge()) //降序
                .forEach(author -> System.out.println(author.getAge()));
limit

可以设置流的最大长度,超出的部分将被抛弃

    List<Author> authors = getAuthors();
        //对流中的元素按照年龄进行降序排序,并且要求不能有重复的元素,然后打印年龄最大的两个作家的姓名
        authors.stream()
                .distinct()
                .sorted((o1, o2) -> o2.getAge()-o1.getAge()) //降序
                .limit(2)
                .forEach(author -> System.out.println(author.getName()));

skip

通过流中的前n个元素,返回剩下的元素

      //打印除了年龄最大的作家外的其他作家 要求不能有重复元素,并且年龄降序
        authors.stream()
                .distinct()
                .sorted((o1, o2) -> o2.getAge()-o1.getAge()) //降序
                .skip(1)
                .forEach(author -> System.out.println(author.getName()));
   
flatMap

map只能把一个对象转换成另一个对象来作为流中的元素。而flatMap可以把一个对象转换成多个对象作为流中的元素

// 例一
  //打印所有书籍的名字,要求对重复的元素进行去重
        List<Author> authors = getAuthors();
        authors.stream()
               .flatMap(author -> author.getBooks().stream())
               .distinct()
                .forEach(book -> System.out.println(book.getName()));
//例二
 List<Author> authors = getAuthors();
        //打印现有数据的所有分类 要求对分类进行去重 不能出现这种格式:哲学,爱情
        authors.stream()
               .flatMap(author -> author.getBooks().stream())
                .distinct() //去重书籍
                .flatMap(book -> Arrays.stream(book.getCategory().split(",")))
                .distinct() //去重分类
                .forEach(category->{
                    System.out.println(category);
                });
终结操作
forEach
   //输出所有作家的名字
        List<Author> authors = getAuthors();
        authors.stream()
                .map(author -> author.getName())
                .distinct()
                .forEach(name-> System.out.println(name));
count

可以获取当前流中元素的个数

  //打印这些作家的所出书籍的题目,注意删除重复元素
        List<Author> authors = getAuthors();
        long count = authors.stream()
                .flatMap(author -> author.getBooks().stream())
                .distinct()
                .count();
        System.out.println(count);
max&min
    //分别获取这些作家的所出书籍的最高分和最低分并打印
        List<Author> authors = getAuthors();
        Optional<Integer> max = authors.stream()
                .flatMap(author -> author.getBooks().stream())
                .map(book -> book.getScore())
                .max((score1, score2) -> score1 - score2);
        System.out.println(max.get());

        Optional<Integer> min = authors.stream()
                .flatMap(author -> author.getBooks().stream())
                .map(book -> book.getScore())
                .min((score1, score2) -> score1 - score2);
        System.out.println(min.get());
collect

把当前流转换成一个集合

        //获取一个存放所有作者名字的List集合
        List<Author> authors = getAuthors();
        List<String> nameList = authors.stream()
                .map(author -> author.getName())
                .collect(Collectors.toList());
        System.out.println(nameList);

        //获取一个所有书名的set集合
        Set<Book> collect = authors.stream()
                .flatMap(author -> author.getBooks().stream())
                .collect(Collectors.toSet());
        System.out.println(collect);

        //获取一个Map集合,map的key为作者名,value为List<Book>
        Map<String, List<Book>> map = authors.stream()
                .distinct()
                .collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));
        System.out.println(map);
3.4 查找与匹配

anyMatch

可以用来判断是否有任意符合条件的元素,结果为boolean类型

   //判断是否有年龄在29以上的作家
        List<Author> authors = getAuthors();
        boolean b = authors.stream()
                .anyMatch(author -> author.getAge() > 29);
        System.out.println(b);

allMatch

可以用来判断是否都符合匹配条件,结果为boolean类型,如果都符合结果为true,否则结果为false

 //判断是否所有的作家都是成年人
        boolean b1 = authors.stream()
                .allMatch(author -> author.getAge() > 18);
        System.out.println(b1);

noneMatch

可以用来判断是否都不符合匹配条件,结果为boolean类型,如果都不符合结果为true,否则结果为false

  //否所有的作家年龄都没有超过100岁
        boolean b2 = authors.stream()
                .noneMatch(author -> author.getAge() > 100);
        System.out.println(b2);

findAny

获取流中的任意一个元素,该方法没有办法保证获取的一定是流中的第一个元素

     //获取任意一个年龄大于18的作家,如果存在输出他的名字
        List<Author> authors = getAuthors();
        Optional<Author> optionalAuthor = authors.stream()
                .filter(author -> author.getAge() > 18)
                .findAny();
        optionalAuthor.ifPresent(author -> System.out.println(author.getName()));

findFirst

获取流中的第一个元素

   //获取一个年龄最小的作家,并输出他的姓名
        Optional<Author> first = authors.stream()
                .sorted(((o1, o2) -> o1.getAge() - o2.getAge()))
                .findFirst();
        first.ifPresent(author -> System.out.println(author.getName()));

3.5 reduce归并

对流中的数据按眠你旨定的计算方式计算出一个结果。(缩减操作)

​ reduce的作用是把stream中的元素给组合起来,我们可以传入一个初始值,它会按照我们的计算方式依次拿流中的元素和初始化值进行计算,计算结果再和后面的元素计算。

​ reduce两个参数的重载形式内部的计算方法如下:

T result=identity;
for (T element: this stream )
    result= accumulator.apply(result, element)
return result;

其中identity就是我们可以通过方法参数传入的初始值,accumulator的apply具体进行什么计算也是我们通过方法参数来确定的。

       //使用reduce求所有作者年龄的和
        List<Author> authors = getAuthors();
        Integer sum = authors.stream()
                .distinct()
                .map(author -> author.getAge())
                .reduce(0, (result, element) -> result + element);
        System.out.println(sum);

        //使用reduce求所有作者中年龄的最大值
        Integer max = authors.stream()
                .map(author -> author.getAge())
                .reduce(Integer.MIN_VALUE, (result, element) -> result < element ? element : result);
        System.out.println(max);


        //使用reduce求所有作者中年龄的最小值
        Integer min = authors.stream()
                .map(author -> author.getAge())
                .reduce(Integer.MAX_VALUE, (result, element) -> result > element ? element : result);
        System.out.println(min);
        Optional<Integer> reduce = authors.stream()
                .map(author -> author.getAge())
                .reduce((result, element) -> result > element ? element : result);
        reduce.ifPresent(age-> System.out.println(age));

3.5注意事项

  • 惰性求值I (如果没有终结操作,没有中间操作是不会得到执行的)
  • 流是一次性的(一旦一个流对象经过一个终结操作后。这个流就不能再被使用)
  • 不会影响原数据(我们在流中可以多数据做很多处理。但是正常情况下是不会影响原来集合中的元素的。这往往也是我们期望的)
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值