我有一个特殊要求,我需要根据相等标准的组合重复删除对象列表。
e.g。如果出现以下情况,则两个Student
个对象相等:
1. firstName和id相同OR 2. lastName,class和emailId相同
我打算使用Set
删除重复项。但是,有一个问题:
我可以覆盖equals
方法,但hashCode
方法可能不会为两个相等的对象返回相同的哈希码。
@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 ((firstName.equals(other.firstName) && id==other.id) ||
(lastName.equals(other.lastName) && class==other.class && emailId.equals(other.emailId ))
return true;
return false;
}
现在我无法覆盖hashCode
方法,因为它根据此equals
方法为两个相等的对象返回相同的哈希码。
有没有办法根据多个平等标准进行重复数据删除?我考虑使用List
,然后使用contains
方法检查元素是否已存在,但这会增加复杂性,因为包含在O(n)时间内运行。我不想为所有对象返回完全相同的哈希码,因为这只会增加时间并超过使用哈希码的目的。我还考虑过使用自定义比较器对项目进行排序,但是这又需要至少O(n log n),再加上一个步骤来删除重复项。
截至目前,我所拥有的最佳解决方案是维护两个不同的集合,每个集合对应一个条件并使用它来构建List
,但这几乎占用了内存的三倍。我正在寻找一种速度更快,内存效率更高的方式,因为我将处理大量的记录。
答案 0 :(得分:0)
您可以Student
Comparable
并使用TreeSet
。 compareTo
的简单实现可能是:
@Override
public int compareTo(Student other) {
if (this.equals(other)) {
return 0;
} else {
return (this.firstName + this.lastName + emailId + clazz + id)
.compareTo(other.firstName + other.lastName + other.emailId + clazz + id);
}
}
或者制作您自己的Set
实现,例如包含List
个不同的Student
个对象,每次添加学生时都要检查是否相等。这将O(n)
增加复杂性,因此不能被认为是一个好的实现,但编写起来很简单。
class ListSet<T> extends AbstractSet<T> {
private List<T> list = new ArrayList<T>();
@Override
public boolean add(T t) {
if (list.contains(t)) {
return false;
} else {
return list.add(t);
}
}
@Override
public Iterator<T> iterator() {
return list.iterator();
}
@Override
public int size() {
return list.size();
}
}