`

HashMap的工作原理及实现

 
阅读更多

HashMap的工作原理

        HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。我们通过put()和get()方法储存和获取对象。当我们将键值对传递给put()方法时,它调用键对象的hashCode()方法来计算hashcode,然后找到bucket位置来储存值对象。当获取对象时,通过键对象的equals()方法找到正确的键值对,然后返回值对象。HashMap使用LinkedList来解决碰撞问题,当发生碰撞了,对象将会储存在LinkedList的下一个节点中。HashMap在每个LinkedList节点中储存键值对对象。

       当两个不同的键对象的hashcode相同时会发生什么?它化会储存在同一个bucket位置的LinkedList中。键对象的equals()方法用来找到键值对。

 

Java实现:

    1.Node节点类:

class Node<K, V> {
    private final K key;
    private V value;
    private Node<K, V> next;

    public Node(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public V getValue() {
        return value;
    }

    public void setValue(V value) {
        this.value = value;
    }

    public Node<K, V> getNext() {
        return next;
    }

    public void setNext(Node<K, V> next) {
        this.next = next;
    }

    public K getKey() {
        return key;
    }
}

   2.HashMap<K,V>实现类

public class HashMap<K, V> {
    private static int DEFAULT_CAPACITY = 16;
    private static double A = (Math.pow(5, 0.5) - 1) / 2;

    private int capacity;
    private int size = 0;

    private Node<K, V>[] buckets;

    public HashMap() {
        this(DEFAULT_CAPACITY);
    }

    @SuppressWarnings("unchecked")
    public HashMap(int capacity) {
        if (capacity <= 0) {
            throw new IllegalArgumentException(
                    "capacity can not be negative or zero");
        }

        // 保证 capacity 是2的n次方
int temp = 1;
        while (temp < capacity) {
            temp <<= 2;
        }
        this.capacity = temp;

        buckets = new Node[this.capacity];
    }

    public void insert(K key, V value) {
        if (key == null) {
            throw new IllegalArgumentException("key can not be null");
        }

        int position = index(key);

        Node<K, V> node = new Node<K, V>(key, value);
        if (buckets[position] != null) {
            node.setNext(buckets[position]);
        }

        buckets[position] = node;
        size++;
    }

    public void put(K key, V value) {
        if (key == null) {
            throw new IllegalArgumentException("key can not be null");
        }

        int position = index(key);

        Node<K, V> node = buckets[position];

        while (node != null) {
            if (node.key.equals(key)) {
                node.value = value;
                return;
            }

            node = node.next;
        }

        Node<K, V> newNode = new Node<K, V>(key, value);
        if (buckets[position] != null) {
            newNode.setNext(buckets[position]);
        }

        buckets[position] = newNode;
        size++;
    }

    public void delete(K key) {
        if (key == null) {
            throw new IllegalArgumentException("key can not be null");
        }

        int position = index(key);
        Node<K, V> node = buckets[position];

        if (node == null) {
            return;
        }

        if (node.key.equals(key)) {
            buckets[position] = node.next;
            size--;
        }

        while (node.next != null) {
            if (node.next.key.equals(key)) {
                node.next = node.next.next;
                size--;
                break;
            }

            node = node.next;
        }
    }

    public V search(K key) {
        if (key == null) {
            throw new IllegalArgumentException("key can not be null");
        }

        int position = index(key);
        Node<K, V> node = buckets[position];

        while (node != null) {
            if (node.key.equals(key)) {
                return node.value;
            }

            node = node.next;
        }

        return null;
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size == 0;
    }

    @Override
public String toString() {
        StringBuffer buffer = new StringBuffer();
        buffer.append("{");

        for (int i = 0; i < capacity; i++) {
            Node<K, V> node = buckets[i];
            while (node != null) {
                buffer.append(node.key + ":" + node.value + ", ");
                node = node.next;
            }
        }

        if (buffer.length() > 1) {
            buffer.delete(buffer.length() - 2, buffer.length());
        }

        buffer.append("}");

        return buffer.toString();
    }

    private int index(K key) {
        int hashCode = key.hashCode();

        double temp = hashCode * A;
        double digit = temp - Math.floor(temp);

        return (int) Math.floor(digit * capacity);
    }

   public static void main(String[] args) {
        HashMap<String, String> map = new HashMap<String, String>();
        map.put("001","apple");
        map.put("002","orange");
        map.put("003","banana");
        map.put("004","grape");
                System.out.println(map);
        System.out.println(map.size());
        System.out.println(map.search("004"));
   }
}
分享到:
评论

相关推荐

    hashmap实现原理

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

    HashMap底层原理.md

    HashMap底层原理.md

    java HashMap原理分析

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

    hashmap实现原理.pdf

    hashmap实现原理.pdf

    深入Java集合学习系列:HashMap的实现原理

    在Java编程语言中,集合框架是开发者日常工作中不可或缺的一部分,HashMap作为其中的重要成员,它的实现原理对于理解Java性能优化和数据结构有深远的意义。HashMap是一个基于哈希表的数据结构,它实现了Map接口,...

    HashMap底层原理

    HashMap的底层原理主要依赖于哈希表,这是一种数据结构,它通过计算键的哈希码来实现高效的查找操作。 在HashMap中,每个元素都是一个键值对,存储在一个Entry对象中。当向HashMap添加键值对时,首先会计算键的哈希...

    基于HashMap的用户标签处理兼Java中HashMap实现原理研究.pdf

    "基于HashMap的用户标签处理兼Java中HashMap实现原理研究" 本文研究了基于HashMap的用户标签处理方法,并对Java中HashMap的实现原理进行了深入研究。HashMap是一种高效的数据结构,可以快速地存储和检索数据。本文...

    HashMap的实现原理

    ### HashMap的实现原理 #### 1. HashMap概述 HashMap 是 Java 集合框架中一个非常重要的类,它实现了 Map 接口,并提供了基于哈希表的存储方式。与其它 Map 实现不同的是,HashMap 允许使用 `null` 键和 `null` 值...

    Jdk1.8中的HashMap实现原理.docx

    《Jdk1.8中的HashMap实现原理》 HashMap作为Java编程语言中常用的数据结构,它在Jdk1.8中的实现结合了哈希表、链表以及红黑树的特性,提供高效且灵活的键值对存储功能。本文将深入探讨HashMap的内部结构、工作原理...

    HashMap的工作原理Java开发Java经验技巧共4页

    深入理解HashMap的工作原理对于提升Java开发的效率和写出高效的代码至关重要。以下是对HashMap工作原理的详细解析。 HashMap基于哈希表(也称为散列表)实现,它的核心思想是通过对象的哈希值来快速定位数据。当向...

    HashMap底层原理.pdf

    HashMap是Java中非常常见的一种数据结构,主要用于存储键值对,其核心原理是通过哈希算法将键映射到数组中的位置来实现快速访问。本文将详细介绍HashMap的底层原理,包括其内部实现结构、关键字段的作用、以及JDK ...

    hashMap基本原理,内存知识

    HashMap 的底层实现原理可以分为两部分:数组 + 链表(jdk 1.7)和数组 + 链表/红黑树(jdk 1.8)。在jdk 1.7中,HashMap 使用数组 + 链表的结构来存储数据,而在 jdk 1.8 中,当链表的长度超过 8 个时,会将链表...

    一线大厂BATJ面试题讲解-hashmap原理实现

    一线大厂BATJ面试题讲解-hashmap原理实现

    Jdk1.8中的HashMap实现原理.pdf

    总结起来,JDK1.8中的HashMap实现原理主要包括以下几个要点: 1. 链表散列结构:数组+链表,链表用于处理哈希碰撞。 2. 红黑树优化:当链表长度超过8时,转换为红黑树,减少查找、插入和删除的时间复杂度。 3. 内部...

    HashMap底层实现原理共6页.pdf.zip

    《HashMap底层实现原理》 HashMap是Java编程语言中一个非常重要的数据结构,它在实际开发中被广泛应用。HashMap提供了一种高效、灵活的方式来存储和检索键值对数据,它的核心特性是快速查找,通常时间复杂度为O(1)...

    HashMap原理.rar

    HashMap是Java编程语言中最常用的集合类之一,它属于`java.util`包,提供了一种以键值对形式存储数据的数据结构。HashMap的核心在于其高效的数据查找、...阅读“HashMap原理.pdf”文件,可以获得更深入的细节和示例。

    hashmap原理和扩容.docx

    #### 一、HashMap的基本工作原理 HashMap是Java集合框架中的一个重要组成部分,它实现了Map接口,并提供了基于哈希表的数据结构。HashMap的主要功能包括存储和检索键值对,其中键(key)是唯一的,而值(value)...

    HashMap原理.docx

    ### HashMap原理详解 #### 一、HashMap简介与应用场景 HashMap是Java集合框架中一个非常重要的组成部分,它提供了基于键值对(key-value)映射的高效数据存储方式。由于其内部采用了数组加链表(以及红黑树优化)的...

Global site tag (gtag.js) - Google Analytics