Java Stream的讲解

Stream的概述

Stream是java 8新增的特性,用来补充集合类。
Stream就是流,流中的数据元素的数量可以是有限个数,也可能是无限个数。

Stream的特性

  • 不存储数据:流失基于数据源的对象,它本身不存储数据元素,而是通过管道蒋淑媛的元素传递操作。
  • 函数式编程:流在每一级的操作中,都会新创建一个副本,例如执行filter不会将数据源中的数据进行删除。
  • 具有顺序不可逆性:每一个级别的操作都是按照编写的顺序进行的,下一个操作会基于上一个操作。

流的创建方法

  1. 使用Collection.stream()直接获取流对象
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream(); //获取一个顺序流
Stream<String> parallelStream = list.parallelStream(); //获取一个并行流
  1. 数组直接转成流对象
Integer[] nums = new Integer[10];
Stream<Integer> stream = Arrays.stream(nums);

  1. 使用Stream中的静态方法:of(),iterate(),generate()
Stream<Integer> stream = Stream.of(1,2,3,4,5,6);
 
Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 2).limit(6);
stream2.forEach(System.out::println); // 0 2 4 6 8 10
 
Stream<Double> stream3 = Stream.generate(Math::random).limit(2);
stream3.forEach(System.out::println);

  1. 使用 BufferedReader.lines() 方法,将每行内容转成流
BufferedReader reader = new BufferedReader(new FileReader("F:\\test_stream.txt"));
Stream<String> lineStream = reader.lines();
lineStream.forEach(System.out::println);

  1. 使用 Pattern.splitAsStream() 方法,将字符串分隔成流
Pattern pattern = Pattern.compile(",");
Stream<String> stringStream = pattern.splitAsStream("a,b,c,d");
stringStream.forEach(System.out::println);

流的操作(流的操作包括中间操作和终端操作,中间操作通常是一些过滤,求值操作,终端操作为统计,或者转换为某种容器的操作)

流的中间操作

  • filter(表达式):过滤流中的某些元素,获取流中符合表达式的元素
  Stream<Integer> integerStream=Stream.of(1,2,3,4,5,6);
        List<Integer> integerList=integerStream
                .filter(integer -> integer.intValue()<5)
                .collect(Collectors.toList());
        System.out.println(integerList);

结果为:在这里插入图片描述

-limit(n):n为数值,获取流中的前n个元素

 Stream<Integer> integerStream=Stream.of(1,2,3,4,5,6);
        List<Integer> integerList=integerStream
                .filter(integer -> integer.intValue()<5)
                .limit(3)
                .collect(Collectors.toList());
        System.out.println(integerList);

在这里插入图片描述

-skip(n):跳过前n元素,配合limit(n)可实现分页

 Stream<Integer> integerStream=Stream.of(1,2,3,4,5,6);
        List<Integer> integerList=integerStream
                .filter(integer -> integer.intValue()<5)
                .limit(3)
                .skip(2)
                .collect(Collectors.toList());
        System.out.println(integerList);

在这里插入图片描述
原本应该是[1,2,3],调用skip(2)后,跳过前面两个元素

  • distinct:通过流中元素的 hashCode() 和 equals() 去除重复元素
   Stream<Integer> integerStream=Stream.of(1,2,2,4,5,6,6,7,8);
        List<Integer> integerList=integerStream
                .skip(2)
                .distinct()
                .collect(Collectors.toList());
        System.out.println(integerList);

在这里插入图片描述

  • 映射
  • map:接收一个函数作为参数,该函数会被应用到每一个元素上,并将其根据函数转换成为一个新的元素。
  Stream<Integer> integerStream=Stream.of(1,2,2,4,5,6,6,7,8);
        List<Integer> integerList=integerStream
                .map(integer -> integer+2)
                .collect(Collectors.toList());
        System.out.println(integerList);

每个元素都进行了+2的操作

  • flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后将所有的流连接成为一个流。
  public static List<Integer> getLessThan(Integer integer) {
        return Stream.iterate(0, x -> x + 1).limit(integer).collect(Collectors.toList());
    }

    public static void main(String[] args) {
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4);
        List<Integer> integerList = integerStream.flatMap(s -> {
            return getLessThan(s).stream();
        })
                .collect(Collectors.toList());
        System.out.println(integerList);
    }

在这里插入图片描述

  • 排序
  • sorted():自然排序,流中的元素需实现Comparable接口
  • sorted(Comparator comparator ):定制排序,自定义Comparator排序器

自然排序:
先实现comparable接口

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Comparable<User> {
    private String name;
    private Integer age;
    private String phone;

    @Override
    public int compareTo(User user) {
        return user.age-this.getAge();
    }
}
    List<User> userList=new ArrayList<>();
        User user=new User("张三",22,"17806533481");
        User user2=new User("李四",27,"18906533481");
        User user3=new User("王老五",28,"15806533481");
        userList.add(user);
        userList.add(user2);
        userList.add(user3);
       List<User> list=userList.stream().sorted().collect(Collectors.toList());
        System.out.println(list);

在这里插入图片描述
自定义排序:不需要实现comparable接口,直接使用比较器

 List<User> userList=new ArrayList<>();
        User user=new User("张三",29,"17806533481");
        User user2=new User("李四",27,"18906533481");
        User user3=new User("王老五",28,"15806533481");
        User user4=new User("赵六",27,"15806533481");
        userList.add(user);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);
       List<User> list=userList.stream().sorted((o1,o2)->{
           if (o1.getAge()> o2.getAge()){
               return 1;
           }else if (o1.getAge()<o2.getAge()){
               return -1;
           }else {
               return 0;
           }
       }).collect(Collectors.toList());
        System.out.println(list);

结果按照age升序
在这里插入图片描述

  • 消费
    如同于map,能获得流中的每一个元素,但是map接受的是Function表达式,具有返回值,而peek接受的是Consumer表达式,没有返回值,只进行消费,可以是输出,或者是外部处理。
List<User> userList=new ArrayList<>();
        User user=new User("张三",29,"17806533481");
        User user2=new User("李四",27,"18906533481");
        User user3=new User("王老五",28,"15806533481");
        User user4=new User("赵六",27,"15806533481");
        userList.add(user);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);

       userList.stream().peek(System.out::println)
               .collect(Collectors.toList());

在这里插入图片描述

流的终端操作

allmatch,noneMatch,anyMatch用于对集合中对象的某一个属性值进行判断,
allMatch全部符合该条件返回true,
noneMatch全部不符合该断言返回true
anyMatch 任意一个元素符合该断言返回true

  • allMatch
List<User> userList=new ArrayList<>();
        User user=new User("张三",29,"17806533481");
        User user2=new User("李四",27,"18906533481");
        User user3=new User("王老五",28,"15806533481");
        User user4=new User("赵六",27,"15806533481");
        userList.add(user);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);

        boolean allMatch= userList.stream().allMatch(user1 -> user1.getAge()<30);
        System.out.println(allMatch);

结果为true;

  • noneMatch
List<User> userList=new ArrayList<>();
        User user=new User("张三",29,"17806533481");
        User user2=new User("李四",27,"18906533481");
        User user3=new User("王老五",28,"15806533481");
        User user4=new User("赵六",27,"15806533481");
        userList.add(user);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);

        boolean noneMatch= userList.stream().noneMatch((user1 -> user1.getAge()>30));
        System.out.println(noneMatch);

判断user.age()是不是没有任何一个大于30,结果是的

  • anyMatch
 List<User> userList=new ArrayList<>();
        User user=new User("张三",29,"17806533481");
        User user2=new User("李四",27,"18906533481");
        User user3=new User("王老五",31,"15806533481");
        User user4=new User("赵六",27,"15806533481");
        userList.add(user);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);

        boolean anyMatch= userList.stream().anyMatch((user1 -> user1.getAge()>30));
        System.out.println(anyMatch)

判断是否至少有一个,符合条件。

findFirst:返回流中第一个元素

findAny:返回流中的任意元素

 List<User> userList = new ArrayList<>();
        User user = new User("张三", 29, "17806533481");
        User user2 = new User("李四", 27, "18906533481");
        User user3 = new User("王老五", 31, "15806533481");
        User user4 = new User("赵六", 27, "15806533481");
        userList.add(user);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);

        User userFirst =userList.stream().findFirst().get();
        System.out.println(userFirst);

在这里插入图片描述

count:返回流中元素的总个数

   List<User> userList = new ArrayList<>();
        User user = new User("张三", 29, "17806533481");
        User user2 = new User("李四", 27, "18906533481");
        User user3 = new User("王老五", 31, "15806533481");
        User user4 = new User("赵六", 27, "15806533481");
        userList.add(user);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);

        Long aLong =userList.stream().count();
        System.out.println(aLong);

在这里插入图片描述

max:返回流中元素最大值

 List<User> userList = new ArrayList<>();
        User user = new User("张三", 29, "17806533481");
        User user2 = new User("李四", 27, "18906533481");
        User user3 = new User("王老五", 31, "15806533481");
        User user4 = new User("赵六", 27, "15806533481");
        userList.add(user);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);

        User userMax = userList.stream().max((u1, u2) -> {
            if (u1.getAge() > u2.getAge()) {
                return 1;
            } else if (u1.getAge() < u2.getAge()) {
                return -1;
            } else {
                return 0;
            }
        }).get();
        System.out.println(userMax);

在这里插入图片描述
min:返回流中元素最小值

   List<User> userList = new ArrayList<>();
        User user = new User("张三", 29, "17806533481");
        User user2 = new User("李四", 27, "18906533481");
        User user3 = new User("王老五", 31, "15806533481");
        User user4 = new User("赵六", 20, "15806533481");
        userList.add(user);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);

        User userMin = userList.stream().min((u1, u2) -> {
            if (u1.getAge() > u2.getAge()) {
                return 1;
            } else if (u1.getAge() < u2.getAge()) {
                return -1;
            } else {
                return 0;
            }
        }).get();
        System.out.println(userMin);

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值