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日

相关文章

  • java处理日期的工具类DateUtil

    Java日期处理工具类DateUtil Java中处理日期时间是非常常见的需求,使用Java默认的Date类虽然可以实现,但是其API使用起来不太友好,我们往往需要借助一些工具类来辅助我们处理日期时间。DateUtil是一款常见的日期处理工具类,它封装了很多常用的方法,可以用于日期的计算、格式化、解析等操作,非常方便实用。 导入DateUtil 在使用Dat…

    Java 2023年5月20日
    00
  • java网上图书商城(9)支付模块

    以下是关于“java网上图书商城(9)支付模块”的完整攻略。 一、支付模块的作用 支付模块是电商网站中不可或缺的重要组成部分,通过对不同的支付方式的集成,使得用户可以方便地完成订单的支付。在该网上图书商城项目中,通过集成支付宝接口,并编写相关代码,实现了用户对订单进行在线支付。 二、支付模块的基本流程 支付模块的基本流程如下: 用户选定商品并提交订单。 系统…

    Java 2023年6月15日
    00
  • 详解JAVA中获取文件MD5值的四种方法

    下面是“详解JAVA中获取文件MD5值的四种方法”的攻略: 1. 使用Java内置的MessageDigest类获取MD5值 Java语言提供了一个DigestMessage类,它可以将任意长度的数据转换成定长的数据,如将任意长度的文件转换成128位(16个字节)的MD5值。使用如下代码可以实现获取文件的MD5值: public static String …

    Java 2023年5月19日
    00
  • SpringBoot激活profiles的几种方式

    下面详细讲解SpringBoot激活profiles的几种方式。 激活profile的几种方式 1. 命令行参数 在启动SpringBoot应用时,可以使用命令行参数-Dspring.profiles.active来激活profile。 例如,输入以下命令可以激活名为”dev”的profile: java -jar myapp.jar -Dspring.pr…

    Java 2023年5月19日
    00
  • Java Spring MVC 上传下载文件配置及controller方法详解

    下面是关于“Java Spring MVC 上传下载文件配置及controller方法详解”的完整攻略,包含两个示例说明。 Java Spring MVC 上传下载文件配置及controller方法详解 在Java Spring MVC中,文件上传和下载是常见的功能。本文将介绍如何配置文件上传和下载,并提供两个示例说明。 步骤一:配置文件上传 首先,我们需要…

    Java 2023年5月17日
    00
  • JAVA/JSP学习系列之三(Resin+Apache的安装)

    下面是详细的JAVA/JSP学习系列之三(Resin+Apache的安装)攻略,包含了安装过程和示例代码。 Resin+Apache的安装 安装Resin 下载Resin压缩文件,可以在官网https://resin.caucho.com/下载,也可以在镜像网站上下载。 解压文件,将解压后的文件夹移动到/usr/local目录下。 tar -zxvf res…

    Java 2023年5月19日
    00
  • Spring配置类源码分析详解

    我来为你详细讲解一下”Spring配置类源码分析详解”的完整攻略。 一、前言 在Spring框架中,我们一般会使用XML配置文件或者注解来配置Bean,但是自从Spring4.0开始,我们也可以使用纯Java类来配置Bean了,这就是所谓的Java Config。Java Config的优点很明显,就是配置简单、类型安全、可重构等等。在本文中,我们将探讨如何…

    Java 2023年5月19日
    00
  • Android笔记之:App模块化及工程扩展的应用

    以下是对“Android笔记之:App模块化及工程扩展的应用”攻略的详细讲解。 1. 什么是App模块化? App模块化是指将整个应用程序拆分为多个独立的模块,每个模块只包含特定的功能。这样做有助于提高代码的可重用性和维护性,并且可以最大程度地减少不必要的耦合。 2. 怎么进行App模块化? 进行App模块化有两种方法:一种是动态模块化,一种是静态模块化。 …

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