[英]Zip two lists into an immutable multimap in Java 8 with Guava?
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
需要返回一個map條目,但是沒有可公開構造的列表條目。 因此,我可以編寫的“最”功能方式是使用壓縮函數返回一個Pair,我不確定它是否存在於Guava中,或者返回一個兩元素列表,這是一個可變類型,在那里沒有正確地說明正是2個元素。
如果我可以創建一個映射條目,那將是理想的:
Streams.zip(keys, values, zippingFunction)
.collect(toImmutableListMultimap(e -> e.getKey(), e.getValue())
這似乎是最好的方式,除非它不可能,並且拉入條目並從條目解壓縮仍然看起來很迂回。 有沒有辦法使這成為可能或一種可以改進的方式?
如果您的列表是隨機訪問,您可以不用壓縮:
Map<Key, Value> map = IntStream.range(0, Math.min(keys.size(), values.size()))
.boxed()
.collect(toImmutableListMultimap(i -> keys[i], i -> values[i]));
我認為你的程序代碼已經是最優化的解決方案(無論是內存還是速度,假設隨機訪問列表)。 通過小的修正,以便您的代碼編譯,它將是:
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();
如果你真的想要使用流來實現“功能”,那么壓縮兩個流是可行的方法,但在收集到multimap之前你仍然需要創建中間的“對”對象。 你聲稱“沒有可公開構建的列表條目”,但事實並非如此,你可以在這里使用JDK的SimpleImmutableEntry
和Guava的Maps.immutableEntry
(它們比更通用的Pair
更合適,實際上它們不能在JDK或Guava中都可以找到。
使用Streams#zip
需要傳遞流,因此最終代碼如下所示:
Streams.zip(keys.stream(), values.stream(), SimpleImmutableEntry::new)
.collect(toImmutableListMultimap(Map.Entry::getKey, Map.Entry::getValue));
如果你願意使用其他允許更多與流相關的操作的“功能”Java庫,你可以使用jOOL及其接受可迭代參數的Seq.zip
:
Seq.zip(keys, values, SimpleImmutableEntry::new)
.collect(toImmutableListMultimap(Map.Entry::getKey, Map.Entry::getValue));
另一個庫是StreamEx ,它公開了EntryStream
- 鍵值EntryStream
的抽象。
所以,你幾乎做對了! 下面是您更新的代碼(假設您的列表是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
的行為(我最喜歡的一個來自溪流)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.