上一篇https://blog.csdn.net/weixin_56640241/article/details/121783221https://blog.csdn.net/weixin_56640241/article/details/121783221
Map概述
一、Map存储双列的数据,Key—Value。
1.HashMap:作为Map的主要实现类,线程不安全,效率高,可以存储null的key与value。
2.LinkedHashMap:保证在遍历Map元素时,可以按照添加的顺序实现遍历。原因:在原有的HashMap底层结构基础上,添加了一对指针,指向前一个与后一个元素。用于频繁遍历.
3.HashTable:作为古老的实现类;线程安全的,效率低;不能存储null的key和value。
Properties:常用来处理配置文件,key-value都是String类型的。
4.TreeMap:保证按照添加的key-value对进行排序,实现排序遍历,此时考虑key的自然排序和定制排序。底层使用红黑树。
二、key-value理解
1.key不可重复,使用Set存储,无序的;Value可以重复,无序的,使用collection存储。
一个键值对称为Entry。
2.Key-value对中的key不可以出现一对多;但是多对一可以。和函数的一样的。Entry是无序的,不可重复的,使用Set存储所有的Entry。
3.key所在类的重写方法:
三、 HashMap底层是实现原理。重点
1.以JDK7为例:
HashMap map = new HashMap();
在实例化以后,底层创建了长度为16的一维数组Entry[]table。
map.put(k,v);
首先调用k所在类的HashCode();得到其Hash值,该值为k在Entry[]table中的存储位置。
①如果此位置上的数据为空,此时的key-value添加成功。
②如果此位置有数据,比较当前k与已经存在一个或多个数据的哈希值:
如果k的哈希值与已经存在的某个数据的哈希值不同,此时k-v添加成功。
如果k的哈希值以已经存在的某个数据的哈希值相同,继续比较:
调用k所在的类的equals()方法比较:①如果equals()返回false,表示添加成功,②如果equals()返回true,使用v去替换数组中已经有的k-v,类似于覆盖。
2.注意点
①在数组相同位置存放的数据,其哈希值不一定相同。
②数组中存放的是链表。
③扩容问题:扩容为原来容量的2倍,并将所有数据复制过来。
3.JDK7与JDK8的不同
①new HashMap():底层没有创建一个长度为16的数组,是一个空的数组。
②JDK8底层的数组是Node[]而非Entry[]。
③首次调用put方法时,底层创建长度为16的数组。
④JDK7底层结构:数组+链表,JDK8:底层结构:数组+链表+红黑树。
⑤当数组的某一个索引位置上的元素以链表形式存在的数据个数>8且当前数组的长度>64时,此时索引位置上的所有数据改为使用红黑树存储。
4.JDK8
HashMap的默认容量为16;默认加载因子是0.75;
threshold:扩容的临界值 = 容量 * 填充因子。16*0.75=12;
Treeify_THRESHOLD:Bucket中链表长度大于该默认值,转化为红黑树。
MIN_TREEIFY_CAPACITY:桶中的Node被树化时最小的hash表容量:64。即:一个索引处的链表长度最小为64时转为树。
当数组的容量为12时,数组扩容,当一个索引出的链表长度大于等于64时,转为树形结构存储。
四、Map接口中的方法
1.添加
Object put(Object key,Object value):将指定的key-value添加到当前map对象中,当map中已经有key就是替换。
void putAll(Map map):将map中所有的key-value存放到当前map中。
2.移除
Object remove(Object key):移除指定key的key-value对,并返回value。
3.清空
void clear():清空当前map中的所有数据。
4.元素查询
①object get(object key):获取指定key对应的value。
②boolean containsKey(object key):是否包含指定的key
③boolean conyainsValue(object value):是否包含指定的value
④int size():返回Map中key-value对的个数。
⑤boolean isEmpty():判断当前Map是否为空。
⑥boolean equals(object obj):判断当前Map和参数对象obj是否相等。
5.遍历
①获得所有的key:Set keySet();
②获得所有的value: Collection values();
③遍历所有的k-v对:Set:entrySet();返回键值对集合,键值对类型为Entry。
Entry.getKey():返回键值对中的key;Entry.getValue:返回键值对中的value。
五、TreeMap和Properties
向TreeMap中添加key-value,要求key必须是由同一个类创建的对象,因为要按照key进行排序:自然排序和定制排序。
Properties类是Hashtable的子类,该对象用于处理属性文件key与value都是String类型。
六、Collections工具类的使用
collections是一个操作set、list、map等集合的工具类。
常用方法
1.reverse(List):反转List中元素的顺序。
2.shuffle(List):对List集合元素进行随机排序。
3.sort(List):根据元素的自然顺序对指定List集合元素按照升序排序。
4.sort(List,Comparator):根据指定的comparator产生的顺序对List集合排序。
5.swap(List,int i,int j):将指定List集合中的i处元素和j处元素进行交换。
6.object max(collection):根据元素的自然顺序,返回给定集合中的最大元素。
7.object max(collection,comparator):根据comparator指定的顺序,返回给定集合中的最大(即排序之后最右边的数)
8.object min(collection):集合中最小的数
9.object min(collection,comparator):按照定制排序得到的最小的数。
10.int frequency(collection,object):返回指定集合中指定元素的出现次数。
11.void copy(List dest,List src):将src中的内容复制到dest中。dest的元素个数必须与src的个数一致,少了就会报错,多了重复赋值。List dest = Arrays.asList(new object[src.size()]);
12.boolean replaceAll(List list,object oldVal,object newVal):使用新值替换List中的旧值。
同步控制
collection类中提供了多个synchronized***()方法,该方法可使将指定集合包装成线程线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题。
例:Collection.synchrohizedList(list);返回的list就是线程安全的list,也可以用于Map。