首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >为什么jdk1.8之前HashMap是由List+链表组成?

为什么jdk1.8之前HashMap是由List+链表组成?

作者头像
贺公子之数据科学与艺术
发布2025-08-29 16:09:50
发布2025-08-29 16:09:50
2080
举报
在jdk1.8之前,Java中的HashMap实现是由数组+链表的方式组成的。这样的设计是为了解决冲突问题,即当两个不同的键值映射到数组的同一个位置时,需要通过链表将它们连接起来。

优点:

  1. 实现简单:使用链表的方式可以方便地处理冲突问题,实现相对简单。
  2. 空间利用率高:链表的插入和删除操作相对高效,可以更好地利用内存空间。

缺点:

  1. 查找效率低:由于链表只能顺序查找,当需要查找特定键值对时,需要遍历整个链表,效率较低。
  2. 遇到长链表时性能下降:如果链表过长,会导致插入和查找操作的性能下降,因为需要遍历整个链表。

链表是由一系列节点组成的数据结构,每个节点包含一个数据元素和一个指向下一个节点的指针。链表的特点是插入和删除操作比较高效,但是查找操作需要遍历整个链表。

代码实现

在JDK1.8之前,HashMap是由数组+链表的形式实现的。下面是一个简单的代码示例:

代码语言:javascript
复制
import java.util.LinkedList;

public class HashMapBeforeJDK1_8<K, V> {
    private LinkedList<Pair<K, V>>[] buckets;
    private int capacity;
    
    public HashMapBeforeJDK1_8(int capacity) {
        this.capacity = capacity;
        buckets = new LinkedList[capacity];
    }
    
    public void put(K key, V value) {
        int index = indexForKey(key);
        if (buckets[index] == null) {
            buckets[index] = new LinkedList<>();
        }
        
        LinkedList<Pair<K, V>> bucket = buckets[index];
        
        Pair<K, V> newPair = new Pair<>(key, value);
        for (Pair<K, V> pair : bucket) {
            if (pair.getKey().equals(key)) {
                pair.setValue(value);
                return;
            }
        }
        
        bucket.add(newPair);
    }
    
    public V get(K key) {
        int index = indexForKey(key);
        LinkedList<Pair<K, V>> bucket = buckets[index];
        
        if (bucket != null) {
            for (Pair<K, V> pair : bucket) {
                if (pair.getKey().equals(key)) {
                    return pair.getValue();
                }
            }
        }
        
        return null;
    }
    
    private int indexForKey(K key) {
        return Math.abs(key.hashCode()) % capacity;
    }
    
    private static class Pair<K, V> {
        private K key;
        private V value;
        
        public Pair(K key, V value) {
            this.key = key;
            this.value = value;
        }
        
        public K getKey() {
            return key;
        }
        
        public V getValue() {
            return value;
        }
        
        public void setValue(V value) {
            this.value = value;
        }
    }
}

在这个示例中,HashMapBeforeJDK1_8类使用一个数组来表示HashMap的桶,每个桶是一个LinkedList<Pair<K, V>>类型的链表。put()方法用于向HashMap中添加键值对,get()方法用于根据键获取对应的值。indexForKey()方法用于计算键的哈希值并映射到对应的桶。Pair<K, V>是一个简单的键值对类,用于存储键值对的数据。

分析

以一个简单的案例来说明,假设我们要存储学生的姓名和对应的分数。使用HashMap可以实现快速根据姓名查找分数的功能。当两个不同学生的姓名映射到同一个数组位置时,HashMap会使用链表将它们连接起来。

例如,我们有两个学生"张三"和"李四",他们的姓名都映射到数组的索引位置1。如果使用了链表结构,将两个学生的信息存储在同一个位置上,可以更好地利用空间。当我们需要查找"张三"的分数时,只需要遍历链表即可。

而如果使用数组结构,则需要使用额外的数据结构存储冲突的元素,例如使用List。在这种情况下,当两个学生的姓名映射到同一个数组位置时,需要将它们存储在同一个List中。如果我们要查找"张三"的分数,需要遍历整个List才能找到对应的分数。这样的设计会导致查找效率的降低。

因此,通过使用数组+链表的方式实现HashMap可以在一定程度上提高空间利用率和插入/删除操作的效率,但在查找操作上有一些性能上的牺牲。在jdk1.8之后,HashMap的实现方式进行了改进,引入了红黑树来替代链表,以优化查找操作的性能。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-07-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 在jdk1.8之前,Java中的HashMap实现是由数组+链表的方式组成的。这样的设计是为了解决冲突问题,即当两个不同的键值映射到数组的同一个位置时,需要通过链表将它们连接起来。
  • 优点:
  • 缺点:
  • 代码实现
  • 分析
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档