【jdk8新特性】Stream流
00.前言
如果有任何问题请指出,感谢。
01.作用
对集合进行处理操作的方法
stream流的特性如下:
Stream流不是一种数据结构,不保存数据,它只是在原数据集上定义了一组操作。
这些操作是惰性的,即每当访问到流中的一个元素,才会在此元素上执行这一系列操作。
Stream不保存数据,故每个Stream流只能使用一次。
stream流的方法有很多中,大致分为延迟方法和终结方法。Stream流属于管道流,只能被消费(使用)一次
第一个stream流调用完毕方法,数据就会流转到下一个Stream上(如果没有下一个流则直接关闭)
而这时第一个stream流已经使用完毕,就会关闭了
所以第一个Stream流就不能再调用方法延迟方法 :返回值类型仍然是 Stream 接口自身类型的方法,因此支持链式调用。(除了终结方法外,其余方法均为延迟方法。)
终结方法 :返回值类型不再是 Stream 接口自身类型的方法,因此不再支持类似 StringBuilder 那样的链式调
用。终结方法包括 count 和 forEach 方法
02.传统处理集合的方法进行对比
传统方法
public static void main(String[] args) throws InterruptedException {
// 一个ArrayList集合中存储有以下数据:张无忌,周芷若,赵敏,张强,张三丰
// 需求:1.拿到所有姓张的 2.拿到名字长度为3个字的 3.打印这些数据
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰");
// 1.拿到所有姓张的
ArrayList<String> zhangList = new ArrayList<>(); // {"张无忌", "张强", "张三丰"}
for (String name : list) {
if (name.startsWith("张")) {
zhangList.add(name);
}
}
// 2.拿到名字长度为3个字的
ArrayList<String> threeList = new ArrayList<>(); // {"张无忌", "张三丰"}
for (String name : zhangList) {
if (name.length() == 3) {
threeList.add(name);
}
}
// 3.打印这些数据
for (String name : threeList) {
System.out.println(name);
}
}
结果
张无忌
张三丰
Stream流及其简化
public static void main(String[] args) throws InterruptedException {
// 一个ArrayList集合中存储有以下数据:张无忌,周芷若,赵敏,张强,张三丰
// 需求:1.拿到所有姓张的 2.拿到名字长度为3个字的 3.打印这些数据
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰");
// 1.拿到所有姓张的 2.拿到名字长度为3个字的 3.打印这些数据
list.stream()
.filter((s) -> {
return s.startsWith("张");
})
.filter((s) -> {
return s.length() == 3;
})
.forEach((s) -> {
System.out.println(s);
});
System.out.println("-----------");
list.stream()
.filter(s -> s.startsWith("张"))
.filter(s -> s.length() == 3)
.forEach(s -> System.out.println(s));
System.out.println("-----------");
list.stream()
.filter(s -> s.startsWith("张"))
.filter(s -> s.length() == 3)
.forEach(System.out::println);
System.out.println("-----------");
}
结果
张无忌
张三丰
张无忌
张三丰
张无忌
张三丰
可以看出相同情况下,Stream流对集合的处理更加的简单并且便于理解,Stream流通常与lambda表达式配合使用。
03.获取Stream流的几种方式
例子
public static void main(String[] args) {
// 方式1 : 根据Collection获取流
// Collection接口中有一个默认的方法: default Stream<E> stream()
List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream();
Set<String> set = new HashSet<>();
Stream<String> stream2 = set.stream();
Map<String, String> map = new HashMap<>();
Stream<String> stream3 = map.keySet().stream();
Stream<String> stream4 = map.values().stream();
Stream<Map.Entry<String, String>> stream5 = map.entrySet().stream();
// 方式2 : Stream中的静态方法of获取流
// static<T> Stream<T> of(T... values)
Stream<String> stream6 = Stream.of("aa", "bb", "cc");
String[] strs = {
"aa", "bb", "cc"};
Stream<String> stream7 = Stream.of(strs);
// 基本数据类型的数组行不行?不行的,会将整个数组看做一个元素进行操作.
int[] arr = {
11, 22, 33};
Stream<int[]> stream8 = Stream.of(arr);
// 装箱后的数据类型的数组行不行?可以,操作的元素就是数组里面的每个元素
Integer[] ar = {
11, 22, 33};
Stream<Integer> stream9