【问题标题】:How hashset remove duplicate entries?hashset如何去除重复条目?
【发布时间】:2015-09-23 06:21:14
【问题描述】:
public class Type extends SomeObject implements java.io.Serializable {

    private Integer typeId;

    private String typeName;

     private String typeCode;
}

我正在使用休眠作为类型对象从数据库中获取数据。现在我的类(也不是它的父类)不会覆盖 equals 方法。因此,如果我将所有 Type 对象插入到哈希集中,它不应该删除重复项,但它正在删除重复项。我的问题是它如何识别重复项?

【问题讨论】:

  • 它不应该也永远不会,除非它找到hashcode and equals
  • SomeObject 类怎么样?它是否覆盖了方法?
  • 从概念上来说不应该。这是否意味着它正在兑现价值并使用相同的对象,如果它有多个参考
  • 之所以如此,是因为 Object 有一个 hashCode() 和一个 equals() 方法。在 Hibernate Session 中,给定的实体只有一个唯一的实例。
  • Parents 类没有覆盖 Equals。

标签: java hibernate collections


【解决方案1】:

在 Hibernate Session 中,给定的实体只存在一次。 IE。如果你这样做了

Type type1 = (Type) session.get(Type.class, 42);
Type type2 = (Type) session.get(Type.class, 42);
Type type3 = (Type) session.createQuery("select t from Type t where t.id = 42").uniqueResult();

那么type1type2type3 都将是对单个对象的引用。因此,将它们全部添加到一个空的 HashSet 中会导致一个大小为 1 的 HashSet,因为Object.equals() 在将对象与自身进行比较时返回 true。

【讨论】:

    【解决方案2】:

    如果你的类覆盖了 hashcode 和 equals 方法,则使用被覆盖的方法,或者使用默认方法,使用 Object 类中存在的方法。但是在 HashSets、Hashmaps 等中使用了 hashcode 和 equals。

    默认行为可以参考doc

    Object类的equals方法实现了最区分 对象上可能的等价关系;也就是说,对于任何非空 参考值 x 和 y,当且仅当 x 和 y 指的是同一个对象(x == y 的值为 true)

    在合理可行的情况下,hashCode 方法定义为 类 Object 确实为不同的对象返回不同的整数。 (这个 通常是通过转换的内部地址来实现 对象转换成整数,但这种实现技术不是 JavaTM 编程语言所要求的。)

    添加如何查找重复项:

    让我们先看看散列:
    散列用于快速检索数据。基本上哈希函数会生成一个索引值(这个索引值通常是指可以存储对象的桶),一旦生成了这个索引值,它就会在那个特定的桶中搜索那个对象。
    我建议你研究一下散列

    Hashing Wiki

    每当我们添加到hashset时,使用hashcode方法,它返回一个索引值,对象存储在那个桶中(那个索引对应的桶)。 当再次添加同一个对象时,哈希码值将相同,因此它引用同一个桶,现在由于该对象已经存在于该桶中(这里使用 equals 方法检查对象之间的相等性),不再添加



    class Data {
    
    public Data(String name) {
        super();
        this.name = name;
    }
    
    String name;
    }
    
    public class ReadFromFile {
    
    public static void main(String[] args) throws IOException {
        Data s = new Data("yo");
        HashSet<Data> set = new HashSet<>();
        set.add(new Data("hi"));// hi
        set.add(new Data("hi"));// hi but has a different address because a new
                                // object is created
        System.out.println("Size before adding s " + set.size());
        set.add(s);
        set.add(s);// because same object is being added, default hashcode
                    // generates same value, as it uses address to generate
                    // hashcode
        System.out.println("Size after adding s " + set.size());
    }
    
    }
    


    输出
    加 s 前的尺寸 2
    添加 s 3 后的大小

    【讨论】:

    • 我引用的内容是 hashcode 和 equals 的默认行为,hashset 使用的方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-20
    • 2010-12-17
    • 1970-01-01
    • 2021-05-18
    • 1970-01-01
    • 2010-12-29
    • 2015-09-12
    相关资源
    最近更新 更多