一:Map基本概念
1:Map接口是在Java.util包下。
Map接口不是Collection的子接口,使用键,值映射表来存储。
public interface Map<K,V>
Map 不能有重复的键(覆盖),每个键可以映射到最多一个值 允许将映射内容视为一组键、值集合或键值映射集合 key 不要求有序,不可以重复。 value 也不要求有序,但可以重复 当使用对象作为 key 时,要重写 equals 和 hashCode 方法
2:抽象方法:
3:不可修改Map对象的方法
`JDK9` 提供了创建不可修改 Map 对象的方法: 1. Map.of 2. Map.ofEntries 3. Map.copyOf
二:TreeMap
1:定义方法
public class TreeMap<K,V> //定义TreeMap方法 extends AbstractMap<K,V> //继承的父类 implements NavigableMap<K,V>, Cloneable, Serializable //接口
继承自 AbstractMap ,一个红黑树基于 NavigableMap 实现 是非线程安全的 key 不能存 `null ,但是 value 可以存 null key 必须是可比较的 (实现 Comparable 接口,传递一个 Comparator 比较器)
2:框架图
3:方法
和map类似
4:实例
public static void main(String[] args) { TreeMap treeMap = new TreeMap<>(); //添加键值对 treeMap.put(3,"Three"); treeMap.put(1,"One"); treeMap.put(4,"Four"); treeMap.put(2,"Two"); treeMap.put(5,"Five"); //输出treeMap System.out.println("TreeMap:" + treeMap); //获取键值对 System.out.println("Value of key 3:" + treeMap.get(3)); //删除键值对 treeMap.remove(5); System.out.println(treeMap); //判断是否包含指定的键或者是值 System.out.println(treeMap.containsKey(3)); System.out.println(treeMap.containsValue("One")); //输出TreeMap的键和值 System.out.println(treeMap.keySet()); System.out.println(treeMap.values()); //遍历TreeKey的键值对 for (Object key : treeMap.keySet()){ System.out.println(key); System.out.println(treeMap.get(key)); } //获取第一个值和最后一个值 System.out.println(treeMap.firstKey()); System.out.println(treeMap.lastEntry()); //获取小于等于指定键的最大值以及大于等于最小值的最小值 System.out.println(treeMap.floorKey(4)); System.out.println(treeMap.tailMap(1)); } }
三:Hashtable
1:定义方法
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable
该类实现了一个哈希表,它将键映射到值 不允许 null 作为键和值 默认初始容量( initialCapacity )为 11 ,默认负载因子( loadFactor )为 0.75f 是同步的(线程安全的) 不能保证顺序 扩容方式是旧容量的2倍 +1
2:为什么hashtable的扩容方式选择为2n+1
为了均匀分布,降低冲突率 数组 + 链表方式存储实现Hash表存储
3:添加值时
如果 hash 一样 equals 为 false 则将当前值添加到链表头 如果 hash 一样 equals 为 true 则使用当前值替换原来的值 ( key 相同)
4:构造方法
5:方法
常用方法和Map一样,在此再添加一个。
四:HashMap
1:定义方法
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable
基于哈希表的实现的Map接口
允许存null值和null键
是非线程安全的
默认容量 16,默认负载因子 0.75 HashMap容量为什么是2的n次方 扩容是 2 倍旧的容量 在存储数据时, key 的 hash 计算调用的是 HashMap 中的 hash 方法 添加值时,如果 hash 一样添加到链表尾部 HashMap 类大致相当于 Hashtable ,除了它是不同步的,并允许null
2:HashMap内部采用的存储方式
数组 + 链表实现 , JDK 8 及以后版本增加红黑树的支持。
HashMap 的 put 过程: 存储时,根据内部的 hash 方法计算 key ,来确定 value 的存储位置( Map 的桶bucket), 如果 hash 相同,在计算下标。如果产生没有碰撞( key 不相同),直接放到桶中,由于 h ash 相同,所以放到一个桶中。放的时候,如果没有超过阈值(8),以链表的形式放到后 边,长度超过阈值且数组长度大于等于64将链表转换成红黑树存储。 删除元素时,如果时以红黑树存储的如果节点小于 6 个将会变为链表存储 如果产生碰撞(节点已经存在)就替换值