所以我搜索了这个"问题",只遇到了一些问题,询问如何从列表中删除真正的重复项但我想要的是根据自定义.equals((方法删除列表中每个等于另一个Object的Object
这里有一个equals((方法被覆盖的示例类:
private static class Test {
int x;
float[] data;
public Test(int x, float[] data) {
this.x = x;
this.data = data;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Test) {
Test compare = (Test) obj;
if (
compare.x == this.x &&
Arrays.equals(compare.data, this.data)
) {
return true;
}
}
return false;
}
}
现在,以下内容当然不一样了(例如,没有可以通过HashMap消除的重复(:
Test test1 = new Test(3, new float[]{0.1f, 0.4f});
Test test2 = new Test(3, new float[]{0.1f, 0.4f});
但在我的情况下,它们是重复的,我只想保留其中一个。
我想出了这个方法:
Test test1 = new Test(3, new float[]{0.1f, 0.4f});
Test test2 = new Test(3, new float[]{0.1f, 0.4f});
Test test3 = new Test(2, new float[]{0.1f, 0.5f});
List<Test> list = new ArrayList<>();
list.add(test1);
list.add(test2);
list.add(test3);
Set<Test> noDuplicates = new HashSet<>();
for (Test testLoop : list) {
boolean alreadyIn = false;
for (Test testCheck : noDuplicates) {
if (testLoop.equals(testCheck)) {
alreadyIn = true;
break;
}
}
if (!alreadyIn) {
noDuplicates.add(testLoop);
}
}
这很好,但就性能而言就不那么好了。(在我的情况下,这很重要,因为列表大小可能很大(
现在我的问题是:有没有更方便的方法来实现这一点
我可能完全误解了您的需求,但我认为您只需要覆盖hashCode((,以便在equals为true的情况下生成相同的哈希代码。
因此,一个为compare.data生成哈希代码的方法。如果你这样做,那么你只需将所有元素添加到hastSet中即可删除重复项。
记住规则:如果覆盖equals,则必须同时覆盖hashCode。
根据定义,集合不允许重复。
Set<Test> noDuplicates = new HashSet<>();
noDuplicates.addAll(list);
EDIT:要实现这一点,您还必须定义hashCode((,而不仅仅是equals((。
HashSet
使用hashCode()
函数来确定对象是否重复。
因此,您需要覆盖Test
类的hashCode()
函数。
这看起来像:
private static class Test {
int x;
float[] data;
...
@Override
public int hashCode() {
int hash = Arrays.hashCode(data);
hash = hash * 31 + x;
return hash;
}
}
现在,如果您将元素添加到包含Test
的HashSet
中,它将正确地解密重复项:
Test test1 = new Test(3, new float[]{0.1f, 0.4f});
Test test2 = new Test(3, new float[]{0.1f, 0.4f});
Test test3 = new Test(2, new float[]{0.1f, 0.5f});
Set<Test> noDuplicates = new HashSet<>();
noDuplicates.add(test1);
noDuplicates.add(test2);
noDuplicates.add(test3);
请记住,每次添加要包含在相等性检查中的成员变量时,都必须更新Test
中的hashCode()
函数
乔恩·斯基特(Jon Skeet(为我上面使用的连接哈希代码函数的方法赢得了赞誉。