您可以使用自定义收藏夹:
Multimap map = list.stream().collect(
ImmutableMultimap::builder,(builder,value) -> value.getTags().forEach(tag -> builder.put(tag,value)),(builder1,builder2) -> builder1.putAll(builder2.build())
).build();
这不会引起额外的副作用(参见here),是并发的,比较惯用的.
您还可以将这些特别的羔羊提取成一个完整的收藏家,如下所示:
public static Collector> toMultimapByKey(Function super T,? extends Iterable extends K>> keysMapper) {
return new MultimapCollector<>(keysMapper);
}
private static class MultimapCollector implements Collector,T>> {
private final Function super T,? extends Iterable extends K>> keysMapper;
private MultimapCollector(Function super T,? extends Iterable extends K>> keysMapper) {
this.keysMapper = keysMapper;
}
@Override
public Supplier> supplier() {
return ImmutableMultimap::builder;
}
@Override
public BiConsumer accumulator() {
return (builder,value) -> keysMapper.apply(value).forEach(k -> builder.put(k,value));
}
@Override
public BinaryOperator> combiner() {
return (b1,b2) -> b1.putAll(b2.build());
}
@Override
public Function> finisher() {
return ImmutableMultimap.Builder::build;
}
@Override
public Set characteristics() {
return Collections.emptySet();
}
}
那么收藏将如下所示:
Multimap map = list.stream().collect(toMultimapByKey(Foo::getTags));
如果您的订单不重要,您还可以从特性()方法返回EnumSet.of(Characteristics.UNORDERED).这可以使内部收集机械更有效地起作用,特别是在并行还原的情况下.