我有一个方法
<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; 。
之类的东西答案 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;
}