【问题标题】:Removing duplicates without overriding hashCode() [duplicate]在不覆盖 hashCode() 的情况下删除重复项 [重复]
【发布时间】:2015-12-16 11:07:46
【问题描述】:

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

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

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

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

【问题讨论】:

  • 我对当前的 hashCode 没有反映任何关于 getter 返回值的平等的信息吗?它是如何实现的?
  • @sphinks yes hashcode 是事实上的对象
  • @sphinks set 依赖于哈希码,不是吗?
  • 扩展集合并覆盖实际通过hashCode比较对象的方法?有可能吗?
  • @NimChimpsky 如果您使用的是 TreeSet,它将依赖比较器。

标签: java collections guava


【解决方案1】:

将感兴趣的对象包装到您自己的类中,并覆盖其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");
    }
}

【讨论】:

    【解决方案2】:

    您可以使用带有比较器的new TreeSet&lt;Pojo&gt; (comparator) 来反映您的情况(假设此处为整数,但根据需要替换 - 对于不可比较的对象,您需要找到一个技巧来返回一些整数)。

    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 的建议可能更好。

    【讨论】:

      猜你喜欢
      • 2015-06-14
      • 2013-06-11
      • 2015-05-18
      • 2019-05-17
      • 2011-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-04
      相关资源
      最近更新 更多