一.Map(接口)
储存键值对类型数据
键值对:K-V映射关系
K:键->唯一的,不可重复的,无序的
Map中的所有的Key拿出来构成一个Set集合
V:值——>可重复的,无序的——>Map中的所有的键值对的value拿出来构成一个collection集合
一个key只能对应一个value,如果想要一个key对应多个value,可以将value定义为数组|集合
如果key相同,value覆盖
遍历:
1.valus():只能遍历value,不能遍历key
2.keyset();
3.entryset();
二.HashMap:基于哈希表的Map接口的实现。 此实现提供了所有可选的映射 *** 作,并允许null值和null键。
底层:哈希表(数组+链表+红黑树)
特点:查询,增删效率高,无序的,根据key去重
线程不安全
默认初始容量16:哈希表数组结构第一次默认大小
加载因子loadFactor|默认加载因子DEFAULT_LOAD_FACTOR:0.75
大小:集合中数据的个数
扩容临界值|阀值:size = Capacity*loadFactor实现扩容
扩容机制:newCap = oldCap《1,每次扩容原容量的两倍
HashSet底层是由HashMap维护的
分析源码:数组长度要求2的整数次幂
链表长度>8,容量<64,会通过resize()进行扩容,如果容量大于64,才会把链表转变为红黑树
1.根据key计算哈希值hash(key) int hash = (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
2.调用putVal(hash,key,value)实现存储键值对数据
3.先判断哈希表中的节点数组是否为null,或者长度为0 ((tab = table) == null || (n = tab.length) == 0),如果是证明是第一次添加数据,调用resize()方法为数组扩容
4.resize()扩容方法内部的扩容机制 int newCap = oldCap << 1,每次扩容原容量的2倍
5.计算位桶的索引(节点数据要存储在数组的指定索引位置) index = (n - 1) & hash
6.判断数组对应索引位置是否存在节点数据 tab[index] == null
7.如果没有存在数据,证明链表中没有节点,当前要存储的数据节点作为链表头节点存在,长度+1,然后判断是否需要扩容,需要扩容调用resize方法进行扩容 if (++size > threshold) {resize();}
tab[index] = new Node<>(hash, key, value, null);
8.如果存在数据,判断已有的节点是否为红黑树的节点,如果调用putTreeval()方法实现添加,如果不是树的节点,证明还是链表结构
遍历链表,判断已有链表的节点的key是否与要存储的键值对的key相同(e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))),
如果相同value覆盖,返回被覆盖的value,
如果不相同,遍历到链表的最后,创建新节点,挂在原链表的最后 p.next = newNode(hash, key, value, null);,长度+1,判断是否需要扩容 (++size > threshold) {resize();}
存储过程中的所有的哈希算法实现,目的都是为了把数据尽量散列的分布在不同的位桶中,减少哈希碰撞,提高效率。
注意:Map的去重根据key实现,HashMap的哈希表中计算位桶的索引,判断是否重复都是根据key与value无关,只有存储数据,构建新节点的时候或者key相同value覆盖的时候才与value有关
去重:HashMap中键值对的key为JavaBean的时候要求key的类型重写Hashcode和equals方法
三:Hashtable:
底层结构:哈希表
HashMap和Hashtable的区别:
1.继承体系不同
2储存键值对中对null值的要求不同
HashMap中null值可以作为键值对
Hashtable中null值不能作为键值对
3.同步情况不同
HashMap线程不安全,不同步
Hashtable线程安全的哈希表
4.初始容量,扩容机制不同
HashMap初始容量16,扩容:每次扩容原容量2倍
Hashtable初始容量10,扩容:每次扩容原容量2倍加1
5.计算key的hash值,与位桶索引的方式不同
HashMap :
int hash = (h = key.hashCode()) ^ (h >>> 16);
int index = (n - 1) & hash;
Hashtable :
int hash = key.hashCode();
int index = (hash & 0x7FFFFFFF) % tab.length;
HashMap线程不安全问题:
1.可以使用Hashtable
2.Collections工具类中 synchronizedmap(Map
3.juc高级并发编程包ConcurrentHashMap
四.TreeMap:
底层结构:红黑树
特点:自动做升序排列,无序的,去重的
注意:无论是排序,还是去重都是根据键值对的key计算。
排列去重问题:都是根据键值对的key实现,要求key的类型实现内部比较器,或者定义TreeMap指定使用外部比较器
TreeSet底层就是由TreeMap维护的,就是TreeMap键值对的key
五.properties:
Properties类表示一组持久的属性。 Properties可以保存到流中或从流中加载。 属性列表中的每个键及其对应的值都是一个字符串。
properties常用作配置文件使用
定义使用步骤:
1.src下新建文件 xx.properties
2.创建Properties类型的对象
3.调用load(InputStream|Reader)
4.根据key获取value getProperty(key)
六.Collections 工具类
此类仅包含对集合进行 *** 作或返回集合的静态方法
静态工厂
类似Arrays
Collection与Collections的区别:
Collection是一个集合接口
Collections是实现Collection的工具类
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)