0

我有两个学生对象列表(listA 和 listB),它们是通过从两个不同的数据库中查询而形成的。我需要迭代一个列表并需要确保它不存在于另一个列表中。

我已经使用了下面的比较代码,即覆盖了equals方法并使用for循环进行了比较。

说列表 A 和列表 B 可以每个有 5000 行,你能建议是否有更好的方法来实现这个吗?

比较代码:

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

学生对象:

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

编辑说明:ListA & ListB 可以有不同的行数

4

4 回答 4

2

我会建议你的retainAll方法:

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

但是您仍然应该覆盖该equals方法

于 2016-02-02T12:21:29.067 回答
1

您可以使用(Apache Commons)containsAny中的方法:CollectionUtils

if(CollectionUtils.containsAny(listA, listB)){
    break;
}
于 2016-02-02T12:38:30.857 回答
0

一般的方法是遍历第一个列表并检查元素是否包含在第二个列表中,如果存在则将元素添加到结果列表下面是完整的解决方案

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

}
}

学生班

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;
}
}
于 2016-02-02T12:47:32.510 回答
0

removeAll 命令是要走的路,但列表查找效率不高(线性时间),所以总时间为 O(n*m)(n 是 sizeA,m 是 sizeB);每个5000个条目,可能有点太多了。

如果可能,您应该将其更改为使用 Sets(并实现 Student 类的 hashCode 和 equals 方法,以防您还没有!):

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

这会让你得到 O(m*hash(n))。

于 2016-02-02T13:06:14.007 回答