- 生成流
List<String> list = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
//为集合创建串行流。主线程,单线程
List<String> stream = list.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
//并行流。即多个线程同时运行
List<String> parallelStream = list.parallelStream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
- 简单 for循环
list.stream().forEach(e ->e.setValue(value));
list.forEach(e ->e.setValue(value));
list.forEach(e ->{ ...... });
- 过滤: filter(T -> boolean)
list.stream() .filter(过滤条件) .collect(Collectors.toList())
List<X> list = aList.stream()
.filter(a -> "value".equals(a.getValue()))
.collect(Collectors.toList());
- 分组
Map<Object,List<Object>> consInfoGroupMap = list.stream()
.collect(Collectors.groupingBy(Object::getValue));
//如:名字相同的 List<User>
Map<String, List<User>> consInfoGroupMap = userList.stream()
.collect(Collectors.groupingBy(User::getName));
//如:名字相同的 Long多少人
Map<String, Long> consInfoGroupMap = userList.stream()
.collect(Collectors.groupingBy(User::getName,Collectors.counting()));
- 多级分组
groupingBy 可以接受一个第二参数实现多级分组:
Map<Integer, Map<T, List<User>>> map = list.stream()
.collect(groupingBy(User::getAge, groupingBy(...)));
//其中返回的 Map 键为 Integer 类型,
//值为 Map<T, List<Person>> 类型,即参数中 groupBy(...) 返回的类型
- 根据字段排序 sorted() / sorted((T, T) -> int)
List<Object> items = list().stream()
.sorted(Comparator.comparing(Object::getValue))
.collect(Collectors.toList());
//如:根据年龄排序
List<User> items = list().stream()
.sorted(Comparator.comparing(User::getAge))
.collect(Collectors.toList());
//如:过滤加排序 全部男性根据age排序
List<User> userList = list.stream()
.filter(temp -> temp.getSix().equals("男人"))
.sorted(Comparator.comparing(temp -> temp.getAge()))
.collect(Collectors.toList());
- 返回前 n 个元素 limit(long n)
//如:返回前两个user 对象
List<User> userList = list.stream().limit(2).collect(toList());
- 去除前 n 个元素 skip(long n)
如:去除钱两个User对象后,返回其余 user 对象
List<User> userList = list.stream().skip(2).collect(toList());
-
tips :
skip(m) 用在limt(n)前面时,先去除前面m个元素再返回剩余元素的前n个元素
limit(n) 用在skip(m)前面时,先返回前n个元素再在剩余的n个元素中去除m个元素 -
map(T -> R) 获取集合 中对象的value属性的值
将流中的每一个元素 T 映射为 R(类似类型转换)
List<String> values = list.stream()
.map(Object::getValue).collect(Collectors.toList());
List<String> values = list.stream()
.map(x -> x.getValue()).collect(Collectors.toList());
//如:
List<String> names = list.stream()
.map(User::getName).collect(Collectors.toList());
- flatMap(T -> Stream)
将流中的每一个元素 T 映射为一个流,再把每一个流连接成为一个流
List<String> list = new ArrayList<>();
list.add("aaa,bbb,ccc");
list.add("ddd,eee,fff");
list.add("ggg,hhh,iii");
list = list.stream()
.map(p -> p.split(","))
.flatMap(Arrays::stream)
.collect(toList());
我们的目的是把 List 中每个字符串元素以","分割开,变成一个新的 List。
首先 map 方法分割每个字符串元素,但此时流的类型为 Stream<String[ ]>,因为 split 方法返回的是 String[ ] 类型;所以我们需要使用 flatMap 方法,先使用Arrays::stream将每个 String[ ] 元素变成一个 Stream 流,然后 flatMap 会将每一个流连接成为一个流,最终返回我们需要的 Stream
- anyMatch(T -> boolean)
流中是否有一个元素匹配给定的 T -> boolean 条件
是否存在一个 user 对象的 age 等于 20:
boolean b = list.stream().anyMatch(user -> user .getAge() == 20);
-
allMatch(T -> boolean)
流中是否所有元素都匹配给定的 T -> boolean 条件 -
noneMatch(T -> boolean)
流中是否没有元素匹配给定的 T -> boolean 条件 -
findAny() 和 findFirst()
findAny():找到其中一个元素
使用 stream() 时找到的是第一个元素;
parallelStream() 并行时找到的是其中一个元素
findFirst():找到第一个元素
值得注意的是,这两个方法返回的是一个 Optional<T> 对象,它是一个容器类,能代表一个值存在或不存在
- reduce((T, T) -> T) 和 reduce(T, (T, T) -> T)
用于组合流中的元素,如求和,求积,求最大值等
计算年龄总和:
int sum = list.stream().map(User::getAge).reduce(0, (a, b) -> a + b);
//相同写法:
int sum = list.stream().map(User::getAge).reduce(0, Integer::sum);
//其中,reduce 第一个参数 0 代表起始值为 0,
//lambda (a, b) -> a + b 即将两值相加产生一个新值
- 计算乘积
//同样地,计算年龄总乘积
int sum = list.stream().map(User::getAge).reduce(1, (a, b) -> a * b);
//或者
Optional<Integer> sum = list.stream()
.map(User::getAge).reduce(Integer::sum);
//即不接受任何起始值,但因为没有初始值
//需要考虑结果可能不存在的情况,因此返回的是 Optional 类型
- count()
返回流中元素个数,结果为 long 类型 - collect()
收集方法,我们很常用的是 collect(toList()),当然还有 collect(toSet()) 等,参数是一个收集器接口 - joining 连接字符串
也是一个比较常用的方法,对流里面的字符串元素进行连接,其底层实现用的是专门用于字符串连接的 StringBuilder
//将User 的getName值 进行连接
String s = list.stream().map(User::getName).collect(joining());
//将User 的getName值 用","进行连接
String s = list.stream().map(User::getName).collect(joining(","));
//结果:name1,name2,name3
joining 还有一个重载方法:
String s = list.stream()
.map(User::getName).collect(joining(" and ", "Today ", " play games."));
//结果:Today name1 and name2 and name3 play games.
//即 Today 放开头,play games. 放结尾,and 在中间连接各个字符串