我一直在沉思这一周,我不太确定如何做到这一点。我遇到的一个常见任务是构建包含ImmutableLists的ImmutableMap,如ImmutableMap<K,ImmutableList<V>>
中所示,对于给定类型的值,我想通过收集器来完成,这样我就可以在流上使用它。 / p>
我在下面的博客上发现了这个伟大的ImmutableMap收藏家。但我希望V是一个ImmutableList,我希望传入的流映射多个值,使用与ImmutableList值配对的相同密钥。我尝试过的每个实现都是次优的而不是像流一样,因为我继续使用保存ImmutableList.Builder值的普通HashMap,当我完成填充时,我会遍历它并将其转换为ImmutableList值调用build()并将其放入新映射中。有什么想法吗?
public static <T, K, V> Collector<T, ?, ImmutableMap<K, V>>
toImmutableMap(
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends V> valueMapper) {
Supplier<ImmutableMap.Builder<K, V>> supplier =
ImmutableMap.Builder::new;
BiConsumer<ImmutableMap.Builder<K, V>, T> accumulator =
(b, t) -> b.put(keyMapper.apply(t), valueMapper.apply(t));
BinaryOperator<ImmutableMap.Builder<K, V>> combiner =
(l, r) -> l.putAll(r.build());
Function<ImmutableMap.Builder<K, V>, ImmutableMap<K, V>> finisher =
ImmutableMap.Builder::build;
return Collector.of(supplier, accumulator, combiner, finisher);
}
我希望实现有一个标题...
public static <T, K, V> Collector<T, ?, ImmutableMap<K, ImmutableList<V>>>
感谢fge的帮助,我成功了!见下面的答案。
答案 0 :(得分:0)
好吧,我想我成功利用了ImmutableListMultimap来实现这一目标!谢谢fge!
如果有人看到任何可以改进的东西(我认为合并器无法优化但是如果我错了就纠正我),请告诉我。
public static <T, K, V> Collector<T, ?, ImmutableListMultimap<K, V>> toImmutableListMultimap(
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends V> valueMapper) {
Supplier<ImmutableListMultimap.Builder<K, V>> supplier = ImmutableListMultimap.Builder::new;
BiConsumer<ImmutableListMultimap.Builder<K, V>, T> accumulator = (b, t) -> b
.put(keyMapper.apply(t), valueMapper.apply(t));
BinaryOperator<ImmutableListMultimap.Builder<K, V>> combiner = (l, r) -> {
final ImmutableListMultimap<K, V> rightMap = r.build();
rightMap.keySet().stream().forEach(k -> l.putAll(k, rightMap.get(k)));
return l;
};
Function<ImmutableListMultimap.Builder<K, V>, ImmutableListMultimap<K, V>> finisher = ImmutableListMultimap.Builder::build;
return Collector.of(supplier, accumulator, combiner, finisher);
}
更新 - 反映fge的建议并简化组合器
public static <T, K, V> Collector<T, ?, ImmutableMultimap<K, V>> toImmutableListMultimap(
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends V> valueMapper) {
Supplier<ImmutableMultimap.Builder<K, V>> supplier = ImmutableListMultimap.Builder::new;
BiConsumer<ImmutableMultimap.Builder<K, V>, T> accumulator = (b, t) -> b
.put(keyMapper.apply(t), valueMapper.apply(t));
BinaryOperator<ImmutableMultimap.Builder<K, V>> combiner = (l, r) -> l.putAll(r.build());
Function<ImmutableMultimap.Builder<K, V>, ImmutableMultimap<K, V>> finisher = ImmutableMultimap.Builder::build;
return Collector.of(supplier, accumulator, combiner, finisher);
}