1. Map存储数据的特点是什么?并指明key,value,entry存储数据的特点。
双列数据,存储key-value对数据。
key:无序的、不可重复的 ---- Set存储
value:无序的、可重复的 ---- Collection存储
key-value:无序的、不可重复的 ---- Set存储
2. 描述HashMap的底层实现原理(jdk 8版)
数组+链表+红黑树,线程不安全的。
(1)开始创建HashMap的对象的时候,底层只定义了默认加载因子(DEFAULT_LOAD_FACTOR),而不对数组的长度进行定义。
(2)在使用 map.put(key1,value1) 添加元素的时候,再创建一个长度为16的数组。
(3)元素添加:
- 先计算哈希值,经过计算后确认放置在 Node() 数组中的位置,若该位置没有元素,直接添加。----情况1
- 如果此位置上的数据不为空,(意味着此位置上存在一个或多个数据(以链表形式存在)),比较key1和已经存在的一个或多个数据的哈希值。
- 如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1-value1添加成功。----情况2
- 如果key1的哈希值和已经存在的某一个数据(key2-value2)的哈希值相同,调用key1所在类的equals(key2)方法,比较:
如果equals()返回false:此时key1-value1添加成功。----情况3
如果equals()返回true:使用value1 替换 value2。
(4)扩容:在不断的添加过程中,会涉及到扩容问题,当超出临界值(且要存放的位置非空)时,扩容。默认的扩容方式:扩容为原来容量的2倍,并将原有的数据复制过来。
(5)当数组的某一个索引位置上的元素以链表形式存在的数据个数 > 8 且当前数组的长度 > 64时,此时此索引位置上的所数据改为使用红黑树存储。
3. Map中常用实现类有哪些?各自有什么特点?
(1)HashMap:Map的主要实现类,数组+链表+红黑树,线程不安全,效率高,可以存储 null 的 key-value。
LinkHashMap:HashMap的子类,数组+双向链表+红黑树,可以顺序的添加元素,对于频繁的遍历操作,可以考虑使用 LinkHashMap 来进行存储。
(2)TreeMap:红黑树,添加的 key 必须是同一类元素,可以进行排序遍历。
(3)Hashtable:作为古老的实现类;线程安全的,效率低;不能存储null的key和value。
其子类 Properties:常用来处理配置文件,key和value都是String类型
4. 如何遍历Map中的 key-value 对,代码实现
方式一,5步
(1)创建 entrySet 对象
(2)创建 entrySet 迭代器
(3)指针下移取 key-value 元素
(4)类型强转
(5)getKey()、getValue()
Set entrySet = map.entrySet();
Iterator iterator = entrySet.iterator();
while(iterator.hasNext()){
Object obj = iterator.next();
Map.Entry entry = (Map.Entry) obj;
System.out.println(entry.getKey() + "---->" + entry.getValue());
}
方式二:4步
(1)创建 keySet 对象
(2)创建迭代器
(3)指针下移取 key 值
(4)取 key 对应的 value 值
Set keySet = map.keySet();
Iterator iter = keySet.iterator();
while (iter.hasNext()){
Object key = iter.next();
Object value = map.get(key);
System.out.println(key + "---->" + value);
}
5. Collection和Collections的区别?
Collection:一个实现集合的接口。
Collections:操作 Collection 和 Map 的工具类。方法都声明为静态的。