Java中集合体系(主要Map和Set)

集合框架脑图下载地址【免费】
图片不太清晰的话可以点击上方链接下载
在这里插入图片描述

List和Map、Set的区别?

List和Set都是单列数据的集合,Map是存储键和值这样的双列数据集合。

  1. List中存储的数据是有顺序的,并且允许重复。

  2. Map中存储的数据是没有顺序的,其键是不能重复的,它的值是可以有重复的。

  3. Set中存储的数据是无序的,不允许重复,但元素在集合中的位置由hashcode决定,位置是固定的(Set集合根据hashcode来进行数据的存储,所以位置是固定的,但是位置不是用户可以控制的,所以对于用户来说set集合还是无序的)。

HashMap底层原理

HashMap根据键的hashCode值存储数据,大多数情况下可以直接定位到它的值,具有很快的访问速度,但是遍历顺序却不确定。

HashMap最多只允许一条记录的键为null,允许多条记录的值为null。

HashMap线程不安全,在同一时刻可以有多个线程同时写HashMap,可能会导致数据不一致。

如果需要满足线程安全,可以使用Collections的synchronizedMap方法使HashMap具有线程安全能力,或者使用ConcurrentHashMap,HashTable。

HashMap是怎样保证数据不重复的?

HashMap通过重写HashCode和equals保证数据不重复。

下面以(对象)为例(对象1,2是相同的,里面的值也一样)

因为当我们向hashmap添加(对象1)时,hashmap首先会调用对象的hashCode来计算hash值作为地址,如果没有重写hashCode方法,那么hashmap是调用的Object的hashCode方法来计算hash值,Object中hashCode计算出来的hash值其实就是对象的地址,(对象1)与(对象2)存储的的地址肯定不同。所以我们无法通过(对象1)找到(对象1)的地址。自然就找不(对象1)的数据


但是当我们重写hashCode以后,他就可以通过重写的HashCode计算出来的hash值找到相同的键的位置,在这之后并不会直接从该地址获取值(HashMap为了解决hash值冲突的问题,使用了拉链法),而是会调用equals方法进行判断,这就和没有重写HashCode造成错误的原因类似了,没有重写equals方法,就要被迫调用Object类的equals方法,而Object类的equals方法是直接比较两个对象的内存地址所以还是找不到。


HashCode的值相同,元素不一定相同。
HashCode的值不同,元素一定不相同。

首先判断HashCode值相同才会调用equals。

拉链法

拉链法就是将数组和链表相结合,也就是说创建一个链表数组,数组中每一个格子都存放着一个链表,如果hash冲突,就会将冲突的值加入到链表中。

Set

HashSet底层是由HashMap时间,不允许集合中有重复的值,使用该方式需要重写hashcode()和equals()。


LinkEdHashSet继承与HashSet,同时又基于LinkedHashMap来实现,底层是LinkedHashMap。

HashSet会通过元素的hashcode()和equals()方法进行判断,当试图将元素加入到Set集合时,HashSet首先会使用对象的hashcode方法来判断对象加入的位置。同时也会与其他已经加入的对象的hashcode进行比较,如果不相等hashcodeHashSet就认为这个对象之前不存在,如果之前存在同样的hashcode值,就会进一步的比较equals()方法,如果equals()比较返回结果是true,那么认为该对象在集合中的对象是一模一样的,不会将其加入;如果比较返回的是false,那么HashSet认为新加入的对象没有重复,可以正确加入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鹈鹕吃吃吃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值