讲讲HashMap

Map接口

概述: map以键和值的形式存储数据,也叫哈希表、散列表,Map<K,V> K - 此映射所维护的键的类型,V - 映射值的类型。其中的键不能重复,值可以重复。
特点:

1、可以根据键取得对应的值。
2、键不允许重复,如果重复值会被覆盖。
3、存放的都是无序的数据。
4、 初始容量是16,默认加载因子是0.75(即长度达到16时就会扩容12)。


HashMap

HashMap底层是一个Entry数组(jdk1.8开始是Node<k,v>[] table数组),当存放数据时会根据hash算法计算数据的存放位置。算法:hash(key)%n,n就是数组的长度。

当计算的位置没有数据时,就直接存放,当计算的位置有数据时也就是发生hash冲突/hash碰撞时,采用链表的方式来解决的,在对应的数组位置存放链表的头结点。对链表而言,新加入的节点会从头结点加入,如下图。

在这里插入图片描述

当链表的长度大于等于8时,链表的的形式就会转换为红黑树的形式;当红黑树长度达到6时,红黑树又转换为链表的形式。



键为啥不允许重复?

看下图源码。
在这里插入图片描述
HashMap在存放数据时会先验证hash值是否相同,然后在判断key是否相同,如果hash值一样且内容相同,则k就是和原来的一样。(HashSet底层就是使用HashMap,用HashMap的key来存放数据以保证它的值不会重复,HashSet在存放对象时,如果想值是相同的,则需要重写key[ 即对象 ]的hashCode()方法和equals()方法。)。



HashMap的两种遍历方式
//第一种,读者自己加类型
Iterator it = map.keySet().iterator();
while(it.hasNext()) {
	System.out.println( map.get(it.next()) );
}

//第二种
Iterator<Entry<k,v>> it2 = map.entrySet().iterator();
while (it2.hasNext()) {
	Entry i = it2.next();
	System.out.println(i.getKey() + ":" + i.getValue());
}
或者
for(Map.Entry<k,v> i : map.entrySet()){
	System.out.println(i.getKey() + ":" + i.getValue());
}

有错误的地方欢迎告知!!!!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
HashMapJava中常用的数据结构之一,它提供了非常快速的查找、插入、删除操作。其底层实现原理主要是基于数组和链表的组合实现的,具体如下: 1. 数组 HashMap内部维护了一个数组,这个数组的长度是固定的,一般是2的幂次方。数组的每一个元素都是一个链表的头节点,当我们往HashMap中添加元素时,首先根据键计算出它在数组中的下标,然后将值插入到对应的链表中。 2. 链表 当两个键经过哈希计算后,它们落在了数组的同一个位置上,这种情况称为“哈希冲突”。为了解决哈希冲突,HashMap使用了链表的数据结构,将落在同一个位置的所有键值对存储在同一个链表中。当我们需要查找某个键值对时,只需遍历对应的链表即可。 3. 扩容 当HashMap中的元素个数超过了数组长度的75%时,就需要对数组进行扩容,这样可以保证HashMap的性能。扩容的过程就是将原来的数组复制到一个新的、长度为原来的两倍的数组中,然后将所有键值对重新插入到新的数组中。 4. 处理哈希冲突 当多个键值对经过哈希计算后,它们落在了数组的同一个位置上,这种情况称为“哈希冲突”。为了解决哈希冲突,HashMap使用了链表的数据结构,在同一个位置上的键值对都存储在同一个链表中。当我们需要查找某个键值对时,只需遍历对应的链表即可。 5. 线程安全问题 HashMap是非线程安全的,当多个线程同时对它进行操作时,可能会发生数据竞争。为了解决这个问题,Java提供了ConcurrentHashMap,它是线程安全的HashMap实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值