有 iterator
类,但也可以用 forEach
,还可以用 toArray
,但是这个方法返回 Object[]
,想要避免可以给指定 constructor
但初次之外,重点的是 Collectors
,可以实现更加灵活的从 Stream
获取 element 的方法
stream.collect(Collectors.toList());
stream.collect(Collectors.joining());
summarizing (Int|Long|Double)
to Maps
这会是一个重要的 topics,因为很多时候我们的 elements 是一个复杂的 class,而提取出来一个信息总是不够的
stream.collect(Collectors.toMap(
Type::getKey,
e -> Collectors.singleton(e),
(exists, new) -> {
var union = new HashSet<Type>(exists);
union.addAll(new);
return union; }));
第一二个参数是函数接口,代表 key 和 value。第三个参数代表起冲突的解决方案,还是函数接口。第四个提供 constructor reference,只能在第三个参数提供的基础上提供
通过解决冲突的方式生成 Map<T, Set<U>>
Grouping and Partitioning
生成这样的 Map<T, List<U>>
类型,参数还是需要 lambda。、
partitioningBy
是 groupingBy
的参数是一个 Predicate
的特例,此时会 Map<Boolean, List<U>>
Downstream Collectors
其实 group by 出来的也是一个流,被默认转 List
了而已,想要对新流操作,可以使用 Collectors
中的别的方法
Map<String, Set<Locale>> countryToLocaleSet = locales.collect( groupingBy(Locale::getCountry, toSet()));
为了看着方便,这里默认引入了静态变量。这里的操作是让默认生成的 List
变为 Set
collectingAndThen & mapping
前者是对 downstream 先决定结合方式,再对集合做操作。处理对象是集合
后者恰好相反,先对元素做操作,然后再去同一集合掉。处理对象是元素
类似的,会有 flatMapping
用来给那些返回 Stream
的方法使用