stream api 流式编程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了stream api 流式编程相关的知识,希望对你有一定的参考价值。

参考技术A map(Function f) 接收流中元素,并且将其映射成为新元素,例如从student对象中取name属性

flatMap(Function f) 将所有流中的元素并到一起连接成一个流

peek(Consumer c) 获取流中元素,操作流中元素,与foreach不同的是不会截断流,可继续操作流

distinct() 通过流所生成元素的equals和hashCode去重

limit(long val) 截断流,取流中前val个元素

sorted(Comparator) 产生一个新流,按照比较器规则排序

java的stream流式编程总结


stream流式编程

1. stream流的3个特性

(1) stream流不存储数据

(2) stream不改变数据源

stream可以看作一根管道,用于数据的转换,所以不会存储数据,也不会影响原来的数据

除了过滤、排序、采集外,还有分组等等功能,这也就是stream流式编程提供的功能
在这里插入图片描述

(3) stream不可重复使用

因为stream是一根管道,不可重复使用就是stream用完一次之后,数据就输出了
在这里插入图片描述
示例

 Stream stream1 = Stream.of(1,2,3);
        
 //创建stream2过滤stream1
 Stream stream2 =  stream1.filter(s->s.equals(1));

 //下句代码会出错,因为stream1流用过一次,消失了
 Stream stream3 =  stream1.filter(s->s.equals(1));

2. 生成流的方式

(1) Array.stream()

Array的静态方法
在这里插入图片描述
例如Arrays.stream(new int[]{1,2,3}); //使用Array的静态方法创建流

(2) Stream.of()

Stream的静态方法,可以传入任何类型
在这里插入图片描述

例如Stream.of(1,"小明",2,new ArrayList<>()); //使用Stream的静态方法创建流

(3) 对象.stream()

stream()方法是Collection接口里的默认方法 ,所以Collection所有的子类和子接口都可以使用.stream()

例如

Collection collection  = new ArrayList();

collection.stream(); // 使用Collection类里的成员方法stream()方式创建流

3. 中间节点(懒节点)与终值节点

(1) 中间节点/懒节点的使用示例

懒节点不会自动执行,所以下例代码不会打印hello

   public static void main(String[] args) {
        List list = new ArrayList();

        Stream.of(list).filter(a->{
            System.out.println("hello");
            return true;
        }); //没有打印结果
}

(2) 懒节点+终值节点

这时在最后加了.toArray()方法,相当于加上了终值节点,那么此时终值节点+前面的节点都会执行

 public static void main(String[] args) {
        List list = new ArrayList();

        Stream.of(list).filter(a->{
            System.out.println("hello");
            return true;
        }).toArray(); //打印输出hello
}

(3) 区分中间节点与终值节点的方法

进入Stream流的源码,按快捷键ctrl+f12

只要方法返回的是Stream,基本都是中间节点,其余就是终值节点

在这里插入图片描述

4. stream流的使用示例及特性

@Data
@AllArgsConstructor
@NoArgsConstructor
public class AppleStore {
    int id; //编号
    String color; //颜色
    double weight; //重量
    String origin; //产地
}

(1) 节点的责任链模式

① 执行每个节点方法:peek()

节点会挨个执行,也称作责任链模式

public class StreamTest {
    private static List<AppleStore> appleStores = new ArrayList();

    static {
        appleStores.add(new AppleStore(1,"red",1.2,"重庆"));
        appleStores.add(new AppleStore(2,"red",1.5,"四川"));
        appleStores.add(new AppleStore(3,"yellow",2.6,"重庆"));
        appleStores.add(new AppleStore(4,"yellow",2.9,"四川"));
        appleStores.add(new AppleStore(5,"red",3.2,"杭州"));
    }
    public static void main(String[] args) {

        //peek()是执行每个节点的方法
        //peek里的方法会挨个执行,也就是节点会挨个执行,也称作责任链模式
        appleStores.stream().peek(appleStore -> System.out.println(appleStore.getColor())) //打印苹果的颜色
                .peek(appleStore -> System.out.println(appleStore.getWeight())) //打印苹果的重量
                .peek(appleStore -> appleStore.getOrigin()) //打印苹果的产地
                .toArray();
    }
}

在这里插入图片描述

② 执行最后一个节点:foreach()

foreach功能和peek相同,不同是foreach是终值节点,也就是不能再往下继续执行

appleStores.stream().peek(apple -> System.out.println(apple.getId())) //打印苹果编号
                .peek(apple -> System.out.println(apple.getColor())) //打印苹果颜色
                .forEach(sout-> System.out.println("节点一次遍历执行完毕"));

在这里插入图片描述

(2) 上一个节点会影响下一个节点

影响方式:过滤、转换/映射、去重

① 过滤:filter()

 appleStores.stream().filter(appleStore -> appleStore.getColor().equals("red")) //过滤出红色的苹果
                .peek(appleStore -> System.out.println(appleStore)) //到第二个节点只有红色苹果的数据了
                .toArray();

在这里插入图片描述

② 转换/映射:map()

   //此时数据全部变成了String字符串 因为map中的方法是getColor(),映射成为的是String
        appleStores.stream().map(appleStore -> appleStore.getColor()) //获取苹果的颜色
                .peek(color -> System.out.println(color))
                .toArray();

③ 去重:distinct()

appleStores.stream().map(appleStore -> appleStore.getColor()) //获取苹果的颜色
                .distinct() //去重
                .peek(color -> System.out.println(color))
                .toArray();

在这里插入图片描述

5. Stream的采集功能

Stream采集功能分为List、map、group by、数组、求最大值、求任意值等,这里就不一一列举了

用一个综合例子来说明其余功能

List<Integer> collect = appleStores.stream() // 获取appleStores的流
                .map(appleStore -> appleStore.getId()) // 转换功能:获取id,从List<AppleStore>转换成了List<int>
                .sorted() // 从小到大排序 (本质是调用compareTo()方法,所以类要实现CompareAble接口)
                .limit(3) // 取前三个元素
                .collect(Collectors.toList()); //将stream流转回List集合

stream流的常用方法
在这里插入图片描述

以上是关于stream api 流式编程的主要内容,如果未能解决你的问题,请参考以下文章

java的stream流式编程总结

Stream流式编程详解

java8-流式编程Stream

Stream流式编程实战

Java8 流式 API(`java.util.stream`)

Go 通过 Map/Filter/ForEach 等流式 API 高效处理数据