Stream
-
不是 IO 流
-
集合数据转化为数据流形式 (从数据源到目标数据中间的抽象形态)
-
可以对这种抽象数据进行一些列 切片、筛选、排序 等的操作
-
解决了大部分集合操作必须依赖于 外部迭代 的方式,让集合操作非常的简便
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ItUhQbaK-1624677798264)(C:\Users\Xingcl\AppData\Roaming\Typora\typora-user-images\image-20210625204339934.png)]
1 . 流的创建
-
Collection.stream() 或者 Collection.paralleStream()
-
@Test public void lambdaTest11() { ArrayList<MyPojo> pojos = VirtualDb.getDate(); Stream<MyPojo> stream = pojos.stream(); Stream<MyPojo> myPojoStream = pojos.parallelStream(); //返回 Stream<T> }
-
-
Arrays.Stream()
- 将 基本类型数组 或者 对象数组 转化为流
-
Stream.of()
- 对象 或者 .…args 转化为流
-
无限流
-
Stream.iterator(T seed,UnaryOperator oprator)
-
Stream.iterate(0,(x)->x+10) .limit(10) .forEach(System.out::println);
- 使用 seed 作为起始值 执行单元操作 没有结束点
-
-
Stream.generate(Supplier supplier)
-
Stream.generate(Math::random) .limit(10) .forEach(System.out::println);
-
-
2.中间操作
-
筛选与切片
-
filter(Predicate predicate)
-
过滤流中不符合条件的单位数据
-
@Test public void lambdaTest13() { ArrayList<MyPojo> myPojos = VirtualDb.getDate(); myPojos.stream() .filter((MyPojo v) -> { return v.age > 30; }) .forEach(System.out::println); //需要指定一下类型 好像推断不出来 // filter 中需要传入一个断言型 函数式接口 //会对集合中的每个元素 附加Predicate 中的实现方法 }
-
-
limit(int n)
-
截断流 当流被阶段后 后面的中间操作全都终止
-
@Test public void lambdaTest14() { Stream.iterate(920,(x)->x+20) .limit(10) .forEach(System.out::println); }
-
-
skip(int n)
-
跳过流的前 n个单位的元素
-
@Test public void lambdaTest15() { ArrayList<MyPojo> myPojos = VirtualDb.getDate(); myPojos.stream() .skip(2) .forEach(System.out::println); }
-
-
distinct()
-
通过 hashCode 和 equals 方法去除流中的重复元素(所以效果的实现依赖于类方法是否重写)
-
@Test public void lambdaTest16() { ArrayList<MyPojo> myPojos = VirtualDb.getDate(); myPojos.stream() .skip(2) .distinct() .forEach(System.out::println); //通过hashCode 和equals 方法去除重复元素 //好像没有参数 }
-
-
-
映射
-
map(Function function)
-
对流中的每个元素执行 函数式接口中的方法 返回一个新流
-
@Test public void lambdaTest17() { ArrayList<MyPojo> myPojos = VirtualDb.getDate(); myPojos.stream() .map(x -> x.age +10) .forEach(System.out::println); }
-
-
flatMap(Function function)
-
流的元素应用一对多转换,然后将结果元素展平为新的流
-
@Test public void lambdaTest18() { List<String> list=Arrays.asList("xzz","zxcx","zxcs","dsadfs"); list.stream() .map(srt->srt.split("")) .flatMap(Arrays::stream) .forEach(System.out::print); //map 对list中的每个数组做了拆分 返回 Stream<Stream> //flutter [Stream<String[]{x,z,z}>,Stream<String[z,x,c,x]>,Stream<String[]....> // 执行了 函数式接口中的 Arrays.stream // 然后 每个元素转化为一个新流 最后合并为一个新流 }
-
-
-
排序、查找与匹配
-
sorted(Comparator comparator)
-
对流中元素通过比较器排序
-
sorted() 自然排序 好像不能用于对象(或者说我没有重写compara?)
-
@Test public void lambdaTest19() { ArrayList<MyPojo> myPojos = VirtualDb.getDate(); myPojos.stream() .sorted(((o1, o2) -> { if (o1.getAge() < o2.getAge()) { return o1.getName().compareTo(o2.getName()); } else { return o1.getAge().compareTo(o2.getAge()); } })) .forEach(System.out::println); }
-
-
allMatch,anyMatch,findFirst…
- Optional
- 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
- 在对流的一些操作时 会使用IOptional 作为容器接受流的结果 省去了空指针检查
-
-
规约、收集
-
reduce(T identity, BinaryOperator accumulator)
-
将流中的元素 反复结合,得到一个值
-
@Test public void lambdaTest20() { Stream<Double> generate = Stream.generate(() -> { return Math.random() * 100; }) //生成一个流 .limit(100); Double reduce = generate.reduce(1.0, (x, y) -> x + y); //((1.0+generate[0])+generate[2])+generate[3]...... System.out.println(reduce); }
-
map-reduce
-
通过map 展开 reduce 求和
-
@Test public void lambdaTest21() { ArrayList<MyPojo> myPojos=VirtualDb.getDate(); Integer reduce = myPojos.stream() .map(MyPojo::getAge) .reduce(0, Integer::sum); System.out.println(reduce); }
-
-
-
collection(collector collector)
-
将数据 从流形态 转化为其他形式(直白的说转存为其他容器) 接受一个收集器 对流
-
jdk 为我们提供了一个收集器工具类 Colletors 可以快捷的创建常用的收集器
```java @Test public void lambdaTest22() { ArrayList<MyPojo> myPojos=VirtualDb.getDate(); List<String> collect = myPojos.stream() .map(MyPojo::getName) .collect(Collectors.toList()); collect.forEach(System.out::println); } ```
-
averaging+Type
-
@Test public void lambdaTest23() { ArrayList<MyPojo> myPojos=VirtualDb.getDate(); Double collect = myPojos.stream() .collect(Collectors.averagingInt(MyPojo::getAge)); System.out.println(collect); }
-
-
groupingBy(Function<? super T, ? extends K> classifier)
-
分组
-
@Test public void lambdaTest24() { ArrayList<MyPojo> myPojos=VirtualDb.getDate(); Map<String, List<MyPojo>> collect = myPojos.stream() .collect(Collectors.groupingBy(MyPojo::getLevel)); collect.forEach((String key,List<MyPojo> myPojos_)->{ System.out.println(key+":"+myPojos_.toString()); }); }
-
-
partitioningBy(Predicate<…> predicate)
-
按条件分区 (true 一组 ,false 一组)
-
@Test public void lambdaTest25() { ArrayList<MyPojo> myPojos=VirtualDb.getDate(); Map<Boolean, List<MyPojo>> collect = myPojos.stream() .collect(Collectors.partitioningBy(po -> { return po.getAge() > 20; })); collect.forEach((b,ps)->{ System.out.println(b+":"+ps.toString()); }); }
-
-
注意
- 理解流的概念
- 注意函数式接口的使用和理解
-