3

我有一个方法

<T> void f (Collection<T> c, T t)

唉,有时我需要作为第一个参数传递而不是Collection而是Collection<P>其中PT的前体,即有一个P getter方法返回一个T。那么如何修改我的方法以同时使用Collection<P>Collection<T>(在后一种情况下,getter是身份)?

例如,

<T> boolean f (Collection<T> c, T t) {
  for (T x : c) if (x.equals(t)) return true;
  return false;
}
class Z { String a, b; }

我希望能够使用f通过ab搜索Collection<Z>

f(Collection<Z> c1 ???searching by a???, "foo")
f(Collection<Z> c2 ???searching by b???, "bar")

无法控制TP的实施;特别是,我不能让P从T继承(而且我不想:就像上面的Z一样,我可能想在不同的时间按不同的字段进行搜索)。

我不想通过映射创建中间Collection<T> 。

我想要一些像common :key Lisp 关键字参数这样的东西。

4

2 回答 2

2

如何使用类似接口的谓词来检查相等性。一个例子是:

interface Predicate<T> {
     public boolean test(T element);
}

然后使用以下功能:

 public <T> boolean f(Collection<T> c, Predicate<T> p) {
     for (T x : c) if (p.test(x)) return true;
     return false;
 }

然后你可以通过以下方式调用它:

Collection<T> ts;
f(ts, new Predicate<T> () { 
            public boolean test(T element) { 
                      return element.equals("foo"); 
            }
 });

Collection<P> ps;
f(ps, new Predicate<P> () { 
            public boolean test(P element) { 
                      return element.getT().equals("foo"); 
            }
});

虽然这种语法非常冗长,但它应该适合您的问题。然而,当 lambda 函数到来时,它会在 Java 8 中变得更漂亮。

于 2012-05-10T19:56:38.533 回答
-1

鉴于“Holder”是前体类,“Stuff”是得到的类,您可以这样做:
编辑:切换到凌乱的 instanceof 语句。

public <H, T> boolean contains (Collection<H> c, T t) {
  if (c instanceof Collection<T>)
  {
    for (T x : c) if (x.equals(t)) return true;
    return false;
  }
  //else
  for (H x : c) if (x.getStuff().equals(t)) return true;
  return false;
}
于 2012-05-10T19:42:49.490 回答