您可以为此使用定制收集器:
Multimap<String, Foo> map = list.stream().collect( ImmutableMultimap::builder, (builder, value) -> value.getTags().forEach(tag -> builder.put(tag, value)), (builder1, builder2) -> builder1.putAll(builder2.build())).build();
这不会引起额外的副作用(请参见此处),并且是并发的并且更加惯用。
您还可以将这些临时lambda提取到成熟的收集器中,如下所示:
public static <T, K> Collector<T, ?, Multimap<K, T>> toMultimapByKey(Function<? super T, ? extends Iterable<? extends K>> keysMapper) { return new MultimapCollector<>(keysMapper);}private static class MultimapCollector<T, K> implements Collector<T, ImmutableMultimap.Builder<K, T>, Multimap<K, 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<ImmutableMultimap.Builder<K, T>> supplier() { return ImmutableMultimap::builder; } @Override public BiConsumer<ImmutableMultimap.Builder<K, T>, T> accumulator() { return (builder, value) -> keysMapper.apply(value).forEach(k -> builder.put(k, value)); } @Override public BinaryOperator<ImmutableMultimap.Builder<K, T>> combiner() { return (b1, b2) -> b1.putAll(b2.build()); } @Override public Function<ImmutableMultimap.Builder<K, T>, Multimap<K, T>> finisher() { return ImmutableMultimap.Builder<K, T>::build; } @Override public Set<Characteristics> characteristics() { return Collections.emptySet(); }}
然后该集合将如下所示:
Multimap<String, Foo> map = list.stream().collect(toMultimapByKey(Foo::getTags));
如果顺序对您不重要,则也可以
EnumSet.of(Characteristics.UNORDERED)从
characteristics()方法返回。这可以使内部收集机制更有效地运行,尤其是在并行缩减的情况下。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)