相交不同类型的集合

时间:2011-08-25 21:29:34

标签: java collections generic-collections

Collection<A> caCollection<B> cbAB共享没有共同的界面,但每个界面都有一个名为String的{​​{1}}属性。我需要过滤something并仅保留ca中具有“对应”值的元素。

不幸的是,根据this question/answer创建cbA的公共界面不是一种选择。

我正在做

B

利用我知道Iterator<A> it = ca.iterator(); while ( it.hasNext() ) { A a = it.next(); if ( !cb.contains(new B(a.getSomething(), ... <known stuff>) ) it.remove; } 做什么的事实。我能做些什么来提高性能和/或资源方面的效果吗?

3 个答案:

答案 0 :(得分: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();
    }
}

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

答案 1 :(得分:1)

你能把As和B放到地图中,用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可能是Set<String>而不是地图,但我喜欢对称性。

答案 2 :(得分:0)

您可以使用Guava Collections2课程transformfilter,如下所示:

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