记一下 Stream 流操作

发布于:2024-06-28 ⋅ 阅读:(23) ⋅ 点赞:(0)

Java Stream流

Function.identity()获取原流中的值

创建流

Collection.stream() / Collection.parallelStream():从集合生成流,后者为并行流。

List<String> list = new ArrayList<>();
Stream<String> stream = list.stream(); //获取一个顺序流
Stream<String> parallelStream = list.parallelStream(); //获取一个并行流

Arrays.stream(T[] array):从数组生成流。

Integer[] nums = new Integer[10];
Stream<Integer> stream = Arrays.stream(nums);

IntStream.range(int startInclusive, int endExclusive):生成一个包含从startInclusive到endExclusive(不包括)的整数序列的流。

Stream.of(T… values):从给定值创建流。

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);

中间操作

map

对流中的每个元素应用一个函数,并将该函数应用的结果作为新的流返回。这个过程是转换性的,意味着它会产生一个新的流,其中的元素是原始元素经过转换后的结果。(对流中每个元素进行函数处理,并返回一个处理后的新流)

  List<Integer> squares = numbers.stream()
                                .map(n -> n * n)
                                .collect(Collectors.toList());

flatMap

对流中的每个元素应用一个函数,这个函数会将每个元素转换为另一个流,然后将所有这些流连接成一个单一的流。()

MapTOxxx

单独流中某属性创建一个新的流用以接收(常用于从对象的流中捕获指定属性)

filter 过滤

filter:用于对Stream流中的数据进行过滤
filter(Predicate<? super T>predicate)
filter方法的参数Predicate是一个函数式接口,可以使用lambda表达式
Predicate中的抽象方法
boolean test(T t)

List<User> user1 = new ArrayList<>();
        // 基础
        for (User user : users) {
            if (user.getId()%2==0){
                user1.add(user);
            }
        }
        //1:lambda
        List<User> user2 = users.stream().filter((user)->user.getId()%2==0).collect(Collectors.toList());

        //2: 匿名内部类 重写 Predicate#test
        List<User> user3 = users.stream().filter(new Predicate<User>() {
            @Override
            public boolean test(User user) {
                return user.getId()%2==0;
            }
        }).collect(Collectors.toList());

        //3: 方法引用 需要在 User类中 新增boolean isEven(User user) 方法
        //List<User> user4 = users.stream().filter(User::isEven).collect(Collectors.toList());

distinct 去重


list1.stream().distinct().collect(Collectors.toList());

注:对于基本数据类型通过 == 判定值是否相同。引用数据类型通过其 equals() 方法判定。

limit 截取

limit:用于截取流中的元素
limit可以对流进行截取,只取用前n个
limit(long maxSize); [0,maxSize)
参数是一个long型,如果集合当前长度大于参数则进行截取,否则不进行操作
limit是一个延迟方法,可以继续使用Stream流方法


list1.stream().limit(2).collect(Collectors.toList());

skip 跳过

skip :用于截取流中的元素
skip 可以对流进行截取,只取用前n个
skip (long minSize); [minSize,-1]
参数是一个long型,如果集合当前长度大于参数则进行截取,否则不进行操作


list1.stream().skip(2).collect(Collectors.toList());

sorted 排序

sorted 对流中的内容进行排序
对于基本数据类型直接比较排序
对于对象则需要对象实现对应的 compareTo 接口才能直接调用比较方法

list.stream().sorted().collect(Collectors.toList()); // 默认升序     

list.stream().sorted(Comparator.comparing(Integer::intValue)).collect(Collectors.toList());

list.stream().sorted((o1, o2) -> o1.compareTo(o2)).collect(Collectors.toList());// 根据返回值判定 正-升,0-等,负-降

list.stream().sorted(new Comparator<Integer>() {
     @Override
      public int compare(Integer o1, Integer o2) {
          return o1 - o2;
      }
}).collect(Collectors.toList());

//对于实体类 
users.stream().sorted().collect(Collectors.toList()); //该类必须实现 compareTo 接口

users.stream().sorted(Comparator.comparing(User::getId)).collect(Collectors.toList());

users.stream().sorted((o1, o2) -> o1.getAccount().compareTo(o2.getAccount())).collect(Collectors.toList());

users.stream().sorted(new Comparator<User>() {
   @Override
   public int compare(User o1, User o2) {
       return o1.getId().compareTo(o2.getId());
   }
}).collect(Collectors.toList());

reduce统计

users.stream().map(User::getId).collect(Collectors.toList());
users.stream().map(user -> user.getId()).reduce((o1, o2) -> o1+o2);

终止操作

forEach遍历

users.stream().forEach();

list 转 list

最终结果或流内容提取

list.stream().map(User::getId).collect(Collectors.toList());```

List 转 Map

从流内容中获取关注部分

Map<Long, User> collect = users.stream().collect(Collectors.toMap(user -> user.getId(), user -> user));

anyMatch 短路匹配 boolean

匹配到一个就返回 true

users.stream().anyMatch(user -> user.getName().length()==3)

allMatch 全部匹配 boolean

所有的都要满足条件才返回true

sers.stream().allMatch(user->user.getId()>1)

noneMatch 全部不匹配boolean

所有的都不满足条件才返回true

sers.stream().noneMatch(user->user.getId()>1)

findAny/findFirst 查找 obj

  //随机获取流中的一个元素,串行流为第一个,并行流可能随机
  Optional<User> any = users.stream().findAny();
  User user1 = any.get();
  //ifPresent 如果存在则执行
  users.stream().findAny().ifPresent(user -> System.out.println(user));
  //findFirst 不论串行、并行都获取第一个
  users.stream().findFirst().ifPresent(user -> System.out.println(user));

收集齐中joining() 方法 string

list.stream().map(String::valueOf).collect(Collectors.joining("-"));
users.stream().map(user -> user.getName()).collect(Collectors.joining("-"));

0-1-2-3-4-5-6-7-8-9
岇鶯翰-逼隗埈蝠-飇冼剉-丟诈乴喪-餢鞋損-辶陀膗葷-铚鈭膕-痷鰎墕熢-釅烸麉-搂軄汿榿

分组 Collectors.groupingBy()

items.stream().collect(Collectors.groupingBy(Function.identity()));
list.stream().collect(Collectors.groupingBy(User::getSex));
Map<String, Long> result2 = items.stream().collect(
                Collectors.groupingBy(
                        Function.identity(), Collectors.counting()
                )
        );  

最值max,min

从流中获取最大的值

list.stream().max(Comparator.comparing(Integer::intValue)).get();// 9
users.stream().max(Comparator.comparing(User::getId)).get(); // id10
users.stream().min(Comparator.comparing(User::getAccount)).get();  // id9
users.stream().max(((o2, o1) -> o1.getId().compareTo(o2.getId()))).get(); //id 1
users.stream().min(((o2, o1) -> o1.getId().compareTo(o2.getId()))).get(); //id 10

注:需要传入一个比较器,因此取到的最大值不一定就是真的最大值,根据你的比较器做的选值(源码如下截图);

在这里插入图片描述

average 平均值

顾名思义取平均值常与 mapToInt、mapToDouble 使用

复合使用(实战)