文章目录
- Stream介绍(摘抄)
- 流的创建
- 流的转换
- 中间操作
- 常用
- 匹配
- 查找元素
- 计数和极值
- 终止操作
- Collectors 具体方法
- 注意事项
Stream介绍(摘抄)
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。JDK8新特性。
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
这种风格将要处理的元素集合看作一种流,流在管道中传输,并且可以在管道的节点上进行处理,比如筛选,排序,聚合等。
Stream有以下特性及优点:
- 无存储。Stream不是一种数据结构,它只是某种数据源的一个视图,数据源可以是一个数组,Java容器或I/O channel等。
- 为函数式编程而生。对Stream的任何修改都不会修改背后的数据源,比如对Stream执行过滤操作并不会删除被过滤的元素,而是会产生一个不包含被过滤元素的新Stream。
- 惰式执行。Stream上的操作并不会立即执行,只有等到用户真正需要结果的时候才会执行。
- 可消费性。Stream只能被“消费”一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成。
流的创建
- 集合
Collection.stream()
- 静态方法
Stream.of
- 数组
Arrays.stream
// 流的创建
// 1.集合
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> listStream = list.stream();
Stream<String> listParallelStream = list.parallelStream();
// 2.数组
Integer[] numberArray = {1,2,3,4};
Stream<Integer> arrayStream1 = Arrays.stream(numberArray);
Stream<Integer> arrayStream2 = Stream.of(numberArray);
Stream<Integer> arrayParallelStream = Stream.of(numberArray).parallel();
// 3.多个元素
Stream<Integer> integerStream = Stream.of(1, 2, 3, 4);
// 4.单一元素
Student student = new Student(1, "gxzhang", BigDecimal.ZERO);
Stream<Student> studentStream = Stream.of(student);
stream为串行流,parallelStream并行流可利用机器多核并发,效率更高,默认并发数为机器cpu核数。
流的转换
// 流的转换
// 普通流转并行流
Stream<String> parallel = listStream.parallel();
// Stream<Integer> -> IntStream
IntStream intStream2 = integerStream.mapToInt(value -> value.intValue());
// IntStream -> Stream<Integer>
Stream<Integer> integerStream3 = intstream.boxed();
中间操作
常用
filter(Predicate)
筛选流中某些元素map(Function f)
接收流中元素,并且将其映射成为新元素,例如从student对象中取name属性flatMap(Function f)
将所有流中的元素并到一起连接成一个流peek(Consumer c)
获取流中元素,操作流中元素,与foreach不同的是不会截断流,可继续操作流distinct()
通过流所生成元素的equals和hashCode去重limit(long val)
截断流,取流中前val个元素sorted(Comparator)
产生一个新流,按照比较器规则排序sorted()
产生一个新流,按照自然顺序排序
匹配
-
booelan allMatch(Predicate)
都符合 -
boolean anyMatch(Predicate)
任一元素符合 -
boolean noneMatch(Predicate)
都不符合
查找元素
-
findFirst
——返回第一个元素 -
findAny
——返回当前流中的任意元素
计数和极值
-
count
——返回流中元素的总个数 -
max
——返回流中最大值 -
min
——返回流中最小值
// 中间操作
// filter:过滤值为为 "a" 的元素 filter的值为false时会被过滤
list = listStream.filter(value -> "a".equals(value)).collect(Collectors.toList());
// map 将值依次进行映射处理;将数据每个字符串后加‘-’符号
list = listStream.map(value->value+"-").collect(Collectors.toList());
// anyMatch 任意符合 返回布尔类型; 判断元素是否存在”a“
boolean b = listStream.anyMatch(value -> "a".equals(value));
// 流的扁平化
// 将 数组["hello", "world"] 转变成 ["h","e","l","o","w","r","d"] 并将元素去重
String[] strings = {"hello", "world"};
// 这样返回的结果为 String[]数组类型的集合,而我们需要将List<String>类型的
// 原因是因为map中将一个元素生成了多个元素返回了一个String[]数组类型
List<String[]> collect = Stream.of(strings)
.map(word -> word.split(""))
.distinct()
.collect(Collectors.toList());
// 采用flatmap进行流扁平化
List<String> collect1 = Stream.of(strings).
flatMap(word -> Arrays.stream(word.split("")))
.distinct()
.collect(Collectors.toList());
终止操作
-
foreach(Consumer c)
遍历操作 -
collect(Collector)
将流转化为其他形式 -
max(Comparator)
返回流中最大值 -
min(Comparator)
返回流中最小值 -
count
返回流中元素综述
Collectors 具体方法
-
toList List<T>
把流中元素收集到List -
toSet Set<T>
把流中元素收集到Set -
toCollection Coolection<T>
把流中元素收集到Collection中 -
groupingBy Map<K,List<T>>
根据K属性对流进行分组 -
partitioningBy Map<boolean, List<T>>
根据boolean值进行分组
// 终止操作
// 流的遍历
listStream.forEach(value-> System.out.println(value));
listStream.forEach(value-> System.out.println(value));
listStream.forEach(System.out::println);
listStream.forEach(value -> {
// 多条语句用花括号
System.out.println("二哈");
System.out.println(value);
});
// 归约,计算数和;0 为identity初始值,a将被赋值为上次计算结果(初始为identity值),b流中元素
int sum = intstream.reduce(0, (a, b) -> a + b);
// 收集 将处理后的结果返回对应的类型数据
List<Integer> list1 = integerStream.collect(Collectors.toList());
// 其他
// 最大值
int max = intstream.max().getAsInt();
// 最小值
int min = intstream.min().getAsInt();
// 和
intstream.sum();
注意事项
流一旦执行了终止操作就不再可用,必须需要重新获取流。
流式编程为语法糖,最终编译后执行效果和不加糖是一致的,只是语法糖帮我们提升了编程效率和常用操作的最优实现。
以上案例仅为方便说明用法,不可直接执行。
流的常用api以上已说明,案例只简单列举了常用的api用法,可根据简单介绍很容易上手。
欲练此功,必先多敲✊