在集合中使用“前体”类

时间:2012-05-10 19:37:03

标签: java generics

我有一个方法

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

唉,有时我需要传递第一个arg而不是集合,但是集合&lt; P&gt; ,其中 P 前体 T ,即 P getter 方法返回 T 。 那么如何修改我的方法以使用 Collection&lt; P&gt; Collection&lt; T&gt; (在后一种情况下 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 a b 搜索集合&lt; Z&gt;

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

没有控制 T P 的实施;特别是,我不能让 P 继承 T (我不想:如上面的 Z ,我可能想要搜索不同时期的不同领域。)

想通过映射创建中间集合&lt; T&gt;

我想要common :key Lisp keyword argument

之类的东西

2 个答案:

答案 0 :(得分: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中变得更漂亮。

答案 1 :(得分:-1)

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

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;
}