背景介绍
我们在日常的开发的过程中,一直都有在使用Map存储数据。但是Map的底层原理,以及Map的Key值为什么不能重复,Map中的key值和Hash有什么关系大家都清楚吗,如果我们把这些内容都搞清楚了我们在使用Map的时候才会得心应手,排查关于Map相关的问题才会更加的容易,才会更快的去定位问题出现的原因,下面我们就深入了解一下Map。
详细说明
什么是Map
Map是Java中的一个接口,用于存储键值对(key-value)数据。它提供了一种将键映射到值的方式,可以根据键快速地获取对应的值。
使用Map有什么好处
- 易于使用和理解:Map提供了简单明了的接口和方法,使得我们可以方便地进行键值对数据的操作,如添加、删除、修改和查询。
- 高效的查找操作:Map使用哈希表或平衡二叉树等数据结构来实现键值对的存储,可以通过键快速地定位到对应的值,从而提供高效的查找操作。
- 灵活的键和值:Map的键和值可以是任意类型的对象,不像数组只能使用整数索引。这使得我们可以根据具体的需求自由选择键和值的类型。
- 不允许重复的键:Map中的键是唯一的,不允许重复。这样可以保证每个键都对应唯一的值,避免了数据的冗余和混乱。
Map底层原理
HashMap底层使用了数组和链表/红黑树的数据结构。当我们向HashMap中添加键值对时,HashMap会根据Key的哈希码来确定Key在数组中的索引位置。下面是一个简化的示例,说明HashMap的底层原理:
1.创建一个HashMap对象:
Map<String, Integer> map = new HashMap<>();
2.向HashMap中添加键值对:
map.put("wzl", 10);
map.put("武梓龙", 5);
map.put("W", 8);
3.获取Key的哈希码:
int hash1 = "wzl".hashCode(); // 哈希码为123456
int hash2 = "武梓龙".hashCode(); // 哈希码为789012
int hash3 = "Wzil".hashCode(); // 哈希码为345678
4.根据哈希码计算数组索引位置:
int index1 = hash1 % arrayLength; // 假设数组长度为16,索引位置为2
int index2 = hash2 % arrayLength; // 索引位置为4
int index3 = hash3 % arrayLength; // 索引位置为10
5.在数组中存储键值对:
Entry<String, Integer> entry1 = new Entry<>("wzl", 10); // Entry是HashMap中的内部类,用于存储键值对
Entry<String, Integer> entry2 = new Entry<>("武梓龙", 5);
Entry<String, Integer> entry3 = new Entry<>("Wzil", 8);
// 数组中的索引位置2上存储entry1
// 数组中的索引位置4上存储entry2
// 数组中的索引位置10上存储entry3
6.处理哈希冲突: 当两个不同的Key生成相同的哈希码时,称之为哈希冲突。HashMap使用链表或红黑树来解决哈希冲突。 假设"apple"和"banana"生成了相同的哈希码,它们都计算出了索引位置2:
// 数组中的索引位置2上原本存储了entry1,现在需要将entry2插入到链表中
entry1 -> entry2
这就是HashMap的简单示例,说明了HashMap底层使用数组和链表/红黑树的数据结构来存储键值对。通过哈希码和数组索引的计算,可以快速定位到存储键值对的位置。当发生哈希冲突时,使用链表或红黑树来解决。这样,HashMap可以提供快速的插入、删除和查找操作。
总结提升
Map是Java中常用的数据结构之一,用于存储键值对数据。Key值和Hash之间有关联,通过哈希函数将Key映射到数组的索引位置。Map提供了丰富的操作方法,可以方便地进行数据的增删改查操作。在选择Map实现类时,需要根据具体的需求和性能要求进行选择。
标签:Map,HashMap,数组,索引,详解,键值,哈希 From: https://blog.51cto.com/u_16102679/6601451