Map集合
Map无序、key唯一
int size();
boolean isEmpty();
boolean containsKey(Object key);
boolean containsValue(Object value);
V get(Object key);
V put(K key, V value);
V remove(Object key);
void putAll(Map<? extends K, ? extends V> m);
void clear();
Set<K> keySet();
Collection<V> values();
Set<Map.Entry<K, V>> entrySet();
int hashCode();
Entry内部接口
AbstractMap
抽象类通常作为一种骨架实现,为各自子类实现公共的方法。抽象类不能通过new关键字直接创建抽象类的实例,但它可以有构造方法。AbstractMap作为它们的骨架实现实现了Map接口部分方法,也就是说为它的子类各种Map提供了公共的方法。
实现的方法有:
- public boolean containsKey(Object key)
- public boolean containsValue(Object value)
- public boolean equals(Object o)
- public V get(Object key)
- public void clear()
- public int hashCode()
- public boolean isEmpty()
- public Set keySet()
- public Collection values()
- public V remove(Object key)
Set<Map.Entry<K, V>> entrySet()方法为抽象方法。
EnumMap
EnumMap是是一种键为枚举类型的特殊的Map实现。所有的Key也必须是一种枚举类型,EnumMap是使用数组来实现的。
构造方法:
- EnumMap(Class< K > keyType):使用指定的键类型创建一个空的枚举映射。
- EnumMap(EnumMap<K,? extends V> m):创建与指定的枚举映射相同的键类型的枚举映射,最初包含相同的映射
- EnumMap(Map<K,? extends V> m):创建从指定Map初始化的枚举映射。
HashMap
https://blog.csdn.net/mq2553299/article/details/76858495
https://juejin.im/post/5aa47ef2f265da23a0492cc8
https://juejin.im/post/5a66a08d5188253dc3321da0 (jdk7 transfer引起链表循环)
关键点:putVal()、remove()、resize()
常见问题:1.线程不安全原因:多个线程put时,在put相同的key时,有的线程的值会被其他线程的值覆盖掉 2.在putVal()方法中,jdk1.8之前会出现循环链表的情况,即在get时会出现死循环,但在1.8中已经解决了这个问题。 可参看博客:http://www.voidcn.com/article/p-hcuguoxo-bob.html
HashMap默认的capacity为16,加载因子为0.75f(loadFactor), threshold=capacity*loadFactor。
resize()扩容为原来容量的2倍( << 1 左移实现)。
resize()的判断依据:当前容量大于threshold
LinkedHashMap
java8 中LinkedHashMap并没有重写HashMap的put方法,而是直接在HashMap中的putVal()方法中使用了
这三个方法,但是这三个方法在LinkedHashMap进行了重写。即在HashMap类中,只做了一个说明。
使用LinkedHashMapsh实现LRU算法。
详细参看:
https://my.oschina.net/biezhi/blog/485728
http://tech.dianwoda.com/2018/09/04/linkedhashmapzhong-lrude-shi-xian/
在putVal()时,若存在相同key时且是插入顺序(accessOrder为true)时,该方法将元素移到末尾。测试结果:
import java.util.LinkedHashMap;
import java.util.Map;
public class TestLinkedHashMap {
public static void main(String[] args) {
//测试有重复的key时,按插入顺序
Map<Integer, Integer> map = new LinkedHashMap<>(2, 3, true);
map.put(1, 2);
map.put(2, 1);
map.put(1, 3);
for(Map.Entry<Integer, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() +":"+entry.getValue());
}
System.out.println();
//默认的访问顺序
Map<Integer, Integer> map1 = new LinkedHashMap<>();
map1.put(1, 2);
map1.put(2, 1);
map1.put(1, 3);
for(Map.Entry<Integer, Integer> entry : map1.entrySet()) {
System.out.println(entry.getKey() +":"+entry.getValue());
}
}
}
结果:
2:1
1:3
1:3
2:1
SortedMap
实现一个有序的Map,该接口声明了一个Comparator<? super K> comparator();该方法用来对Key进行排序,默认是升序,具体实现可参看TreeMap。声明的方法有:
Comparator<? super K> comparator();
SortedMap<K,V> subMap(K fromKey, K toKey);
SortedMap<K,V> headMap(K toKey);
SortedMap<K,V> tailMap(K fromKey);
K firstKey();
K lastKey();
Set<K> keySet();
Collection<V> values();
Set<Map.Entry<K, V>> entrySet();
NavigableMap
NavigableMap扩展了 SortedMap,具有了针对给定搜索目标返回最接近匹配项的导航方法。方法 lowerEntry、floorEntry、ceilingEntry 和 higherEntry 分别返回与小于、小于等于、大于等于、大于给定键的键关联的 Map.Entry 对象,如果不存在这样的键,则返回 null。类似地,方法 lowerKey、floorKey、ceilingKey 和 higherKey 只返回关联的键。所有这些方法是为查找条目而不是遍历条目而设计的。
TreeMap
TreeMap实现的接口及继承的类如下: