Ale
Ale

Reputation: 2354

Java compare different Object by common property

I have ObjectA & ObjectB. Both have a property called ID (Long). I have 2 List, ListA which contains objects type ObjectA and ListB which contains objects type ObjectB.

I want to fill ListC, with all the objects from ListA and ListB but without duplicates.

I cannot use the contains method because ObjectA and ObjectB are different objects, I have to compare by the property ID.

I know the best solution would be that ObjectA and ObjectB extends a Super class, but I cannot change that for now, I just have to find a temporally solution to make it work.

I have try this:

listC.addAll(listA);    

for(int j=0; j<ListA.size(); j++) {
    for(int k=0; k<ListB.size(); k++) {
        ObjectA objectA = ((ObjectA)listA.get(j));
        ObjectB objectB = ((ObjectB)listB.get(k));

        if(!objectA.getId().equals(objectB.getId())) {
            listC.add(objectB);
        }
    }
}

Any ideas? I'm going crazy with it.

Upvotes: 1

Views: 1579

Answers (3)

Julien Charon
Julien Charon

Reputation: 610

For a solution for which you don't need to touch your classes at all, you could implement a java.util.Comparator
like e.g.

public class ObjectComparator implements java.util.Comparator {
    @Override
    public int compare(Object o1, Object o2) {
        long id1 = -1L;
        long id2 = -1L;
        if(o1 instanceof ObjectA) {
            id1 = ((ObjectA)o1).getId();
        }
        if(o1 instanceof ObjectB) {
            id1 = ((ObjectB)o1).getId();
        }
        if(o2 instanceof ObjectA) {
            id2 = ((ObjectA)o2).getId();
        }
        if(o2 instanceof ObjectB) {
            id2 = ((ObjectB)o2).getId();
        }
        return Long.valueOf(id1).compareTo(Long.valueOf(id2));
    }
}

Then you could simply use a java.util.TreeSet to remove duplicates for you:

Set distinct = new TreeSet(new ObjectComparator());
distinct.addAll(listA);
distinct.addAll(listB);

Of course you will get compiler warnings for using raw types, but it should work.

Upvotes: 3

ParkerHalo
ParkerHalo

Reputation: 4430

If you want an "efficient" solution you could implement a HashSet<Long> which is holding all yet used IDs.

HashSet<Long> ids = new HashSet<Long>();
for (ObjectA objA: listA) {
    list.add(objA);
    ids.add(objA.getId());
}

for (ObjectB objB: listB) {
    if (!ids.contains(objB.getId())) {
        ids.add(objB.getId());
        list.add(objB);
    }
}

Upvotes: 2

ctst
ctst

Reputation: 1690

If they both have the same property, write an interface (that's why they are there) which has only the value ID (maybe with a getter) and implement it in your Classes ObjectA and ObjectB. Then you can write your own Comparator (with type of your Interface) or since you only need equals, just override this method (that wouldn't be clean). This should be the cleanest way.

Upvotes: 3

Related Questions