21.javase-javaAPI-集合之map集合

Map

map是一种key,value结构,key是键,value是值,也就是键值对结构.
这是Map的继承体系
在这里插入图片描述

HashMap(数组+链表+红黑树)

特点:
1.键值对,<key,value>结构
2.key值是根据键的hash值计算的,并且键是唯一的.
3.value是任意类型的.
4.底层是数组加链表的形式.当key’的hash值相同时,发生hash碰撞,再用equals()方法判断是否相同,如果相同则覆盖,如果不同则生成链表.当链表长度大于8时,链表变成红黑树.
5.hashMap为线程不安全的数据结构.如果多线程可能造成hash碰撞时链表中的两个节点互相指定.形成循环链.

jdk1.7时hashMap的实现
大方向上,HashMap 里面是一个数组,然后数组中每个元素是一个单向链表。上图中,每个绿色的实体是嵌套类 Entry 的实例,Entry 包含四个属性:key, value, hash 值和用于单向链表的 next。

  1. capacity:当前数组容量,始终保持 2^n,可以扩容,扩容后数组大小为当前的 2 倍。
  2. loadFactor:负载因子,默认为 0.75。
  3. threshold:扩容的阈值,等于 capacity * loadFactor
    在这里插入图片描述
    jdk1.8时hashMap的实现
    最大的不同就是利用了红黑树,所以其由 数组+链表+红黑
    树 组成。
    根据 Java7 HashMap 的介绍,我们知道,查找的时候,根据 hash 值我们能够快速定位到数组的具体下标,但是之后的话,需要顺着链表一个个比较下去才能找到我们需要的,时间复杂度取决于链表的长度,为 O(n)。为了降低这部分的开销,在 Java8 中,当链表中的元素超过了 8 个以后,
    会将链表转换为红黑树,在这些位置进行查找的时候可以降低时间复杂度为 O(logN)。
    在这里插入图片描述
    hashMap的参数:
    在这里插入图片描述
    节点Node类,定义在hashMap的内部类,这是一个单向链表
    在这里插入图片描述
    节点数组,node<K,V>[]
    在这里插入图片描述
    常用方法

添加
put(K,V) 添加
putAll(collection c)添加集合
删除
remove(K)
clear()清空
获取
get(K) 获取value
keySet() 获取key的集合
values() 获取value值得集合
entrySet()获取节点的集合
查询
containsKey(K) 查询是否存在key
containsValue(V) 查询是否存在value值
isEmpty() 查询是否为空 替换 replace(K,V) 替换

hashMap的遍历方式:

		//第一种遍历,通过key的集合
		for(Object i : map.keySet())
		{
			System.out.println(map.get(i));
		}
		//第二种遍历,通过节点entry的集合
		for(Map.Entry<Integer, String> entry: map.entrySet()) {
			System.out.println(entry.getKey());
			System.out.println(entry.getValue());	
		}
		//第三种遍历,通过遍历器
		Iterator<Map.Entry<Integer, String>> it = map.entrySet().iterator();
		while(it.hasNext()) {
			Map.Entry<Integer, String> en = it.next();
			System.out.println(en.getKey());
			System.out.println(en.getValue());
		}
		//第四种遍历,通过value的集合
		for(Object o : map.values()) {
			System.out.println(o);
		}

HashTable(线程安全)

特点:
1.大部分方法和hashMap相似
2.线程安全的
3.性能低的,我们如果想保证线程安全,一般使用ConcurrentHashMap对象

put方法加锁
在这里插入图片描述
get方法也加锁
在这里插入图片描述

TreeMap(可排序)

特点:
1.key 和value结构
2.数据按照key值排序.所以key值必须实现comparable接口,重写compareTo方法.
3.treeSet是在treeMap的基础之上实现的.

在这里插入图片描述
常用方法:略

LinkHashMap(记录插入顺序)

特点:
1.在hashMap的基础之上,他保证了插入的hash表的有序行.
在这里插入图片描述
实现方式,可以在put方法里,现将key值放入一个linkedList集合中去,遍历的时候先从LinkedList集合中取key值,再拿取到的key值去map中取value值.

ConcurrentHashMap(线程并发安全的map集合)

Segment 段

ConcurrentHashMap 和 HashMap 思路是差不多的,但是因为它支持并发操作,所以要复杂一些。整个ConcurrentHashMap 由一个个 Segment 组成,Segment 代表”部分“或”一段“的意思,所以很多地方都会将其描述为分段锁。注意,行文中,我很多地方用了“槽”来代表一个segment

线程安全(Segment 继承 ReentrantLock 加锁)

简单理解就是,ConcurrentHashMap 是一个 Segment 数组,Segment 通过继承 ReentrantLock来进行加锁,所以每次需要加锁的操作锁住的是一个 segment,这样只要保证每 个 Segment 是线程安全的,也就实现了全局的线程安全。
在这里插入图片描述
并行度(默认 16)
concurrencyLevel:并行级别、并发数、Segment 数,怎么翻译不重要,理解它。默认是 16, 也就是说ConcurrentHashMap 有 16 个 Segments,所以理论上,这个时候,最多可以同时支 持 16个线程并发写,只要它们的操作分别分布在不同的 Segment 上。这个值可以在初始化的时候设置为其他值,但是一旦初始化以后,它是不可以扩容的。再具体到每个 Segment 内部,其实 每个 Segment 很像之前介绍的HashMap,不过它要保证线程安全,所以处理起来要麻烦些。

Java8 实现 (引入了红黑树)
Java8 对 ConcurrentHashMap 进行了比较大的改动,Java8 也引入了红黑树。
在这里插入图片描述

发布了42 篇原创文章 · 获赞 0 · 访问量 666

猜你喜欢

转载自blog.csdn.net/weixin_45449911/article/details/104497317