使用Guava将两个列表压缩成Java 8中的不可变多图吗? [英] Zip two lists into an immutable multimap in Java 8 with Guava?

查看:63
本文介绍了使用Guava将两个列表压缩成Java 8中的不可变多图吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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中可能的第一步是

A possible first step in Guava / Java 8 is

Streams.zip(keys, values, zippingFunction)

我认为 zippingFunction 需要返回一个地图条目,但是没有可公开构建的列表条目.因此,我可以写出的最"函数式方法是使用一个zipping函数,该函数返回一个对(我不确定在Guava中是否存在对)或返回一个两个元素的列表,这是一个可变类型,不能正确地表示在那里恰好是2个元素.

I think zippingFunction needs to return a map entry, but there isn't a publicly constructable list entry. So the "most" functional way I can write this is with a zipping function that returns a Pair, which I'm not sure exists in Guava, or returns a two-element list, which is a mutable type that does not properly connote there are exactly 2 elements.

如果我可以创建地图条目,这将是理想的:

This would be desired if I could create a map entry:

Streams.zip(keys, values, zippingFunction)
.collect(toImmutableListMultimap(e -> e.getKey(), e.getValue())

这似乎是最好的方法,除了不可能的以外,将条目压缩并从条目解压缩似乎仍然是回旋.有没有办法使之成为可能或有待改进?

This seems like the best way, except it's not possible, and the zip into entries and unzip from entries still seems roundabout. Is there a way to make this possible or a way it can be improved?

推荐答案

我认为您的过程代码已经是最佳的解决方案(就内存和速度而言,假设使用随机访问列表).进行一些小的更正,以便您的代码得以编译,这将是:

I think your procedural code is the most optimal solution already (both in terms of memory and speed, assuming random access lists). With small corrections, so that your code compiles, it would be:

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();

如果您真的想使用流来起作用",则压缩两个流是可行的方法,但是在收集到多图之前,您仍然必须创建中间的"pair"对象.您声称没有可公开构建的列表条目",但这不是事实,存在JDK的

If you really want to use streams in order to "be functional", zipping two streams is the way to go, but you'd still have to create intermediate "pair" objects before collecting to multimap. You claim that "there isn't a publicly constructable list entry", but it's not true, there are JDK's SimpleImmutableEntry and Guava's Maps.immutableEntry you can use here (and they fit better than more generic Pair, which, in fact, cannot be found in both JDK or Guava.

使用

Using Streams#zip requires passing streams, so the final code would look like this:

Streams.zip(keys.stream(), values.stream(), SimpleImmutableEntry::new)
    .collect(toImmutableListMultimap(Map.Entry::getKey, Map.Entry::getValue));


如果您愿意使用允许更多与流有关的操作的其他功能性" Java库,则可以使用 jOOL 及其


If you're open to using other "functional" Java libraries which allow more stream-related operations, you could use jOOL and its Seq.zip, which accept iterable parameters:

    Seq.zip(keys, values, SimpleImmutableEntry::new)
        .collect(toImmutableListMultimap(Map.Entry::getKey, Map.Entry::getValue));

另一个库是 StreamEx ,该库公开了

Another library would be StreamEx, which exposes EntryStream - an abstraction for key-value pair streams.

这篇关于使用Guava将两个列表压缩成Java 8中的不可变多图吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆