从零开始实现一个HashMap

本文将逐步介绍HashMap的实现过程,从仅使用数组存储开始,到引入链表处理哈希冲突,最后讨论数组的扩容策略,以确保高效的数据存储和检索。通过优化哈希值计算和数组下标索引,解决哈希冲突并实现动态扩容,全面理解HashMap的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

将会从简单到复杂,一步步地实现跟源码一样的HashMap

一:仅使用数组存储

/** 
 * 一:数组
 * 二:数组 + 链表
 * 三:数组 + 链表 + resize
 * 四:数组 + 链表 + 二叉搜索树
 * 五:数组 + 链表 + 红黑树
 */
public class HashMap_my<K,V> {
   
   
    /**
     *  官方源码数组长度默认为16,此处为4,总之为2的N次方就好
     */
    Node<K,V>[] elementDate = new Node[4];

    class Node<K,V> {
   
   
        int hash;
        K key;
        V value;

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

    public void put(K key,V value) {
   
   
        int hash = key.hashCode();
        /**
         * 因为还没使用链表,此处Node还没next属性
         */
        final Node<K, V> newNode = new Node<>(hash, key, value);
        /** 
         * 有两种计算索引的方式:
 		 * 1、int index = hash & (elementDate.length - 1)
 		 * 2、int index = hash % elementDate.length
 		 * 当length为2的N次方时,1跟2计算结果是一样的,此处可自行查阅验证
 		 */
        int index = hash % elementDate.length;
        elementDate[index] = newNode;
    }

    public V get(K key) {
   
   
        int hash = key.hashCode();
        int index = hash % elementDate.length;
        return elementDate[index].value;
    }

    public static void main(String[] args) {
   
   
        final HashMap_my<Object, Object> hashMap = new HashMap_my<>();
        hashMap.put("k1","v1");
        hashMap.put("k2","v2");
        System.out.println(hashMap.get("k1")); // v1
        System.out.println(hashMap.get("k2")); // v2
    }
}

下面我要对上面代码进行两个优化:
优化1:求hash值
优化2:计算数组下标索引

public class HashMap_my<K,V> {
   
   
    
    Node<K,V>[] elementDate = new Node[4];

    class Node<K,V> {
   
   
        int hash;
        K key;
        V value;

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

    public void put(K key,V value) {
   
   
    	/**
    	 * 一个int有4字节32位,
    	 * 此处是将hashCode的高16位跟低16位进行异或组成新的低16位,高16位不变
    	 */
        int hash = key.hashCode() ^ (key.hashCode() >>> 16);
        final Node<K, V> newNode = new Node<>(hash, key, value);
        /**
         * hash & (elementDate.length - 1) 与 hash % elementDate.length
 		 * 当length为2的N次方时,1跟2计算结果是一样的
         */
        int index = hash & (elementDate.length -
<think>我们被要求生成一个关于Java编程语言基础教程的回答,并生成相关问题。 根据引用内容,我们可以整合以下信息: 引用[1]:Java基础教程,包括环境配置、编写和运行Java程序、基本语法和面向对象编程。 引用[2]和[3]:提供了Java学习路线,包括集合、IO流、线程、反射机制、注解等,但用户目前只需要基础知识。 引用[4]:从零开始Java,包括认识Java。 因此,我们可以将Java基础知识学习分为以下几个步骤: 1. 认识Java和配置环境 2. 基本语法(变量、数据类型、运算符、控制流程等) 3. 面向对象编程(类、对象、继承、多态、接口、抽象类等) 4. 异常处理 5. 数组和常用类 注意:用户要求从零开始,所以我们要从最基础的开始。 回答结构: 1. 引言:介绍Java和为什么学习Java 2. 学习步骤:分步骤讲解,每个步骤给出关键点 3. 示例代码:展示一个简单的Java程序 4. 学习资源:可以提及参考的教程(根据引用) 然后,按照要求生成相关问题。 注意:引用标识要自然地添加在引用内容的末尾。由于我们的引用是来自给定的参考,我们可以在提及这些资源时添加引用标识。 另外,根据系统指令,数学表达式用$...$,但本问题中可能较少涉及数学表达式,但如果有,要遵守规则。独立公式用$$...$$。这里可能用不到,但要注意。 由于是中文回答,所以整个回答使用中文。 开始构建回答:</think>### Java编程语言基础教程:从零开始学习 #### 1. Java概述与环境配置 Java是一种面向对象、跨平台的编程语言,广泛应用于企业级开发、移动应用(Android)和大数据领域。学习路径如下: - **环境搭建**:安装JDK(Java Development Kit),配置环境变量(JAVA_HOME和PATH) - **开发工具**:推荐使用IntelliJ IDEA或Eclipse - **第一个程序**: ```java public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, Java!"); } } ``` 编译运行:`javac HelloWorld.java` → `java HelloWorld`[^4] #### 2. 核心语法基础 | 知识点 | 说明 | 示例 | |--------------|-----------------------|--------------------------| | 变量与数据类型 | 8种基本类型+引用类型 | `int age = 25;` | | 运算符 | 算术/关系/逻辑运算 | `boolean flag = (a > b) && (c != 0);` | | 控制语句 | if-else/for/while | `for(int i=0; i<10; i++){...}` | | 数组 | 定长容器 | `int[] arr = new int[5];` | #### 3. 面向对象编程(OOP) - **类与对象**:类是蓝图,对象是实例 ```java class Person { String name; void speak() { System.out.println("I'm " + name); } } // 创建对象 Person p = new Person(); p.name = "Alice"; p.speak(); ``` - **四大特性**: - **封装**:通过private属性和getter/setter控制访问 - **继承**:`class Student extends Person` - **多态**:父类引用指向子类对象 - **抽象**:抽象类(abstract class)与接口(interface) #### 4. 进阶必备知识 - **异常处理**:try-catch-finally机制 ```java try { int result = 10 / 0; } catch (ArithmeticException e) { System.out.println("除零错误"); } ``` - **常用类库**: - String/StringBuilder处理字符串 - ArrayList/HashMap等集合类 - Math、Date等工具类 #### 5. 学习资源推荐 1. 官方Oracle Java教程(英文) 2. [Java零基础从入门到精通系列文档](引用[3]) 3. 配套视频教程(B站搜索"Java零基础") > **关键建议**:每天坚持编码练习,从控制台程序开始,逐步实现小项目(如计算器、学生管理系统)[^1][^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值