Stream流式操作集合(下)

133 阅读2分钟

这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战

前言

上一篇章我们为Stream开了一个头,但是没有进行Stream的讲解,本篇章将带大家了解一下Stream流的操作。

image.png

Stream的组成

下面就是一个简单地Stream例子

List<String> list = water.stream()
             .filter(e -> e.startsWith("L")) //以L开头的
             .map(String::toUpperCase) //所有字母变为大写
             .sorted() //进行排序
             .collect(toList()); //转为List 聚合

我们把Stream分为三个部分,数据源、数据处理、收集结果。 首先Stream的数据源需要通过集合的stream方法获取,而过滤使用Stream的filter方法,最后收集使用collect方法。

water.stream()  //先把它转为数据源
.filter() //你需要过滤的条件,把它比作我们的上面的滤网
.filter() //你的第二个过滤条件, 第二个滤网
.collect() //最后收集结果

filter的条件如何定义

从上述代码中我们可以看出,filter需要我们提供滤网的条件,那么条件就是需要程序员自己提供,也就是你希望流过滤什么不过滤什么。filter的参数是个Predicate p1 = new 类,那么我们就可以吧上面转为下面方式。进入这个类我们可以发现他是一个函数式接口,这也就意味着可以使用我们上一篇章讲的lambda函数

@FunctionalInterface
public interface Predicate<T> {

    boolean test(T t);

    default Predicate<T> and(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) && other.test(t);
    }

    default Predicate<T> negate() {
        return (t) -> !test(t);
    }

    default Predicate<T> or(Predicate<? super T> other) {
        Objects.requireNonNull(other);
        return (t) -> test(t) || other.test(t);
    }

}

Predicate p1 = e -> e.getMoney > 114;
Predicate p1 = e -> e.getMoney < 514;


water.stream()  
.filter(p1) 
.filter(p2) 
.collect(Collectors.toList()) 

在日常开发中我还会把他更加简化,简化为直接把Predicate传入filter中即可

water.stream()  
.filter(e -> e.getMoney > 114) 
.filter(e.getMoney < 514) 
.collect(Collectors.toList()) 

Predicate 的 and 与 or

在上面的Predicate源码中,我们发现他有and 和 or方法,用过实体类jap的小伙伴来说应该很熟悉这种写法了。他就是用来进一步组合滤网条件。

filter就可以写成这样 .filter(p1) .and(p2) 又或者是 .filter(p1) .or(p2)

Stream 的各个方法

sorted

.sorted 方法默认是进行升序排列,如果加上 .sorted(Comparator.reverseOrder()) 为降序输出

max min count

max 取最大值,需要传入compareTo比较方法 min 取最小值,需要传入compareTo比较方法 count 直接获取长度

map

对每个对象元素进行你需要的特定操作。但是这个map是对所有的对象进行操作 .map(e->e.getmoney + 114)

reduce

对每个元素进行你需要的特定操作,但是会累积成一个值

collect

把过滤或者其他操作的元素,进行一个聚合,传入数组,把流处理后的数据放入新的数组。