`

hashcode()方法 及 HashMap再分析

 
阅读更多

   之前 , 听过很多次,重写equals()方法的时候,必须重写hashcode() ,

   两个对象equals,hashcode()必然相等,两个对象hash值相等,当时不一定equals;

   那么 究竟hashcode 是什么?起的作用又是什么?

   hashcode() 和 equals() 方法都是Object(终极父类)中的方法;

   如果子类 没有重写 , 那么就默认的调用父类中的方法;

 

   Object 中的hashcode方法是通过本地方法实现的,并不是通过Java语言

public native int hashCode(); 
//This is typically implemented by converting the internal address of the object into an integer
//通过把对象的地址空间转换成一个整数实现的

   String 中的hashcode() :

 public int hashCode() {
        int h = hash;
// value 是 字符数组,字符串是一个字符数组构成的
        if (h == 0 && value.length > 0) {
            char val[] = value;
//散列公式: s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

 

   hashcode的作用就体现在构建hashMap , hashtable 这种集合的时候;

   它们首先会根据对象hash值,找到相对应的数组下标,进行比较 , 插入和读取;

  如下面的hashmap中的get(Object key) 方法: 

 public V get(Object key) {
        if (key == null)
            return getForNullKey();
//hashmap通过拉链法处理冲突的,Entry是链表节点类型
        Entry<K,V> entry = getEntry(key); 
        return null == entry ? null : entry.getValue();
    }

 

final Entry<K,V> getEntry(Object key) {
        if (size == 0) {
            return null;
        }
// 看,这一步获取该key的hash值,hash(key)方法就调用key的hashcode方法
//所以,为什么我们自定义的类型做key都要重写hashcode方法,下面会告诉你
//为什么要重写equals()方法
        int hash = (key == null) ? 0 : hash(key);
// 根据hash值找到index , 然后就是遍历链表
        for (Entry<K,V> e = table[indexFor(hash, table.length)];
             e != null;
             e = e.next) {
            Object k;
//这里不就说明为什么要重写equals吗
            if (e.hash == hash &&
                ((k = e.key) == key || (key != null && key.equals(k))))
                return e;
        }
        return null;
    }

 

 final int hash(Object k) {
        int h = hashSeed;
        if (0 != h && k instanceof String) {
            return sun.misc.Hashing.stringHash32((String) k);
        }
     //这里不就是根据key的hashcode来生成相应的hash值
        h ^= k.hashCode();

        // This function ensures that hashCodes that differ only by
        // constant multiples at each bit position have a bounded
        // number of collisions (approximately 8 at default load factor).
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }

 关于HashMap的扩容?

  

void resize(int newCapacity) { 
        Entry[] oldTable = table;
        int oldCapacity = oldTable.length;
        if (oldCapacity == MAXIMUM_CAPACITY) {
            threshold = Integer.MAX_VALUE;
            return;
        }
//新建一个新数组将容量扩大两倍
        Entry[] newTable = new Entry[newCapacity];
// 接下来就是怎样把原来数组的中的元素放入新数组中!       
        transfer(newTable, initHashSeedAsNeeded(newCapacity));
        table = newTable;
       threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1);
    }

    /**
     * Transfers all entries from current table to newTable.
     */
    void transfer(Entry[] newTable, boolean rehash) {
        int newCapacity = newTable.length;
//对链表数组中的每个元素
        for (Entry<K,V> e : table) { 
//对链表中的每个元素
            while(null != e) {
                Entry<K,V> next = e.next;
                if (rehash) {
//对key可能要再次hash!!!
                    e.hash = null == e.key ? 0 : hash(e.key);
                }
//根据e的hash值与数组的容量求的索引的位置!
                int i = indexFor(e.hash, newCapacity);
// 这一步的意思就是 前面可能有元素在i位置了,那么就把i位置的元素加在他后面!
                e.next = newTable[i]; 
                newTable[i] = e;
                e = next;
            }
        }
    }

 

分享到:
评论

相关推荐

    深入 HashCode 方法~

    ### 深入理解 HashCode 方法 #### 一、HashCode 的基本概念与作用 在 Java 编程语言中,`HashCode` 是一个非常重要且基础的概念。简单来说,`HashCode` 是一个整数值,用于快速定位对象的位置。在 Java 中,每一个...

    java HashMap原理分析

    Java HashMap原理分析 Java HashMap是一种基于哈希表的数据结构,它的存储原理是通过将Key-Value对存储在一个数组中,每个数组元素是一个链表,链表中的每个元素是一个Entry对象,Entry对象包含了Key、Value和指向...

    equals与hashCode方法讲解

    在 HashMap 的 Node 类中,hashCode 方法的实现是根据键值对的键和值来计算哈希码。 public final int hashCode() { return Objects.hashCode(key) ^ Objects.hashCode(value); } equals 方法和 hashCode 方法都...

    重写equals和hashcode方法_equals_重写equals和hashcode方法_

    在Java编程语言中,`equals()` 和 `hashCode()` 方法是Object类中的两个核心方法,所有类都默认继承自Object类。这两个方法在处理对象比较和集合操作时起着至关重要的作用。当我们创建自定义类并需要对对象进行精确...

    关于Object中equals方法和hashCode方法判断的分析

    "关于Object中equals方法和hashCode方法判断的分析" 在 Java 中,Object 类提供了两个重要的方法:equals 方法和 hashCode 方法。这两个方法都是用于比较两个对象是否相等的,但它们的实现机理和作用域却有所不同。...

    hashmap实现原理

    在深入探讨HashMap的实现原理之前,我们需要了解两个关键的接口方法:`hashCode()`和`equals()`。 根据《Effective JAVA》的建议,当重写`equals()`方法时,也应重写`hashCode()`方法。这是因为在HashMap中,`...

    深入HashCode方法

    HashCode方法在Java编程中扮演着至关重要的角色,尤其是在涉及对象存储和查找效率的数据结构,如HashMap和Hashtable中。一个对象的HashCode是一个简单的哈希算法实现,尽管它相对复杂的哈希算法而言较为简单,但其...

    面试必考之HashMap源码分析与实现

    插入HashMap的对象必须正确实现`equals()`和`hashCode()`方法,以确保键的比较和哈希计算符合预期。这两个方法的实现对于HashMap的正确性和效率至关重要。 8. **常用方法** - `put(K key, V value)`: 插入键值对...

    java中hashcode()和equals()方法详解

    ### Java中`hashCode()`与`equals()`方法详解 #### 前言 在Java编程语言中,`hashCode()`和`equals()`方法是非常重要的概念,它们不仅对于深入理解Java内存管理至关重要,也是实现自定义类的关键部分之一。本文将...

    Java理论与实践:hashCode()和equals()方法

    本文介绍了Java语言不直接支持关联数组,可以使用任何对象作为一个索引的数组,但在根Object类中使用 hashCode()方法明确表示期望广泛使用HashMap。理想情况下基于散列的容器提供有效插入和有效检索;直接在对象模式...

    HashCode的用法详解

    * 在 HashMap 中,hashCode 用于确定键的存储地址。 * 在排序算法中,hashCode 用于快速定位到目标对象。 equals() 和 hashCode() 的关系 equals() 和 hashCode() 是两个相关的概念。equals() 用于判断两个对象...

    深入理解Java中HashCode方法

    例如,在HashMap中,key的hashCode值将被用来确定其在表中的索引位置。如果两个对象的hashCode值相同,但它们不是同一个对象,那么它们将被存储在同一个索引位置上,这将导致严重的问题。 因此,在Java中,hashCode...

    HashMap之put方法源码解读.docx

    在本文中,我们将对 HashMap 的 put 方法的源码进行详细解读,分析put 方法源码中的内在逻辑关系,欣赏源码独特之美,从中学习更为精致的编程思维。 首先,让我们看一下 put 方法的源码: ```java public V put(K ...

    java中Hashcode的作用.docx

    在Java中的散列表(如HashMap、HashSet等)中,Hashcode扮演着关键角色。它可以快速地判断两个对象是否相等,从而提高散列表的性能。 证明Hashcode不是内存地址 有人认为Hashcode是对象在内存中的地址,但这是一种...

    hashcode的作用

    在Java中,`hashCode()` 方法是 `Object` 类的一个重要成员方法,它返回一个整数,这个整数通常用来表示对象的哈希值。哈希值在Java集合框架中扮演着至关重要的角色,尤其是在散列表(如 `HashMap` 和 `Hashtable`)...

    hashmap面试题_hashmap_

    面试中,可能会被问及HashMap的性能优化、内存占用分析、以及在特定场景下的选择,如并发环境、内存敏感的应用等。 总结,HashMap是Java编程中的基础工具,掌握其工作原理和常见面试题,不仅能帮助我们应对面试,更...

    Java基础加强_ArrayList_HashSet的比较及Hashcode分析

    在自定义类中,为了使对象能被HashSet或HashMap正确处理,通常需要重写hashCode()和equals()方法,确保它们遵循一致性原则。 在ArrayList和HashSet的比较中,我们可以总结以下几点: 1. 数据结构:ArrayList基于...

    hashcode使用方法

    - **集合框架**:在 `HashSet`, `HashMap`, `Hashtable` 等集合中,`hashCode` 方法用于快速查找和存储对象。 - **缓存机制**:在缓存中,`hashCode` 和 `equals` 方法一起用于识别缓存项,以便在需要时快速找到它们...

    Hashmap详解

    put 方法是 HashMap 中最重要的方法之一,它负责将键值对添加到 HashMap 中。put 方法的实现可以分为以下几个步骤: 1. 首先,根据键的 hashCode 值计算 Hash 码,Hash 码是用于确定键值对在数组中的索引。 2. 然后...

Global site tag (gtag.js) - Google Analytics