从列表中快速删除具有相同内容的重复项(custom.equals())



所以我搜索了这个"问题",只遇到了一些问题,询问如何从列表中删除真正的重复项但我想要的是根据自定义.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;
}
}

现在,如果您将元素添加到包含TestHashSet中,它将正确地解密重复项:

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(为我上面使用的连接哈希代码函数的方法赢得了赞誉。

最新更新