0

我有Collection<A> caCollection<B> cbA并且B没有共享通用接口,但每个接口都有一个String名为something. 我只需要过滤ca并保留那些在cb.

A不幸的是,B这个问题/答案创建一个通用界面并不是一种选择。

我目前在做

Iterator<A> it = ca.iterator();
while ( it.hasNext() ) {
    A a = it.next();
    if ( !cb.contains(new B(a.getSomething(), ... <known stuff>) )
        it.remove;
}

利用我知道做什么的事实B.equals。在性能和/或资源方面,我能做些什么来改善这一点?

4

3 回答 3

1

你能考虑创建新的包装对象吗?

interface Holder {
    Object getThing(); //or a primative

class HolderA implements Holder {
    private A a;

    public HolderA(A _a) {
        a = _a;
    }

    public Object getThing() {
        return a.getSomething();
    }
}

class HolderB implements Holder {
    private B b;

    public HolderB(B _b) {
        b = _b;
    }

    public Object getThing() {
        return b.getSomething();
    }
}

我认为您应该能够比较这两个对象。

于 2011-08-25T21:38:29.870 回答
1

您可以将 As 和 Bs 放入 Maps 中,由 String 键入吗?然后你可以使用 Collection.retainAll() 几次:

Map<String, A> as = new HashMap<String, A>;
for (A a: ca) as.put(a.getSomething(), a);
Map<String, B> bs = new HashMap<String, B>;
for (B b: cb) bs.put(b.getSomething(), b);
as.keySet().retainAll(bs.keySet());
ca.retainAll(as.values());

有点生气,但你走了。

bs 可能是 aSet<String>而不是 Map,但我喜欢对称性。

于 2011-08-25T23:19:52.767 回答
0

您可以使用Guava Collections2类,transform如下filter所示:

Collection<A> as = ...;
Collection<B> bs = ...;

final Collection<String> b_somethings = 
    Collections2.transform(
        bs, 
        new Function<B, String>() {
            public String apply(B input) {
                return input.getSomething();
            }   
        });

Collection<A> filtered_as = 
    Collections2.filter(
        as, 
        new Predicate<A>() {
            public boolean apply(A input) {
                return b_somethings.contains(input.getSomething());
            }
        });
于 2011-08-25T23:53:00.260 回答