精华内容
下载资源
问答
  • 2019-02-01 23:37:03

    原文地址
    Java的Object类中有一个方法:

    public native int hashcode();
    

    hashcode方法的作用

    对于包含容器类型的程序设计语言来说,基本上都会涉及到hashCode。在Java中也一样,hashCode方法的主要作用是为了配合基于散列的集合一起正常运行,这样的散列集合包括HashSet、HashMap以及HashTable。

    为什么这么说呢?考虑一种情况,当向集合中插入对象时,如何判别在集合中是否已经存在该对象了?(注意:集合中不允许重复的元素存在)

    也许大多数人都会想到调用equals方法来逐个进行比较,这个方法确实可行。但是如果集合中已经存在一万条数据或者更多的数据,如果采用equals方法去逐一比较,效率必然是一个问题。此时hashCode方法的作用就体现出来了,当集合要添加新的对象时,先调用这个对象的hashCode方法,得到对应的hashcode值,实际上在HashMap的具体实现中会用一个table保存已经存进去的对象的hashcode值,如果table中没有该hashcode值,它就可以直接存进去,不用再进行任何比较了;如果存在该hashcode值, 就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址,所以这里存在一个冲突解决的问题,这样一来实际调用equals方法的次数就大大降低了,说通俗一点:Java中的hashCode方法就是根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。

    有些朋友误以为默认情况下,hashCode返回的就是对象的存储地址,事实上这种看法是不全面的,确实有些JVM在实现时是直接返回对象的存储地址,但是大多时候并不是这样,只能说可能存储地址有一定关联。

    因此有人会说,可以直接根据hashcode值判断两个对象是否相等吗?肯定是不可以的,因为不同的对象可能会生成相同的hashcode值。虽然不能根据hashcode值判断两个对象是否相等,但是可以直接根据hashcode值判断两个对象不等,如果两个对象的hashcode值不等,则必定是两个不同的对象。如果要判断两个对象是否真正相等,必须通过equals方法。

    也就是说对于两个对象,如果调用equals方法得到的结果为true,则两个对象的hashcode值必定相等;

    如果equals方法得到的结果为false,则两个对象的hashcode值不一定不同;

    如果两个对象的hashcode值不等,则equals方法得到的结果必定为false;

    如果两个对象的hashcode值相等,则equals方法得到的结果未知。

    equals方法和hashCode方法

    在重写equals方法的同时,必须重写hashCode方法。目的是让equals方法和hashCode方法始终在逻辑上保持一致性。

    在设计hashCode方法和equals方法的时候,如果对象中的数据易变,则最好在equals方法和hashCode方法中不要依赖于该字段。

    更多相关内容
  • hashCode 原理

    2021-02-25 20:20:31
    网上一般都说hashCode 就是对象的内存地址,但是你想下垃圾回收时(复制算法,整理算法)都要发生对象移动,都要改变对象的内存地址。但hashCode又不能变化,那么该值一定是被保存在对象的某个地方了。 hashcode就是...

    网上一般都说hashCode 就是对象的内存地址,但是你想下垃圾回收时(复制算法,整理算法)都要发生对象移动,都要改变对象的内存地址。但hashCode又不能变化,那么该值一定是被保存在对象的某个地方了。

    hashcode就是保存在对象头里面的,但是如果hashcode是内存地址的话,那么就有可能会重复到之前回收对象的地址。对象头详解见此文章

    synchronized 原理 锁升级 详解

    苍天可见,hashcode绝对不是简简单单的内存地址。

    hashcode的6种生成策略

    可以通过在JVM启动参数中添加-XX:hashCode=4,改变默认的hashCode计算方式。

    1. hashCode=0

    if (hashCode == 0) {
         value = os::random() ;
      }
    

    此类方案返回一个Park-Miller伪随机数生成器生成的随机数OpenJdk 6 &7的默认实现。

    2. hashCode=1

    if (hashCode == 1) {
         intptr_t addrBits = cast_from_oop<intptr_t>(obj) >> 3 ;
         value = addrBits ^ (addrBits >> 5) ^ GVars.stwRandom ;
    }
    

    此类方案将对象的内存地址,做移位运算后与一个随机数进行异或得到结果。

    3. hashCode = 2

    if (hashCode == 2) {
         value = 1 ;            // for sensitivity testing
    }
    

    此类方案返回固定的1。

    4. hashCode = 3

    if (hashCode == 3) {
         value = ++GVars.hcSequence ;
    }
    

    此类方案返回一个自增序列的当前值。

    5. hashCode = 4

    if (hashCode == 4) {
         value = cast_from_oop<intptr_t>(obj) ;
    }
    

    此类方案返回当前对象的内存地址。

    6. hashCode 为 其它

    通过和当前线程有关的一个随机数+三个确定值,运用Marsaglia’s xorshift scheme随机数算法得到的一个随机数。JDK8 的默认hashCode的计算方法就是这个xorshift 算法。

    测试hashcode是不是内存地址

    首先有个工具类:利用Unsafe类 打印真实内存地址

    public static class Memory {
            static final Unsafe unsafe = getUnsafe();
            static final boolean is64bit = true;
    
            public static void printAddresses(Object... objects) {
                long last = 0;
                int offset = unsafe.arrayBaseOffset(objects.getClass());
                int scale = unsafe.arrayIndexScale(objects.getClass());
                switch (scale) {
                    case 4:
                        long factor = is64bit ? 8 : 1;
                        final long i1 = (unsafe.getInt(objects, offset) & 0xFFFFFFFFL) * factor;
                        System.out.print(Long.toHexString(i1));
                        last = i1;
                        for (int i = 1; i < objects.length; i++) {
                            final long i2 = (unsafe.getInt(objects, offset + i * 4) & 0xFFFFFFFFL) * factor;
                            if (i2 > last)
                                System.out.print(", +" + Long.toHexString(i2 - last));
                            else
                                System.out.print(", -" + Long.toHexString(last - i2));
                            last = i2;
                        }
                        break;
                    case 8:
                        throw new AssertionError("Not supported");
                }
                System.out.println();
    
            }
    
            private static Unsafe getUnsafe() {
    
                try {
                    Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
                    theUnsafe.setAccessible(true);
                    return (Unsafe)theUnsafe.get(null);
                } catch (Exception e) {
                    throw new AssertionError(e);
                }
    
            }
        }
    

    main方法

     public static void main(String[] args) throws Exception {
            Object o = new Object();
            
            Memory.printAddresses(o);
            System.err.println(Long.toHexString(o.hashCode()));
            System.err.println(Long.toHexString(System.identityHashCode(o)));
        }
    

    打印结果

    76b8b4c28
    4e25154f
    4e25154f
    

    hashCode 跟 System.identityHashCode 方法一样,但是跟内存地址没半毛钱关系。

    我们在改变main方法

     public static void main(String[] args) throws Exception {
            Object o1 = new Object();
            Object o2 = new Object();
            
            Memory.printAddresses(o2);
            System.err.println(Long.toHexString(o2.hashCode()));
            System.err.println(Long.toHexString(System.identityHashCode(o2)));
        }
    

    打印结果

    76b8b4c58
    4e25154f
    4e25154f
    

    很奇怪,我们定义了两个对象,打印第二个对象内存地址和第一次打印的不同,这很正常。

    但是打印hashcode确实跟第一次完全一样,由此可见hashcode值跟对象没关系,可能就是分配好的数列,你构造了一个对象就顺序取取数列中的数作为hashcode。

    hashcode什么时候生成,在哪分配给对象的 还请大神知道的留言给我!!!!谢谢~~

    再来欣赏几个面试题

    1、equals()既然已经能实现对比的功能了,为什么还要hashCode()呢?

    因为重写的equals()里一般比较的比较全面比较复杂,这样效率就比较低,而利用hashCode()进行对比,则只要生成一个hash值进行比较就可以了,效率很高。

    2、hashCode()既然效率这么高为什么还要equals()呢?

    因为hashCode()并不是完全可靠,有时候不同的对象他们生成的hashcode也会一样(生成hash值得公式可能存在的问题),所以hashCode()只能说是大部分时候可靠,并不是绝对可靠,所以我们可以得出:

    equals()相等的两个对象他们的hashCode()肯定相等,也就是用equals()对比是绝对可靠的。

    hashCode()相等的两个对象他们的equals()不一定相等,也就是hashCode()不是绝对可靠的。

    3、为什么要重写 hashcode 和 equals 方法?

    因为原生的hashcode和equals 只是比较类似内存地址的唯一值,也就是说必须是new出的同个对象才返回相等,跟对象里的业务值没关系。 但是有的场景比如订单对象,很明显当订单号相同的两个订单对象就应该是相等的,于是我们需要重写hashcode 和equals 只判断订单号相等则对象相等。

    Hashcode的位移优化

    一些位运算符介绍

    << : 左移运算符,num << 1,相当于num乘以2 低位补0>> : 右移运算符,num >> 1,相当于num除以2 高位补0>>> : 无符号右移,忽略符号位,空位都以0补齐。
    
    
    % : 模运算 取余。
    
    
    ^ : 位异或 第一个操作数的的第n位于第二个操作数的第n位相反,那么结果的第n为也为1,否则为0& : 与运算 第一个操作数的的第n位于第二个操作数的第n位如果都是1,那么结果的第n为也为1,否则为0| : 或运算 第一个操作数的的第n位于第二个操作数的第n位 只要有一个是1,那么结果的第n为也为1,否则为0~ : 非运算 操作数的第n位为1,那么结果的第n位为0,反之,也就是取反运算(一元操作符:只操作一个数)。
    

    String类的hashcode方法

    public int hashCode() {
            int h = hash;
            if (h == 0 && value.length > 0) {
                 // 保证只计算一次,之后直接取hash 这个缓存
                char val[] = value;
    
                for (int i = 0; i < value.length; i++) {
                    h = 31 * h + val[i];
                }
                hash = h;
            }
            return h;
        }
    

    31*h可以被编译器优化为 h左移5位后减h , 因为31 二进制是 11111, 有较高的性能。

    之所以是31原因就是,选太小的质数移位后也是区间很小,hash冲突高,如果选择很大的质数,移位后会导致区间数很大,超出int的范围,而String的hash就是用int存储的。

    其它的原因我也讲不出来,还是请各位看下大佬的解释吧,也请大佬跟我留言解释下为什么就是31,感谢大佬

    强烈推荐一套Java进阶博客,都是干货,走向架构师不是梦!

    Java进阶全套博客

    展开全文
  • Java基础之hashcode剖析

    2022-02-21 18:49:08
    在 Java 中,高效的散列算法支持一些最流行的集合,例如HashMap和HashSet,在本文中,我们将重点介绍hashCode() 的工作原理、它如何在集合中使用以及如何正确实现它。 2. hashcode 原理 2.1 Java equals()和...

    1. 前言

    散列是计算机科学的一个基本概念。在 Java 中,高效的散列算法支持一些最流行的集合,例如HashMap和HashSet,在本文中,我们将重点介绍hashCode() 的工作原理、它如何在集合中使用以及如何正确实现它。

    2. hashcode 原理

    2.1 Java equals()和hashCode()的关系

    Object.html#hashCode()

    hashcode的理解

    1. hashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,hashCode是用来在散列存储结构中确定对象的存储地址的;
    2. 如果两个对象相同,就是适用于equals(java.lang.Object) 方法,那么这两个对象的hashCode一定要相同;
    3. 如果对象的equals方法被重写,那么对象的hashCode也尽量重写,并且产生hashCode使用的对象,一定要和equals方法中使用的一致,否则就会违反上面提到的第2点;
    4. 两个对象的hashCode相同,并不一定表示两个对象就相同,也就是不一定适用于equals(java.lang.Object) 方法,只能够说明这两个对象在散列存储结构中,如Hashtable,他们 “存放在同一个篮子里” 。

    再归纳一下就是 hashCode是用于查找使用的,而 equals是用于比较两个对象的是否相等的。以下这段话是从别人帖子回复拷贝过来的,说得很形象:

    (1) hashcode是用来查找的,如果你学过数据结构就应该知道,在查找和排序说过:假如内存中有这样的位置 [0 1 2 3 4 5 6 7] 而我有个类,这个类有个字段叫ID,我要把这个类存放在以上8个位置之一,如果不用hashcode而任意存放,那么当查找时就需要到这八个位置里挨个去找,或者用类似二分法的算法。 但如果用hashcode那就会使效率提高很多。

    我们这个类中有个字段叫ID,那么我们就定义我们的hashcode为ID%8,然后把我们的类存放在取得得余 数那个位置。比如我们的ID为9,9除8的余数为1,那么我们就把该类存在1这个位置,如果ID是13,求得 的余数是5,那么我们就把该类放在5这个位置。这样,以后在查找该类时就可以通过ID和8求余数直接找到 存放的位置了。

    (2) 但是如果两个类有相同的hashcode该怎么办呢(假设上面的ID不是唯一的),假如 9%8=1,17%8=1,那么这是不是合法的呢?回答是:可以这样。

    那么如何判断呢?在这个时候就需要定义 equals了。也就是说,我们先通过hashcode来判断两个类是否存放在一个桶里面,但是这个桶里面可以有很多类,那么我们就需要通过equals 来在这个桶里找到我们要的类。

    那么。重写了equals(),为什么还要重写hashCode()呢?

    想想,你要在一个桶里找东西,你必须先要找到这个桶啊,你不通过重写hashcode()来找到桶,光重写equals()有什么用啊

    2.2 举例分析

    package com.wxw.common.hashcode;
    
    import java.util.HashSet;
    import java.util.Set;
    
    /**
     * @author 公众号:Java半颗糖
     * @desc:
     * @date: 2021/7/24
     */
    public class DemoHashCode {
    
        private int id;
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public Integer getId() {
            return id;
        }
    
        @Override
        public int hashCode() {
            return id % 10;
        }
    
        public static void main(String[] args) {
            DemoHashCode a = new DemoHashCode();
            DemoHashCode b = new DemoHashCode();
            a.setId(1);
            b.setId(1);
            Set<DemoHashCode> set = new HashSet<>();
            set.add(a);
            set.add(b);
            System.out.println(a.hashCode() == b.hashCode());
            System.out.println(a.equals(b));
            System.out.println(set);
    
            /**
             * ----------
             * 运行结果:
             * true
             * false
             * [com.wxw.common.hashcode.DemoHashCode@1, com.wxw.common.hashcode.DemoHashCode@1]
             */
        }
    
    }
    复制代码

    以上这个示例,我们只重写了hashcode() 方法,从上面的结果可以看出,虽然两个对象的hashcode相等,但实际上两个对象并不相等。

    我们没有重写 equals()方法,那么就会调用Object默认的equals()方法,是比较两个对象的引用是不是相同,实际上两个对象的引用肯定是不等的,这里我们将生成的对象放到了HashSet中,而HashSet中只能够存放唯一的对象,也就是相同的(适用于equals方法)的对象只会存放一个,但是这里实际上是两个对象a,b都被放到了HashSet中,这样HashSet就失去了他本身的意义了。 此时我们把equals方法给加上:

    package com.wxw.common.hashcode;
    
    import java.util.HashSet;
    import java.util.Set;
    
    /**
     * @author 公众号:Java半颗糖
     * @desc:
     * @date: 2021/7/24
     */
    public class DemoHashCode {
    
        private int id;
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public Integer getId() {
            return id;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            DemoHashCode that = (DemoHashCode) o;
            return id == that.id;
        }
    
        @Override
        public int hashCode() {
            return id % 10;
        }
    
        public static void main(String[] args) {
            DemoHashCode a = new DemoHashCode();
            DemoHashCode b = new DemoHashCode();
            a.setId(1);
            b.setId(1);
            Set<DemoHashCode> set = new HashSet<>();
            set.add(a);
            set.add(b);
            System.out.println(a.hashCode() == b.hashCode());
            System.out.println(a.equals(b));
            System.out.println(set);
    
            /**
             * ----------
             * 运行结果:
             * true
             * true
             * [com.wxw.common.hashcode.DemoHashCode@1]
             */
        }
    
    }
    复制代码

    从结果我们可以看出,现在两个对象就完全相等了,HashSet中也只存放了一份对象。

    3. hash 冲突

    哈希表的内在行为也带来了相应的问题:即使使用有效的哈希算法,两个或多个对象可能具有相同的哈希码,即使两个对象不相等。因此,即使它们具有不同的散列值,它们的散列码也会指向同一个桶。 这种情况通常被称为散列冲突。

    解决hash冲突的方法,详细分析可以点此处查看:

    • 链表法
    • 开放寻址法

    Java中的hashMap是使用链表法解决hash冲突的

    当两个或多个对象指向同一个存储桶时,它们只是存储在一个链表中。在这种情况下,哈希表是一个链表数组,每个具有相同哈希值的对象都附加到链表中的通索引处。

    在最坏的情况下,几个桶会绑定一个链表,而对链表中对象的检索将是线性执行的。

    处理哈希冲突 简言之,为什么高效地实现 hashCode()如此重要?

    Java8 也为HashMap的实现进行了增强,如果桶大小超过8,节点入超过64,则会转换为红黑树,而不是使用链表,这样当链表太长接近线性查找(复杂度为O(n))时 用红黑树 O(logN) 代替。

    3.1 hashmap和hashcode的联系

    User类中我们重写hashcode方法

    @Data
    public class User {
        private long userId;
        private String userName;
        private String email;
    
        @Override
        public int hashCode() {
            int hash = 7;
            hash = 31 * hash + (int) userId;
            hash = 31 * hash + (userName == null ? 0 : userName.hashCode());
            hash = 31 * hash + (email == null ? 0 : email.hashCode());
            System.out.println("hashCode() called - Computed hash: " + hash);
            return hash;
        }
    
        public User(Long userId, String userName, String email) {
            this.userId = userId;
            this.userName = userName;
            this.email = email;
        }
    }
    复制代码

    应用程序的入口:

    public class DemoHashMap {
    
        public static void main(String[] args) {
            Map<User, User> users = new HashMap<>();
            User user1 = new User(1L, "John", "john@domain.com");
            User user2 = new User(2L, "Jennifer", "jennifer@domain.com");
            User user3 = new User(3L, "Mary", "mary@domain.com");
            users.put(user1, user1);
            users.put(user2, user2);
            users.put(user3, user3);
    
            if (users.containsKey(user1)) {
                System.out.print("User found in the collection");
            }
        }
    }
    复制代码

    在这里,重要的是要注意,每次将对象存储在哈希映射中并使用containsKey() 方法检查时,都会调用hashCode() 并将计算出的哈希码打印到控制台:

    结论

    很明显,生成高效的hashCode() 实现通常需要混合一些数学概念(即素数和任意数)、逻辑和基本数学运算。但是我们也可以有效地实现hashCode(),只需要确保散列算法为不相等的对象生成不同的散列码,并且它与equals()* 的实现一致

    展开全文
  • HashCode原理

    千次阅读 2018-10-31 07:56:58
    HashCode原理 原理 概念: 根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。 作用: 主要是保证基于散列的集合,如HashSet、HashMap以及...

    HashCode原理

    1. 原理
      1. 概念:

    根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值。

      1. 作用:

    主要是保证基于散列的集合,如HashSet、HashMap以及HashTable等,在插入元素时保证元素不可重复,同时为了提高元素的插入删除便利效率而设计;主要是为了查找的便捷性而存在。

      1. 常见类别
    • Integer.hashCode()即对应的int值;故equals相等则相等。
    • String.equals()是根据具体的内容(实际的字符串),通过特定的算法计算出来的
    • Object.hashCode()是通过对应的地址计算。
    1. equals方法和hashCode方法
      1. 在重写equals方法的同时,必须重写hashCode方法
      2. 设计hashCode()原则

    无论何时,对同一个对象调用hashCode()都应该产生同样的值。

    如果两个对象根据equals方法比较是相等的,那么两个对象的hashCode方法返回的整数值必须相等。

    如果两个对象根据equals方法比较是不等的,则hashCode方法不一定得返回不同的整数。

      1. 应用:哈希表

    可以提供快速的插入操作和查找操作。数据的插入删除便利时间复杂度为O(1)

    1. 使用问题
      1. 哈希表中只覆盖equals()情况下,造成元素的重复性和本身设置的不符。

    如在散列表中,当为了使满足某种条件的两个对象相等(例在属性相等则忽略地址均认为属于同一元素)情况下,重写了equsals()方法,而未重写hashCode()方法。但是散列表判断元素是否相同,是先通过hashCode一致后才equals()比较,则会出现bug。即要想保证元素的唯一性,必须同时覆盖hashCode和equals才行。

      1. 内存泄露:

    在哈希表中元素添加之后,不能修改其与hashCode有关的信息(如用户自定义的hashCode()方法,该方法的值和具体的属性有关),防止remove等操作因元素桶的变化而失效的同时,在集合中进行大量的元素添加后修改值再进行remove移除,导致内存泄露。

    qq_38331606
    1. 总结:
    • Hashcode是为了提高元素在哈希表中的插入删除便利效率而设计的
    • 为了保证程序的严谨性,必须同时覆盖hashCode和equals
    • 在哈希表中元素添加之后,不能修改其与hashCode有关的信息,防止remove操作失效,发生内存泄露
    • 如果两个对象根据equals方法比较是相等的,那么两个对象的hashCode方法返回的整数值必须相等。
    1. 哈希算法

    是将数据依特定算法直接指定到一个地址上。

    这样一来,当集合要添加新的元素时,先调用这个元素的HashCode方法,就一下子能定位到它应该放置的物理位置上。

    (1)如果这个位置上没有元素,它就可以直接存储在这个位置上,不用再进行任何比较了;

    (2)如果这个位置上已经有元素了,就调用它的equals方法与新元素进行比较,相同的话就不存了;

    (3)不相同的话,也就是发生了Hash key相同导致冲突的情况,那么就在这个Hash key的地方产生一个链表,将所有产生相同HashCode的对象放到这个单链表上去,串在一起(很少出现)。这样一来实际调用equals方法的次数就大大降低了,几乎只需要一两次。 

     

     

    展开全文
  • 二、Hash算法原理 当Set接收一个元素时根据该对象的内存地址算出hashCode,看它属于哪一个区间,在这个区间里调用equeals方法。 确实提高了效率。但一个面临问题:若两个对象equals相等,但不在一个区间,根本没有...
  • 介绍hashcode和equals是Object类中定义的方法;hashCode 源码:public native int hashCode();equals()源码:public boolean equals(Object obj) {return (this == obj);}从equals源码可以看到 对于Object equals 和...
  • Java自学-集合框架 hashCode原理

    千次阅读 2019-06-01 12:42:36
    Java hashcode原理 步骤 1 : List查找的低效率 假设在List中存放着无重复名称,没有顺序的2000000个Hero 要把名字叫做“hero 1000000”的对象找出来 List的做法是对每一个进行挨个遍历,直到找到名字叫做“hero ...
  •  当一个类有自己特有的“逻辑相等”概念(不同于对象身份的概念)。  2、为什么改写equals()的时候,总是要改写hashCode()  两个原则:  hashCode()的返回值和equals()的关系如下:  如果x.equals(y)...
  • public boolean equals(Object obj)public int hashCode()这两个方法最开发者来说是十分重要的,必须清楚的理解,但实际上,甚至很多经验丰富的Java开发者有时候也没有真正搞清楚这两个方法的使用和原理。...
  • (1)HashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,HashCode经常用于确定对象的存储地址; (2)如果两个对象相同, equals方法一定返回true,并且这两个对象HashCode一定相同; (3)两个...
  • HashCode重写原理

    2018-05-21 15:49:00
    例如对象 String str1 = “aa”, str1.hashCode= 3104String str2 = “bb”, str2.hashCode= 3106String str3 = “aa”, str3.hashCode= 3104根据HashCode由此可得出str1!=str2,str1==str3下面给出几个常用的哈希码...
  • Java中的hashCode的计算方法与原理

    千次阅读 2020-05-03 17:08:13
    在Java中,每个对象都有一个从Object基类派生出的 hashCode() 方法,用于根据当前对象的某些特征返回一个整型变量。其核心源代码中有个奇怪的数字31,本文就计算公式和取这个数字的含义进行详细的说明。
  • 如果发生了碰撞,也就是说有两个对象的key 的hashcode值相等,那么则需要通过key的equals方法判断这两个对象是否是同一个对象,如果是,那么原本存 储的旧值会被新值所替换;如果不是同一个对象,则把新的键值对对象...
  • 同时我们也知道,无论何时调用同一对象hashCode方法,都必须返回相同的值,也就是说一个对象hashCode值要在生命周期中保持不变。同时,网传“hashCode是根据对象地址生成的”。那么,问题来了,当对象地址变化了...
  • hashCodehashCode是jdk根据对象的地址或者字符串或者数字算出来的int类型的数值。public int hashCode()返回该对象的哈希码值。支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。理解:...
  • 由于String类对hashCode()和equals(Object)方法进行了重写而String类又是一个被final修饰的类,所以无法继承该类进行进一步的自定义功能开发,因此了解其内部工作的原理是十分必要的。
  • 写在前面 除了需要掌握集合的基本使用,还需要对Java底层了解的深一点,对我们用好这门语言更有利。...集合存放的对象增删操作需要设计重写hashCode ,否则导致元素删除失败 开始 一、hashCode属性 ...
  • (1)HashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,HashCode经常用于确定对象的存储地址; (2)如果两个对象相同, equals方法一定返回true,并且这两个对象HashCode一定相同; (3)两个...
  • Java中的HashCode 1 之hash算法基本原理

    千次阅读 2018-11-09 10:17:04
    Java中的HashCode 1 之hash算法基本原理
  • 目录hashcode原理比较器ComparatorComparable聚合操作 hashcode原理 List的查找效率低下 HashMap的查找效率好,几乎不花时间。类似平时查字典,先找目录找到多少页,然后直接翻到对应的页码就好了,而这个页码...
  • HashSet和HashMap一直都是JDK中最常用的两个类,HashSet要求不能存储相同的对象,HashMap要求不能存储相同的键。  那么Java运行时环境是...在研究这个问题之前,首先说明一下JDK对equals(Object obj)和hashcode()这
  • 两个对象不相同,hashcode可能相同

    千次阅读 2018-06-11 15:17:46
    HashSet和HashMap一直都是JDK中最常用的两个类,HashSet要求不能存储相同的对象,HashMap要求不能存储相同的键。... 在研究这个问题之前,首先说明一下JDK对equals(Object obj)和hashcode()这两个方法的定...
  • Hash表数据结构常识: 哈希表基于数组。 缺点:基于数组的,数组创建后难以扩展。某些哈希表被基本填满时,性能下降得非常严重。...一个对象HashCode就是一个简单的Hash算法的实现,虽然它和那...
  • 2 如果两个对象hashCode相同,它们并不一定相同,这里的对象相同指的是用eqauls方法比较。     三、例子   1 没有重写hashCode和equals的方法  package cn.xy.test; ...
  • hashCode和内存地址关系 1.当我们没有重写hashCode方法的时候默认的哈希值是内存地址是永远不相同的 Student s=new Student(); Student a=new Student(); System.out.println(s.hashCode());//2018699554 System...
  • HashSet储存对象时重写equals和hashcode方法时的情景分析Set 接口的特点:hashCode() 与 equals()两种情形情形一示例:情形二示例:总结 Set 接口的特点: 1.它不允许出现重复元素-----------无重复 2.不保证...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 73,693
精华内容 29,477
关键字:

对象的hashcode原理