for循环看起来像
ImmutableListMultiMap.<Key, Value>Builder builder
= ImmutableListMultiMap.<Key, Value>newBuilder();
for (int i = 0; i < Math.min(keys.length(), values.length()); i++) {
builder.put(keys.at(i), values.at(i));
}
Guava / Java 8中可能的第一步是
Streams.zip(keys, values, zippingFunction)
我认为zippingFunction
需要返回一个映射条目,但是没有可公开构建的列表条目。因此,我可以编写的“最”功能方式是使用压缩函数返回一个Pair,我不确定它是否存在于Guava中,或者返回一个两元素列表,这是一个可变类型,在那里没有正确地说明正好是2个元素。
如果我可以创建一个地图条目,那将是理想的:
Streams.zip(keys, values, zippingFunction)
.collect(toImmutableListMultimap(e -> e.getKey(), e.getValue())
这似乎是最好的方式,除非它不可能,并且拉入条目并从条目解压缩仍然看起来很迂回。有没有办法使这成为可能或一种可以改进的方式?
答案 0 :(得分:5)
如果你的列表是随机访问的,你可以不用压缩来实现:
Map<Key, Value> map = IntStream.range(0, Math.min(keys.size(), values.size()))
.boxed()
.collect(toImmutableListMultimap(i -> keys[i], i -> values[i]));
答案 1 :(得分:3)
我认为你的程序代码已经是最优的解决方案(在内存和速度方面,假设随机访问列表)。通过小的修正,以便您的代码编译,它将是:
ImmutableListMultimap.Builder<Key, Value> builder = ImmutableListMultimap.builder();
for (int i = 0; i < Math.min(keys.size(), values.size()); i++) {
builder.put(keys.get(i), values.get(i));
}
return builder.build();
如果你真的想要使用流来实现功能&#34;,那么就可以使用两个流,但是你还需要创建中间&#34;对&#34; ;收集到multimap之前的对象。您声称&#34;没有可公开构建的列表条目&#34;,但它不是真的,有JDK&#39; s SimpleImmutableEntry
和Guava&#39; s {{ 3}}你可以在这里使用(它们比更通用的Pair
更合适,事实上,它们在JDK或Guava中都找不到。
使用Maps.immutableEntry
需要传递流,因此最终代码如下所示:
Streams.zip(keys.stream(), values.stream(), SimpleImmutableEntry::new)
.collect(toImmutableListMultimap(Map.Entry::getKey, Map.Entry::getValue));
如果您愿意使用其他&#34;功能性&#34;允许更多与流相关的操作的Java库,您可以使用Streams#zip
及其jOOL,它们接受可迭代的参数:
Seq.zip(keys, values, SimpleImmutableEntry::new)
.collect(toImmutableListMultimap(Map.Entry::getKey, Map.Entry::getValue));
答案 2 :(得分:2)
所以,你几乎做对了!以下是您的更新代码(假设您的列表属于Integer
类型):
Streams.zip(keys.stream(), values.stream(), AbstractMap.SimpleImmutableEntry::new)
.collect(toImmutableListMultimap(Map.Entry<Integer, Integer>::getKey,
Map.Entry<Integer, Integer>::getValue)
);
但我总是喜欢在本地做事,因为它会给你更多力量。请使用collect
:
Streams.zip(keys.stream(), values.stream(), (k, v) -> new AbstractMap.SimpleImmutableEntry(k, v))
.collect(ImmutableListMultimap::builder,
ImmutableListMultimap.Builder::put,
(builder2, builder3) -> builder2.putAll(builder3.build())
).build();
注意: - builder2.putAll(builder3.build())
BiConsumer仅在您使用并行流时才有效。这是collect
的行为(我最喜欢的一个来自溪流)。