Search code examples
javacollectionsgeneric-collections

Intersect differently typed Collections


I have Collection<A> ca and Collection<B> cb, A and B sharing no common interface but each having a String property called something. I need to filter ca and retain only those elements which have a "corresponding" value in cb.

Unfortunately, creating a common interface for A and B as per this question/answer is not an option.

I'm currently doing

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

exploiting the fact that I know what B.equals does. Is there anything I can do to improve this, performance- and/or resource-wise?


Solution

  • Could you put the As and Bs into Maps, keyed by String? Then you could just use Collection.retainAll() a couple of times:

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

    Bit mad, but there you go.

    bs could be a Set<String> rather than a Map, but i like the symmetry.