JAVA------Stream流

2024-01-08 11:31:58

Stream流

  • Collection提供了新的stream()方法
  • 流不存储值,通过管道的方式获取值
  • 本质是函数式的,对流的操作会生成一个结果,不过并不会修改底层的数据源,集合可以作为流的底层数据源
  • 延迟查找,很多流操作(过滤、映射、排序等)都可以延迟实现。
流由3部分构成:

1.源
2.零个或多个中间操作
3.终止操作

流操作的分类:

1.惰性求值
2.及早求值

stream.xxx().yyy().count()
.xxx().yyy():惰性求值、零个或多个中间操作
.count():及早求值、终止操作

public static void main(Strig[] args){
	Stream stream1 = Stream.of("你好","世界","啊");

	String[] myArrays = new String[]{"你好","世界","啊"};
	Stream stream2 = Stream.of(myArrays);
	Stream stream3 = Arrays.stream(myArrays);

	List<String> list = Arrays.asList(myArrays);
	Stream stream4 = list.stream();
}

Stream例子

public class StreamDemp {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(2,4,5,6);
        /*传统写法*/
        int sum = 0;
        for(Integer i : list){
            sum += 2 * i;
        }
        /*Stream写法*/
        System.out.println(list.stream().map(value -> value*2).reduce(0, Integer::sum));
        /*Lambda写法*/
        System.out.println(list.stream().map(value -> value*2).reduce(0,(a,b) ->a+b));
    }
}

打印数组

public class StreamDemo2 {
    public static void main(String[] args) {
        Stream<String> stream = Stream.of("das","add");
        //打印数组
        //String[] array = stream.toArray(value -> new String[value]);
        //方法一:方法引用的形式:String[] array = stream.toArray(String[]::new);
        //方法二:通过封装的形式:List<String> list = stream.collect(Collectors.toList());
        //方法三:因为调用的collect方法中需要有三个参数,其中第一个Supplier不需要接受参数,直接返回值。
        //       第二个参数:累加器是通过对我们传递的两个值,第一个值来add第二个值,第二个值在该方法中起到遍历的作用,遍历完添加的list1这个集合中,
        //       第三个参数,把第二个参数中遍历后的list1(相当于list4),都存放在list3中
        //List<String> list = stream.collect(()-> new ArrayList<String>(),(list1,item)->list1.add(item),(list3,list4)->list3.addAll(list4));
        //方法四:方法引用替换方法三
        //List<String> list = stream.collect(ArrayList::new, ArrayList::add,ArrayList::addAll);
        //方法五:以流的形式。
        //总结:方法二的原理就是方法三、四、五
        String toString = stream.collect(StringBuilder::new, StringBuilder::append, StringBuilder::append).toString();
        System.out.println(toString);
        Arrays.asList(toString).forEach(System.out::println);
    }
}

在这里插入图片描述

Stream<List<Integer>> stream = Stream.of(Arrays.asList(1),(Arrays.asList(2,3),(Arrays.asList(4,5,6));
stream.flatMap(theList -> theList.stream()).map(item -> item * item).foreach(System.out::println);

练习
找出该流中大于2的元素,然后将每个元素乘以2,然后忽略掉流中的前两个元素,然后再取流中的前两个元素,最后求出流中元素的总和。

public static void main(String[] args){
	Stream<Integer> stream = Stream.iterate(1, item -> item + 2).limit(6);
	System.out.println(stream.filter(item -> item > 2).mapToInt(item -> item * 2).skip(2).limit(2).sum());
}

疑问:为什么min和max源码里面参数的类型为OptionInt,而sum为int类型?
取决于该值能不能为null,因为sum方法纵使你前面无任何值,最后也会为0,而min和max当Stream里面没有值时,就会抛出以下异常。
在这里插入图片描述
如何解决想使用min但是怕抛出异常的方法?
解决方法

stream.filter(item -> item > 2).mapToInt(item -> item * 2).skip(2).limit(2).min().ifPresent(System.out::println);

如何同时获取最大值、最小值这些值?
可以通过SummaryStatics
代码演示

IntSummaryStatics summaryStatics = stream.filter(item -> item > 200).
								   mapInt(item -> item * 2).limit(2).summaryStatics();
System.out.println(summaryStatics.getMin());
System.out.println(summaryStatics.getCount());
System.out.println(summaryStatics.getMax());

stream只能使用一次
代码理解

System.out.println(stream);
System.out.println(stream.filter(item -> item > 2));
System.out.println(stream.distinct());//报错

解决方法:

Stream<Integer> stream2 = stream.filter(item -> item > 2);
Stream<Integer> stream3 = stream2.distinct();

在这里插入图片描述
在这里插入图片描述
分组和分区
在这里插入图片描述

Collector

suppplier用来创建一个结果容器
accumulator不断地将元素累加到结果容器中
combiner在多线程中用来合并结果
finisher用来将结果容器类型转换为另一个类型

比较器详解与类型推断特例

在这里插入图片描述
在这里插入图片描述
根本原因在于
在这里插入图片描述
源码中是要求为数据类型或者往上的类型,不能为向下的类型。

文章来源:https://blog.csdn.net/Thrive_LCX/article/details/135401686
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。