Stream 流编程

228 阅读2分钟

这是我参与8月更文挑战的第26天,活动详情查看:8月更文挑战

Stream是什么

Stream是一个高级的迭代器,不会存数据,Stream关注的是怎么把数据高效的处理,类似于生活中的流水线。

外部迭代内部迭代

public static void main(String[] args) {
    int[] nums = {1,2,3};
    //外部迭代
    int sum =0;
    for (int i:nums
         ) {
        sum+=i;
    }

    System.out.println("结果为"+sum);
//内部迭代

    int sum2 = IntStream.of(nums).sum();
    System.out.println("结果为:" +sum2);
}

外部迭代的缺点:1.需要自己写过程 2.上述外部迭代的代码是串行的效率低

中间操作、终止操作、惰性求值

将原来的数X2

int sum2 = IntStream.of(nums).map(i->i*2).sum();
System.out.println("结果为:" +sum2);

这里map 就是中间操作, 也就是返回流的操作 sum就是 终止操作返回一个结果

import java.util.stream.IntStream;

public class StreamDemo {
    public static void main(String[] args) {
        int[] nums = {1,2,3};
        //外部迭代
        int sum =0;
        for (int i:nums
             ) {
            sum+=i;
        }
        System.out.println("结果为"+sum);
        int sum2 = IntStream.of(nums).map(StreamDemo::doubleNum).sum();
        System.out.println("结果为:" +sum2);
        System.out.println("惰性操作就是终止没有调用的情况下,中间操作不会执行");
        IntStream.of(nums).map(StreamDemo::doubleNum);
    }
    public static int doubleNum(int i){
        System.out.println("执行了X2 ");
        return i*2;
    }
}

image.png

int sum2 = IntStream.of(nums).map(StreamDemo::doubleNum).sum();这里调用了 sum 所以执行了 3次 X2

但是

IntStream.of(nums).map(StreamDemo::doubleNum);

没有调用终止操作,所以不被调用

流操作

image.png

直接上代码

public class StreamDemo2 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        //从集合中创建
        list.stream();
        list.parallelStream();
        //从数组中创建
        Arrays.stream(new int[]{2,3,5});

        //创建数字流
        IntStream.of(1,2,3);
        IntStream.rangeClosed(1,10);//相当于边界

        //使用random 创建一个无线流
        new Random().ints().limit(10);

        //自己手动创建
        Random random = new Random();
        Stream.generate(()-> random.nextInt()).limit(20);


    }
}

流的中间操作

中间操作有两种 :无状态操作和有状态操作

无状态操作: 操作和其他的值无关 有状态操作:状态要等待流结束才给出最终结果

image.png

public class StreamDemo3 {
    public static void main(String[] args) {
        String str = "my name is 007";

        //把每个单词长度调用出来
        Stream.of(str.split(" ")).filter(s->s.length()>2).map(s->s.length()).forEach(System.out::println);

        //flatMap A-> B 属性 (A是个集合) 最终得到,所有A元素里面所有属于B元素的集合
        //IntStream /longStream 并不是Stream的子类 ,所以要进行装箱
        Stream.of(str.split(" ")).flatMap(s->s.chars().boxed()).forEach(
                i->System.out.println((char) i.intValue())
        );
        
        //peek 一般用于debug.是个中间操作,和forEach是终止操作
        Stream.of(str.split(" ")).peek(System.out::println).forEach(System.out::println);

        //limit 使用 ,主要是使用无线流 如果不做限制会一直进行下去
        new Random().ints().filter(i->i>100 && i<1000).limit(10)
                .forEach(System.out::println);
    }
}