ger*_*ges 5 java functional-programming guava
我很抱歉,如果这个问题是一个重复的,搜索是困难的,因为我是不确定的就是我试图完成正确的名称.最简单的解释是
List<A>, List<B> into Map<Key, Tuple<A,B>> where A.Key matched B.Key
Run Code Online (Sandbox Code Playgroud)
澄清一下:我有一个共享密钥的A对象和B对象的列表.我想那么这两个列表关联到一个地图,当密钥匹配到地图的关键,而元组A,B.
我已经在脑子里玩了很多关于如何做到这一点的想法,但大多数人都觉得我觉得我误用了这个库(比如Maps.uniqueIndex和Iterables.transform).谁能指出我正确的方向?
Guava中没有元组(对等)实现.(这是另一个讨论,如果在Java中实现元组是个好主意.)我建议的自然映射是使用Multimap:
List<A> as = Lists.newArrayList(new A(1, "a"), new A(3, "c"), new A(2, "b"));
List<B> bs = Lists.newArrayList(new B(1, 2), new B(3, 6), new B(5, 10));
Function<WithKey, Object> toKey = new Function<WithKey, Object>() {
@Override public Object apply(WithKey input) { return input.key(); }
};
ImmutableListMultimap<Object, AbstractWithKey> index =
Multimaps.index(Iterables.concat(as, bs), toKey);
Run Code Online (Sandbox Code Playgroud)
要么
Multimap<Object, WithKey> m = ArrayListMultimap.create();
for (WithKey w : Iterables.concat(as, bs)) m.put(w.key(), w);
Run Code Online (Sandbox Code Playgroud)
您必须在使用多图之前(或在迭代多图条目时)检查不变量,例如,可能只有A或B实例的键.(这不应该是性能问题,因为它可以通过Iterables.filter懒散地完成.)
一种类型的重复是另一个问题.您可以检查它们或使用HashMultimap忽略它们.您甚至可以构建一个带有约束集的多图,用于检查值是唯一的值(请参阅Multimaps.newSetMultimap(Map> map,Supplier> factory)和 Constraints.constrainedSet(Set set,Constraint constraint)).这具有快速失败的优点.
通过这些A和B实现:
interface WithKey {
Object key();
}
abstract class AbstractWithKey implements WithKey {
Object key;
Object v;
@Override public Object key() { return key; }
@Override public String toString() {
return MoreObjects.toStringHelper(this).add("k", key).add("v", v).toString();
}
}
class A extends AbstractWithKey {
public A(int i, String v) {
key = i;
this.v = v;
}
}
class B extends AbstractWithKey {
public B(int i, int v) {
key = i;
this.v = v;
}
}
Run Code Online (Sandbox Code Playgroud)
输出是:
{1 = [A {k = 1,v = a},B {k = 1,v = 2}],2 = [A {k = 2,v = b}],3 = [A {k = 3 ,v = c},B {k = 3,v = 6}],5 = [B {k = 5,v = 10}]}
更新:
如果必须最终使用元组实例,则可以转换Multimap.
Multimap<Object, WithKey> m = ArrayListMultimap.create();
for (WithKey w : Iterables.concat(as, bs)) m.put(w.key(), w);
Function<Collection<WithKey>, Tuple> f =
new Function<Collection<WithKey>, Tuple>(){
@Override public Tuple apply(Collection<WithKey> input) {
Iterator<WithKey> iterator = input.iterator();
return new Tuple(iterator.next(), iterator.next());
} };
Map<Object, Tuple> result = Maps.transformValues(m.asMap(), f);
Run Code Online (Sandbox Code Playgroud)
输出((a,b)是元组语法):
{1=(A{k=1, v=a},B{k=1, v=2}), 3=(A{k=3, v=c},B{k=3, v=6})}
Run Code Online (Sandbox Code Playgroud)