Map:无序(存入)、key唯一、可存null
接口下主要有:HashMap,HashTable、LinkedHashMap、TreeMap、ConcurrentHashMap
================================================================
HashMap :基于hashCode(),底层是Entry键值对数组
问:HashMap是怎么添加数据的呢?(判断机制:hashCode+equals())
答:根据添加的key的hashCode值 模 当前数组的length(默认16),运算的结果就是这个键值对在数组中的下标,进而保存键值对。所以无序
如果key模length后,得到的下标是相等的,这种情况就叫hash碰撞(哈希冲突)
这时候再继续判断key的equals方法,如果equals判断为true,就会将原来key的值覆盖;如果是false,就会在该下标处的原来键值对后面形成 链表(put)
jdk1.8之后,如果链表长度达到8个,就形成红黑树。
当进行删除(remove)操作后,链表中键值对剩余的数量小于等于6的时候,就重新将红黑树退化为链表。
问:那么怎么解决哈希冲突呢?
答:合理设计数组(当然数组越长,哈希冲突几率越小,就看自己是不是土豪叭)
===================================================================
Hashtable : 就是一个线程安全的HashMap,不能存放null键和null值
Properties:是Hashtable子类,只不过key-value都是String类型,一般用来做配置文件:.xml、.properties、.ini/.init、.yml (SprintBoot),从而解决文件的硬编码问题
ConcurrentHashMap : 就是一个线程安全且效率更高的的HashTable,理论上是Hashtable的16倍,JDK1.5开始
LinkedHashMap: 就是一个内部维护了一个链表的HashMap,可以保证存入和取出顺序
=======================================================================
TreeMap : 判断key重复的规则和TreeSet一样
TreeMap中的键(key)要么是具有自然排序能力(需要key实现Comparable接口,重写CompareTo方法);要么TreeMap中提供一个比较器Comparetor实现类对象。
排序规则:返回值是0:key是重复的
是正数,则按照key的升序排序
是负数,降序
==============================================================
Map的三种取值
entrySet():取键值对
keySet():只取键
values():只取值
//3种遍历方法
//2种遍历方式:foreach和迭代器
Set<Entry<String, Integer>> entrySet = hashMap.entrySet();
Iterator<Entry<String, Integer>> iterator = entrySet.iterator();
while (iterator.hasNext()) {
Map.Entry<java.lang.String, java.lang.Integer> entry = (Map.Entry<java.lang.String, java.lang.Integer>) iterator
.next();
System.out.println(entry.getKey()+"----------"+entry.getValue());
//System.out.println(iterator.next());
}
for (Entry<String, Integer> entry : entrySet) {//效率最高,因为一次遍历就把键和值都取出来了
System.out.println(entry.getKey()+" = "+entry.getValue());
}
Set<String> keySet = hashMap.keySet();//二次查询
for (String string : keySet) {
System.out.println(string+" = "+hashMap.get(string));
}
Collection<Integer> values = hashMap.values();//只能取值
for (Integer integer : values) {
System.out.println(integer);
}
==============================================================