java编程进阶小白也能手写HashMap代码

Java编程进阶:小白也能手写HashMap代码

前言

HashMap 是 Java 中常用的数据结构之一,它可以用于键值对存储和快速查找。虽然 Java 提供了 HashMap 的实现,但是手写 HashMap 算是 Java 编程基本功之一。本文将向大家介绍手写 HashMap 的完整攻略。

原理概述

Java 中 HashMap 是由数组和链表构成的,其主要原理是将 key 的 hashCode 计算出数组下标,如果该位置没有元素则直接插入,如果该位置已经有元素,则用链表的形式同步保存新的元素。

代码实现

下面我们来实现一个简单的 HashMap,代码清晰易懂。


public class MyHashMap<K, V> {

    private static final int INIT_CAPACITY = 16;

    private static final float LOAD_FACTOR = 0.75f;

    private int size;

    private int threshold;

    private Entry<K, V>[] table;

    public MyHashMap() {
        table = new Entry[INIT_CAPACITY];
        threshold = (int) (INIT_CAPACITY * LOAD_FACTOR);
    }

    static class Entry<K, V> {
        K key;
        V value;
        Entry<K, V> next;

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

    public void put(K key, V value) {
        int hash = hash(key);
        int i = indexFor(hash, table.length);
        for (Entry<K, V> e = table[i]; e != null; e = e.next) {
            if (e.key.equals(key)) {
                e.value = value;
                return;
            }
        }
        addEntry(key, value, hash, i);
    }

    public V get(K key) {
        int hash = hash(key);
        int i = indexFor(hash, table.length);
        for (Entry<K, V> e = table[i]; e != null; e = e.next) {
            if (e.key.equals(key)) {
                return e.value;
            }
        }
        return null;
    }

    private int indexFor(int h, int length) {
        return h & (length - 1);
    }

    private int hash(K key) {
        return key.hashCode();
    }

    private void addEntry(K key, V value, int hash, int bucketIndex) {
        Entry<K, V> e = table[bucketIndex];
        table[bucketIndex] = new Entry<>(key, value);
        table[bucketIndex].next = e;
        size++;
        if (size >= threshold) {
            resize(table.length * 2);
        }
    }

    private void resize(int newCapacity) {
        Entry<K, V>[] oldTable = table;
        int oldCapacity = oldTable.length;
        if (oldCapacity >= 1 << 30) {
            threshold = Integer.MAX_VALUE;
            return;
        }
        Entry<K, V>[] newTable = new Entry[newCapacity];
        transfer(newTable);
        table = newTable;
        threshold = (int) (newCapacity * LOAD_FACTOR);
    }

    @SuppressWarnings("unchecked")
    private void transfer(Entry<K, V>[] newTable) {
        Entry<K, V>[] src = table;
        int newCapacity = newTable.length;
        for (int j = 0; j < src.length; j++) {
            Entry<K, V> e = src[j];
            if (e != null) {
                src[j] = null;
                do {
                    Entry<K, V> next = e.next;
                    int i = indexFor(e.key.hashCode(), newCapacity);
                    e.next = newTable[i];
                    newTable[i] = e;
                    e = next;
                } while (e != null);
            }
        }
    }
}

示例说明

下面我们利用前面的 HashMap 实现,进行两个操作进行说明:

  1. 存放一个键为"name", 值为"张三"的元素
  2. 根据 key "name" 获取相应的值

public class Test {
    public static void main(String[] args) {
        MyHashMap<String, String> map = new MyHashMap<>();
        map.put("name", "张三");
        String name = map.get("name");
        System.out.println(name); // 输出"张三"
    }
}

总结

手动实现 HashMap 需要对 HashMap 的实现原理熟悉,以及对数组和链表处理的掌握,本文大概介绍了 HashMap 的实现原理,并提供了一个 Java 实现示例供大家导入使用或对其进行学习、修改等操作。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:java编程进阶小白也能手写HashMap代码 - Python技术站

(0)
上一篇 2023年5月26日
下一篇 2023年5月26日

相关文章

  • Spring Native打包本地镜像的操作方法(无需通过Graal的maven插件buildtools)

    Spring Native打包本地镜像的操作方法 简介 Spring Native是Spring团队推出的一款可以将Java代码编译成本地可执行二进制文件的工具,在性能、启动速度等方面拥有很大的优势。本文主要介绍如何使用Spring Native将Java应用打包成本地镜像。 环境准备 在开始之前,需要确保以下工具已经安装好并配置: Docker Java …

    Java 2023年6月2日
    00
  • Redis 集成Spring的示例代码(spring-data-redis)

    下面是有关Redis集成Spring的完整攻略 1. 前置条件 在使用Spring集成Redis的过程中,需要确保以下条件:- 已经安装并配置好Redis数据库- 已经熟悉Spring的基本操作 2. 导入依赖 在 Spring 项目中,我们需要添加支持 Redis 的依赖 spring-data-redis 。 这里我们使用 Maven 管理工具进行相关依…

    Java 2023年5月20日
    00
  • java查找字符串中的包含子字符串的个数实现代码

    下面是“Java查找字符串中的包含子字符串的个数实现代码”的完整攻略。 问题描述 我们需要写一个Java程序,用于在一个字符串中查找指定的子字符串,并返回该子字符串在源字符串中出现的次数。 解决方案 我们可以使用Java内置的字符串函数或正则表达式来实现这个功能,下面是两种不同的方法: 方法一:使用String函数 我们可以使用String类中提供的inde…

    Java 2023年5月27日
    00
  • Spark Streaming算子开发实例

    下面我将详细讲解“Spark Streaming算子开发实例”的完整攻略。 算子开发实例 1. 算子函数定义 首先,我们需要定义一个算子函数,其输入参数为RDD类型,输出参数为RDD类型。 def applyFunction(rdd: RDD[String]): RDD[String] = { rdd.flatMap(line => line.spli…

    Java 2023年5月20日
    00
  • SpringMVC执行步骤、Model的使用详解

    以下是关于“SpringMVC执行步骤、Model的使用详解”的完整攻略,其中包含两个示例。 1. 前言 SpringMVC是一种常用的Java Web开发框架,它可以帮助开发者快速构建Web应用程序。本攻略将详细讲解SpringMVC的执行步骤和Model的使用方法,帮助读者更好地掌握SpringMVC框架的使用方法。 2. SpringMVC的执行步骤 …

    Java 2023年5月16日
    00
  • Spring Boot使用Servlet及Filter过程详解

    下面是详细的讲解“Spring Boot使用 Servlet 及 Filter 过程详解”的完整攻略。 什么是 Servlet 及 Filter Servlet 是一种 Web 组件,用于处理浏览器发来的请求和响应相应结果。 Filter 是另一种 Web 组件,用于在 Servlet 处理请求之前或之后对请求进行拦截和处理。 Spring Boot 中使用…

    Java 2023年5月20日
    00
  • 这是我的战争前期前五天玩法介绍

    我的战争前期前五天玩法介绍 在《我的战争》游戏中,前期的五天非常关键,这里提供一些玩家可以使用的策略来存活和发展。 1. 初期资源的获取 在游戏的开始,资源非常有限,但是这并不意味着你不能快速发展。第一天,最重要的任务是保持活下来,建立一个可以保护你的基地。最好的方法是寻找资源点并获得最初的几个资源,例如金属和木材,而不是在第一天建造建筑。 2. 建立初期的…

    Java 2023年6月16日
    00
  • Eclipse快捷键 推荐10个最有用的快捷键

    下面是Eclipse快捷键的完整攻略: 1. 常用快捷键 在Eclipse中,一些常用的快捷键包括: Ctrl + S:保存当前文件 Ctrl + C、Ctrl + X、Ctrl + V:复制、剪切、粘贴 Ctrl + Z、Ctrl + Y:撤销、重做 Ctrl + F:查找 Ctrl + Shift + R:查找某个文件并打开 2. 推荐使用的快捷键 除了…

    Java 2023年6月15日
    00
合作推广
合作推广
分享本页
返回顶部