目录
前言
hashmap
hash碰撞
Hashtable
TreeMap
map集合的常用方法
前言
我们之前说map系列的集合每个元素存储的是一对数据我们称为键值对,其中键(key)的值是无序,没有索引,不能重复的。值(value)的值是无序,可重复的,没有索引的,我们上一次学习的set集合其实就是使用了map集合,我们常用的map集合有HashMap , TreeMap , Hashtable
hashmap
hashmap底层使用数组加链表加红黑树结构
hashmap每次存储数据时会使用hashcode方法生成一个尽可能唯一的值,hashcode方法是一个native方法,是通过c或c++语言编写的
通过hashcode得到hash值后,底层会根据数组的大小为每一个元素生成一个不超过数据大小的尽可能唯一的位置存储元素
hashcode方法是object类中的方法,并且对象的hash值不是与生俱来的,在第一次调用hashcode方法是才产生的,当我们存储自定义的类时需要重写hashcode方法,重写原则是,equals相等hashcode相等,equals不相等hashcode无所谓
hash碰撞
即使底层会根据每个对象的属性尽可能生成一个唯一的值,但是还是有可能出现两个对象的hash相等的情况,这时如果两个对象都需要存储,就会在数组上两个对象都要存储的位置形成一个链表
因为key的值是不能重复的,所以一旦出现hash碰撞不能直接形成链表,需要先进行判断
如果hash相等,equals相等说明是同一个key,这时key会去重,在底层没有做任何操作,value会用新的值覆盖旧的值
如果不相等,就将新元素的节点添加到链表最后
hash结构创做的目的就是快速的存和快速的取,如果链表过长反而会影响查找的速度
当链表的长度达到8时会先判断数组的长度,如果数组的长度小于64会将数组进行二倍扩容,再通过上面的方法将数据重新分配位置
如果数组长度达到64会将链表变成红黑树
Hashtable
Hashtable和HashMap的作用相同,也是hash结构,适合快存和快取
hashtable是早期版本是线程同步,安全性高,效率低的
HashMap是非线程同步,安全性低,效率高的
Hashtable中的key和value不能为null
HashMap中的key和value可以为null
TreeMap
treemap底层使用红黑树结构存储数据
红黑树是一个二叉树,每个节点有两个子节点,父节点左边的数据比父节点小,父节点右边的节点比父节点大
正是因为红黑树的特点,所以虽然map集合本身是无序的但是treemap
中的数据是自然排好序的,会按照从小到大的顺序排序
当我们添加数据是数据会先跟根节点比较,如果小就去根节点左边找,如果大就去根节点右边找
如果重复也是key去重value覆盖
map集合的常用方法
Map<Integer,String> map = new HashMap<>();
(key,value) ; //添加一个元素
(Map otherMap) ;//添加一组元素。将另一个map中的元素都添加到当前map集合中
String value = (key) ; //根据key取出对应的value
(key) ;//删除key对应的数据, 同时返回删除的value
(); //返回元素(键值对)的个数
(key);//判断集合是否包含指定的key
(value);//判断集合是否包含指定的value
map集合本身是不支持直接遍历的,但是也给我们提供了三种间接的遍历方式
Set<Integer> keys = (); //返回装有所有key的set集合
Collection<String> values = ();//返回装有所有value的collection集合,
//返回一个entrySet集合这个集合是一个装有所有键值对数据的set集合
Set<<Integer, String>> entries = ();
前两种方法就是拿到一个全是key或者全是value的集合,之后我们就可以使用迭代器或者增强for去遍历集合
第一个方法拿到key后可以使用上面的get方法获得对应的value
第二种方法就只能获得每个value因为value是可以重复的,所以我们没法通过value获得对应的key
第三个方法返回entry类型的set集合,这个entry就是key和value打包在一起的set集合,之后我们也可以使用迭代器或者增强for遍历这个集合
Map<Integer,String> map = new TreeMap<>();
Set<<Integer, String>> entries = ();
for (<Integer, String> entry : entries) {
();
();
}
当我们拿到这个set集合中的每个entry后就能使用get方法获得key和value。