Reputation: 53
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
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
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
Reputation: 1416
You could use containsAny
method from CollectionUtils
(Apache Commons):
if(CollectionUtils.containsAny(listA, listB)){
break;
}
Upvotes: 1
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