- Map集合的三个实现类 HashMap、TreeMap、Hashtable
- map中的key 无序的 不可重复的 使用set集合存储
- map中的value 无序的 可重复的 使用collection集合存储
- HashMap 线程不安全的 效率高
- JDK7底层使用数组+链表 底层是Entry[]数组 new HashMap时 创建长度为16的数组 每次扩容为当前长度的2倍
- JDK8底层使用数组+链表+红黑数 底层是Node[]数组 懒汉式创建 添加元素时才创建长度为16的数组 每次扩容为当前元素的2倍
- 当数组的某个下标上的元素>8且数组的长度>64时 此时此下标上的所有数据改为使用红黑数
- Hashtable 线程安全的 古老的实现类 效率低
- TreeMap 可以对集合进行排序 实现排序遍历 根据Key值进行排序 底层使用红黑树
- LinkedHashMap HashMap的子类 保证遍历元素时 按照添加的顺序进行遍历 对于频繁遍历的操作 此类执行效率高于HashMap
- properties Hashtable的子类 key与value元素都是String
// 将默认加载因子赋值给loadFactor 0.75fpublic HashMap() { this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted }
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; // 将成员变量赋值给局部变量tab 判断是否为空 或长度为0 if ((tab = table) == null || (n = tab.length) == 0) // resize 创建数组 初始默认长度为16 // n记录数组长度 n = (tab = resize()).length; // 计算新添加元素应处的位置是否为空 并获取当前位置元素赋值给P if ((p = tab[i = (n - 1) & hash]) == null) // 将新添加的元素方法当前位置 tab[i] = newNode(hash, key, value, null); else { Node<K,V> e; K k; // 当前位置元素hash值 key值与新添加元素值相同 if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) // 将当前元素赋值给e e = p; // 红黑树相关处理 else if (p instanceof TreeNode) e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); else { // 当前位置元素与新添加元素比对不一致 遍历当前元素链表下的其他元素 for (int binCount = 0; ; ++binCount) { // 当前元素的下一个元素为空 if ((e = p.next) == null) { // 将新添加的元素设置为当前元素的下一个元素 p.next = newNode(hash, key, value, null); // 当前遍历此时>=8-1 if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st // 进入该方法 转换为红黑树或扩容 treeifyBin(tab, hash); break; } // 判断当前e变量的 hash值 key值 是否等于新添加的元素 如果是结束循环 if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) break; // 上方的if条件都没能符合条件 将e变量赋值给局部变量p 继续循环 p = e; } } // e不为空 if (e != null) { // existing mapping for key // 记录当前e变量key的value V oldValue = e.value; if (!onlyIfAbsent || oldValue == null) // 将新添加变量的value赋值e变量(因为key值相同 后添加的覆盖之前的value) e.value = value; afterNodeAccess(e); return oldValue; } } ++modCount; if (++size > threshold) resize(); afterNodeInsertion(evict); return null; }
final Node<K,V>[] resize() { // 将成员变量table赋值给新数组 Node<K,V>[] oldTab = table; // 获取数组长度 int oldCap = (oldTab == null) ? 0 : oldTab.length; // 获取默认的临界值(数组长度达到临界值 开始扩容) 默认为0 int oldThr = threshold; int newCap, newThr = 0; if (oldCap > 0) { // 数组长度大于默认的最大值 if (oldCap >= MAXIMUM_CAPACITY) { // 获取integer最大值 threshold = Integer.MAX_VALUE; return oldTab; } // 数组长度小于默认的最大值 并且 大于等于初始容量 扩容原先容量的2倍 else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY && oldCap >= DEFAULT_INITIAL_CAPACITY) newThr = oldThr << 1; // double threshold } // 临界值是否大于0 else if (oldThr > 0) // initial capacity was placed in threshold // 将临界值赋值给变量newCap newCap = oldThr; else { // zero initial threshold signifies using defaults // 临界值为0 获取默认长度 newCap = DEFAULT_INITIAL_CAPACITY; // 获取临界值 长度*加载因子 newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY); } if (newThr == 0) { float ft = (float)newCap * loadFactor; newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ? (int)ft : Integer.MAX_VALUE); } // 设置临界值 threshold = newThr; @SuppressWarnings({"rawtypes","unchecked"}) // 创建数组 Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap]; table = newTab; if (oldTab != null) { for (int j = 0; j < oldCap; ++j) { Node<K,V> e; if ((e = oldTab[j]) != null) { oldTab[j] = null; if (e.next == null) newTab[e.hash & (newCap - 1)] = e; else if (e instanceof TreeNode) ((TreeNode<K,V>)e).split(this, newTab, j, oldCap); else { // preserve order Node<K,V> loHead = null, loTail = null; Node<K,V> hiHead = null, hiTail = null; Node<K,V> next; do { next = e.next; if ((e.hash & oldCap) == 0) { if (loTail == null) loHead = e; else loTail.next = e; loTail = e; } else { if (hiTail == null) hiHead = e; else hiTail.next = e; hiTail = e; } } while ((e = next) != null); if (loTail != null) { loTail.next = null; newTab[j] = loHead; } if (hiTail != null) { hiTail.next = null; newTab[j + oldCap] = hiHead; } } } } } return newTab; }
/** * @author:LYY 创建时间:2022/5/7 */public class MapTest { public static void main(String[] args) { HashMap<String, Object> map = new HashMap<>(); map.put("01", "哈哈"); map.put("02", "嘻嘻"); map.put("03", "笨笨"); map.put("04", "嘻嘻"); map.put("04", 55); System.out.println(map); // 获取集合中的所有key值 Set<String> keySet = map.keySet(); Iterator<String> iterator = keySet.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } // 获取所有value集合 Collection<Object> values = map.values(); for (Object value : values) { System.out.println(value); } // 获取entrySet 遍历所有key和value Set<Map.Entry<String, Object>> entries = map.entrySet(); Iterator<Map.Entry<String, Object>> iterator1 = entries.iterator(); while (iterator1.hasNext()) { // 每一个元素可以都是Entry类型数据 Map.Entry<String, Object> next = iterator1.next(); System.out.println(next.getKey() + " == " + next.getValue()); } }}