删除重复项而不覆盖hashCode()

时间:2015-12-15 16:14:25

标签: java collections guava

对于企业原因我无法覆盖hashCode,我必须使用Java 6(但我可以使用番石榴)

什么是最优/最快/最有效/ [插入相当于最佳的不确定形容词]机制从Java集合中删除重复的bean?

副本由返回相同值的getter子集定义,例如

pojoA.getVal() == pojoB.getVal() && pojoA.getOtherVal() == pojoB.getOtherVal()

2 个答案:

答案 0 :(得分:10)

将感兴趣的对象包装到您自己的类中,并覆盖其hashCode / equals以关注特定的属性子集。制作一个包装器的哈希集,然后从集合中获取对象以获得无重复的子集。

以下是一个例子:

class ActualData {
    public String getAttr1();
    public String getAttr2();
    public String getAttr3();
    public String getAttr4();
}

让我们说你要注意属性1,2和4.然后你可以制作这样的包装:

class Wrapper {
    private final ActualData data;
    public ActualData getData() {
        return data;
    }
    private final int hash;
    public Wrapper(ActualData data) {
        this.data = data;
        this.has = ... // Compute hash based on data's attr1, 2, and 4
    }
    @Override
    public int hashCode() {
        return hashCode;
    }
    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Wrapper)) return false;
        Wrapper other = (Wrapper)obj;
        return data.getAttr1().equals(other.getAttr1())
            && data.getAttr2().equals(other.getAttr2())
            && data.getAttr4().equals(other.getAttr4());
    }
}

现在你可以制作一个HashSet<Wrapper>

Set<Wrapper> set = new HashSet<>();
for (ActualData item : listWithDuplicates) {
    if (!set.add(new Wrapper(item))) {
        System.out.println("Item "+item+" was a duplicate");
    }
}

答案 1 :(得分:3)

您可以使用带有比较器的new TreeSet<Pojo> (comparator)来反映您的条件(假设这里是整数但是根据需要替换 - 对于非类似对象,您需要找到一个hack来返回一些整数)。

if (pojoA.getVal() != pojoB.getVal())
  return Integer.compare(pojoA.getVal(), pojoB.getVal());
if (pojoA.getOtherVal() != pojoB.getOtherVal())
  return Integer.compare(pojoA.getOtherVal(), pojoB.getOtherVal());
return 0;

虽然效率不如普通HashSet - @dasblikenlight建议可能更好。