Log
Log

Reputation: 53

Comparing two list of objects in Java

I have two list of Student Objects(listA & listB) which were formed by querying from two different databases. I need to iterate one list and need to make sure it is not present in the other list.

I have used the below comparison code for the same i.e overwritten the equals method and compared using for loops.

Say List A & List B could have 5000 rows each, can you suggest if there are better ways to implement this?

Comparison code:

for (Student dataA:listA) {
    for (Student dataB:listB) {
        if(dataB.equals(dataA))
            break;                                              
    }
}

Student Object:

public class Student {
    int A;
    int B;
    String C;   

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj == null || obj.getClass() != this.getClass()) {
            return false;
        }
        Student student = (Student) obj;
        return A == student.A && B == student.B && C.equals(student.C);
    }
}

Edit Note: ListA & ListB can have different number of rows

Upvotes: 0

Views: 11070

Answers (4)

Manas
Manas

Reputation: 86

The general approach is iterate through first list and check for element if it is contained in second list, if it exist add the element to the result list Below is the complete solution

import java.util.ArrayList;
import java.util.List;

public class CompareListofObj {

public static void main(String[] args) {

    List<Student> listStd1 = new ArrayList<Student>();
    List<Student> listStd2 = new ArrayList<Student>();

    Student std1 = new Student(1, 1, "a");
    Student std2 = new Student(2, 1, "b");
    Student std3 = new Student(3, 3, "c");
    Student std4 = new Student(4, 4, "d");
    listStd1.add(std1);
    listStd1.add(std2);
    listStd1.add(std3);
    listStd1.add(std4);

    Student std5 = new Student(1, 1, "a");
    Student std6 = new Student(2, 1, "b");
    Student std7 = new Student(7, 7, "c");
    Student std8 = new Student(8, 8, "d");
    listStd2.add(std5);
    listStd2.add(std6);
    listStd2.add(std7);
    listStd2.add(std8);

    List<Student> listResult = new ArrayList<Student>();

    for (int i = 0; i < listStd1.size(); i++) {
        if (listStd2.contains(listStd1.get(i))) {

            listResult.add(listStd1.get(i));

        } else {

        }
    }

    for (int i = 0; i < listResult.size(); i++) {
        System.out.println("common elt" + listResult.get(i).getA() + ", " + listResult.get(i).getB() + ", "
                + listResult.get(i).getC());
    }

}
}

Student class

package sample;

public class Student {

int A;
int B;
String C;

public Student(int a, int b, String c) {
    super();
    A = a;
    B = b;
    C = c;
}

public int getA() {
    return A;
}

public void setA(int a) {
    A = a;
}

public int getB() {
    return B;
}

public void setB(int b) {
    B = b;
}

public String getC() {
    return C;
}

public void setC(String c) {
    C = c;
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + A;
    result = prime * result + B;
    result = prime * result + ((C == null) ? 0 : C.hashCode());
    return result;
}

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Student other = (Student) obj;
    if (A != other.A)
        return false;
    if (B != other.B)
        return false;
    if (C == null) {
        if (other.C != null)
            return false;
    } else if (!C.equals(other.C))
        return false;
    return true;
}
}

Upvotes: 0

Diego Martinoia
Diego Martinoia

Reputation: 4652

The removeAll command is the way to go, but List lookup is not efficient (linear time), so you get a O(n*m) total time (n is sizeA, m is sizeB); 5000 entries on each, it may be a bit too much.

If possible, you should change it to use Sets (and implements the hashCode and equals methods of your Student classes in case you didn't already!):

Set<Student> studentsA = new HashSet<>();
Set<Student> studentsB = new HashSet<>();
studentsA.removeAll(studentsB);

This gets you O(m*hash(n)).

Upvotes: 0

Radu Dumbrăveanu
Radu Dumbrăveanu

Reputation: 1416

You could use containsAny method from CollectionUtils (Apache Commons):

if(CollectionUtils.containsAny(listA, listB)){
    break;
}

Upvotes: 1

ctst
ctst

Reputation: 1680

I would suggest you the retainAll method:

List<Student> listC = new ArrayList();
listC.addAll(listA);
listC.retainAll(listB);   //now listC contains all double students

But you should still override the equals method

Upvotes: 2

Related Questions