对stream的操作有
1.创建stream流
-
stream() − 为集合创建串行流。
-
parallelStream() − 为集合创建并行流。
String[] dd = { "a", "b", "c" };
Arrays.stream(dd).forEach(System.out::print);// abc
System.out.println();
Stream.of(dd).forEach(System.out::print);// abc
System.out.println();
Arrays.asList(dd).stream().forEach(System.out::print);// abc
System.out.println();
Stream.iterate(0, x -> x + 1).limit(10).forEach(System.out::print);// 0123456789
System.out.println();
Stream.generate(() -> "x").limit(10).forEach(System.out::print);// xxxxxxxxxx
1.1List最常用的方式:
List<String> list = new ArrayList<>(); Stream<String> stream = list.stream();//返回一个新的元素流,对源对象不会造成影响
2.2Map最长的方式:
在Java中Map不能直接使用Stream,因为Map是一种键值对映射的数据结构,而stream流是用于处理集合元素的API,一般是对集合的List和set进行处理和操作,由于Map是键值对关系,它不能直接去循环,所以在循环Map必须要转换为entrySet()、keySet()和values()方法来获取Map中的键/值/键值对集合,通过转为KeySet()和EntrySet()和values()获取Stream流来对Map进行处理,常见的做法是:
- 将Map.Entry对象转换为Stream:
map.entrySet().stream()
。 - 将Map中所有键转换为Stream:
map.keySet().stream()
。 - 将Map中所有值转换为Stream:
map.values().stream()
。
2.中间操作
主要包括以下几种:
-
filter(Predicate<T> predicate):过滤出符合条件的元素并返回一个新的Stream对象。
-
map(Function<T, R> mapper):将一个类型的流转换为另一个类型的流并返回一个新的Stream对象。
-
flatMap(Function<T, Stream<R>> mapper):与map类似,但是可以将元素映射为流(而不是单个元素),最后将所有流合并成一个流,并返回一个新的Stream对象。(用自己的话说就是对象中还有对象就只用这个去循环)
-
distinct():去重并返回一个新的Stream对象。
-
sorted():排序并返回一个新的Stream对象。如果是对象,则要求其实现Comparable接口,或需要传入Comparator。
-
peek(Consumer<T> action):对每个元素应用action函数,并返回一个新的Stream对象,适合于调试或日志输出等用途。(用自己的话说就是对流中的每个元素进行一定的操作比如+1,加上同样的名字)
-
limit(long maxSize) 和 skip(long n):limit方法返回一个Stream对象,它限制了结果集的最大长度,并跳过复显式字段指定数量的数据。skip方法做的正好相反,是跳过前N个元素,截取从第N+1个元素至末尾的全部元素。
-
takeWhile(Predicate<T> predicate) 和 dropWhile(Predicate<T> predicate):takeWhile方法获取从开头开始匹配predicate函数的元素,直到遇到不匹配为止;dropWhile方法则从开头忽略掉一部分符合valeus的数据(直到遇到不符合的片段),然后返回一个新的Stream对象。(用自己的话说就是takeWhile就是根据自己的条件进行匹配获取想要的数据,而dropWhile就是相反)
takeWhile()
和 dropWhile()
方法与 Stream API 中的 filter()的区别:
takeWhile()
和 dropWhile()
方法与 Stream API 中的 filter()
方法都可以进行条件筛选和过滤,但它们之间存在以下几个区别:
-
filter()
方法通过判断流中元素是否满足指定谓词来决定是否保留元素,而takeWhile()
和dropWhile()
方法则根据条件从开头开始获取或丢弃元素直到遇到不符合该条件的第一个元素。 -
filter()
方法是终止操作,并完整输出流中所有符合条件的元素。而takeWhile()
和dropWhile()
方法都是中间操作,能够在流中挑选出满足条件的部分元素,在其后接其他中间/终止操作完成任务。 -
takeWhile()
和dropWhile()
可以更灵活地截取、扩充原始流:当一些数据需要按照一定的规则处理时,takeWhile()
和dropWhile()
方法可以将复杂的判断交由用户自己实现。而filter()
则关注于对单一维度的数据集合进行筛选。
3.终结操作
常见的终止操作包括:
forEach()
:对流中的每个元素执行操作(可以再方法体中写逻辑)。toArray()
:将流中的元素转为一个数组。reduce()
:按照指定的运算逻辑返回计算结果(可以再方法体中写逻辑)。collect()
:将流中的元素收集到一个集合中(可以再方法体中写逻辑)。min()
和max()
:返回流中最小和最大元素(可以再方法体中写逻辑)。count()
:返回流中元素的数量。anyMatch()
、allMatch()
和noneMatch()
:判断流中是否有任何/全部/无元素符合指定的条件(可以再方法体中写逻辑)。findAny()
和findFirst()
:查找并返回流中的任意一个或第一个元素(可以再方法体中写逻辑)。iterator()
:返回这个流的迭代器。
需要注意的是,终止操作都会导致流已关闭,不可进行更多的中间操作。因此必须谨慎选择终止操作,保证流被正确处理。同时,Stream 还支持类似于 sorted()
、distinct()
等比较相关的方法,虽然它们也可以作为中间操作调用,但实际上也仅有当前有限的数据段参与排序,直到终结操作调用而自然溢出为止。
常见的List转Map
List<User> userList = new ArrayList<>();
userList.add(new User("Alice", 20));
userList.add(new User("Bob", 25));
userList.add(new User("Cathy", 30));
Map<String, Integer> nameToAgeMap = userList.stream()
.collect(Collectors.toMap(User::getName, User::getAge));