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。、

partitioningBygroupingBy 的参数是一个 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 的方法使用

filtering

reducing