4. 键值对
4.1 java.util 接口 Map<K,V>
- 将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
- Map 接口提供三种collection 视图,允许以键集、值集或键-值映射关系集的形式查看某个映射的内容。
- 所有已知实现类:
HashMap
,Hashtable
,TreeMap
。 - Map和Collection的区别?
A:Map 存储的是键值对形式的元素,键唯一,值可以重复。
B:Collection 存储的是单独出现的元素,子接口Set元素唯一,子接口List元素可重复。
嵌套类
- Map.Entry<K,V> 映射项(键-值对):public static interface Map.Entry<K,V>
- Map.Entry<K,V>中 Entry<K,V> 为Map接口的内部接口,定义了数据类型为键值对。
- HashMap中Entry<K,V>实现并扩展了Map.Entry<K,V>,定义为元素为数组中的链表头结点。
- TreeMap中Entry<K,V>实现并扩展了Map.Entry<K,V>,定义为元素为三叉链表,包含孩子和父指针。
- 其中设计采用了接口的内部接口,类的静态内部类的方式。
抽象方法
添加功能 put
- V put(K key, V value):将指定的值与此映射中的指定键关联,返回以前与 key 关联的值,如果没有针对 key 的映射关系,则返回 null。
- void putAll(Map<? extends K,? extends V> m):从指定映射中将所有映射关系复制到此映射中。
删除功能 remove
- void clear():从此映射中移除所有映射关系。
- V remove(Object key):如果存在一个键的映射关系,则将其从此映射中移除,返回此映射中以前关联该键的值,如果此映射不包含该键的映射关系,则返回 null。
判断功能 containsKey
, containsValue
- boolean containsKey(Object key):如果此映射包含指定键的映射关系,则返回 true。
- boolean containsValue(Object value):如果此映射将一个或多个键映射到指定值,则返回 true。
- boolean equals(Object o):比较指定的对象与此映射是否相等。
- boolean isEmpty():如果此映射未包含键-值映射关系,则返回 true。
获取功能 entrySet
, keySet
, values
, get
, size
- Set<Map.Entry<K,V>> entrySet():返回此映射中包含的映射关系的 Set 视图,得到键值对。
- Set keySet():返回此映射中包含的键的 Set 视图。
- Collection values():返回此映射中包含的值的 Collection 视图。
- V get(Object key):返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
- int hashCode():返回此映射的哈希码值。
- int size():返回此映射中的键-值映射关系数。如果该映射包含的元素大于 Integer.MAX_VALUE,则返回 Integer.MAX_VALUE。
知识扩展
Map集合的遍历
A:键找值
a:获取所有键的集合
b:遍历键的集合,得到每一个键
c:根据键到集合中去找值
B:键值对对象找键和值
a:获取所有的键值对对象的集合
b:遍历键值对对象的集合,获取每一个键值对对象
c:根据键值对对象去获取键和值
代码体现:
Map<String,String> hm = new HashMap<String,String>();
hm.put("it002","hello");
hm.put("it003","world");
hm.put("it001","java");
//方式1 键找值
Set<String> set = hm.keySet();
for(String key : set) {
String value = hm.get(key);
System.out.println(key+"---"+value);
}
//方式2 键值对对象找键和值
Set<Map.Entry<String,String>> set2 = hm.entrySet();
for(Map.Entry<String,String> me : set2) {
String key = me.getKey();
String value = me.getValue();
System.out.println(key+"---"+value);
}
4.2 java.util 类 HashMap<K,V>
- 基于哈希表的 Map 接口的实现,HashSet集合也是基于HashMap实现。
- 底层数据结构是哈希表(是一个元素为链表的数组)。
- 此类为基本操作提供了稳定性能,这些基本操作包括 add、remove、contains 和 size。
- 此实现不是同步,线程不安全。
- 除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。
- HashMap 的实例有两个参数影响其性能:初始容量和加载因子。
- 默认加载因子 (0.75) 在时间和空间成本上寻求一种折衷。加载因子过高虽然减少了空间开销,但同时也增加了查询成本。
具体方法(参考Map即可)
嵌套类
- 类 AbstractMap.SimpleEntry<K,V> 映射项(键-值对):public static class AbstractMap.SimpleEntry<K,V>
- 类 AbstractMap.SimpleImmutableEntry<K,V>:维护不可变的键和值的 Entry。此类不支持 setValue 方法。
- 均实现了Map.Entry<K,V>其中的方法,但没有实际意义。因为HashMap和TreeMap中的Entry<K,V>是实现了Map.Entry<K,V>内部接口,并不是实现了AbstractMap中的内部类。
构造方法
- public HashMap():构造一个映射关系与指定 Map 相同的新 HashMap。所创建的 HashMap 具有默认加载因子 (0.75) 和足以容纳指定 Map 中映射关系的初始容量。
- public HashMap(int initialCapacity):构造一个带指定初始容量和默认加载因子 (0.75) 的空 HashMap。
- public HashMap(int initialCapacity, float loadFactor):构造一个带指定初始容量和加载因子的空 HashMap。
- public HashMap(Map<? extends K,? extends V> m):构造一个映射关系与指定 Map 相同的新 HashMap。
4.3 java.util 类 TreeMap<K,V>
- 基于红黑树(Red-Black tree)的 NavigableMap 实现。
- 该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法。
- 此实现为 containsKey、get、put 和 remove 操作提供受保证的 log(n) 时间开销。
- 此实现不是同步,线程不安全。
具体方法
嵌套类(与hashMap相同)
构造方法
- public TreeMap():使用键的自然顺序构造一个新的、空的树映射。
- public TreeMap(Comparator<? super K> comparator):构造一个新的、空的树映射,该映射根据给定比较器进行排序。
- public TreeMap(Map<? extends K,? extends V> m):构造一个与给定映射具有相同映射关系的新的树映射,该映射根据其键的自然顺序 进行排序。
特殊方法(主要利用了tree结构中key的排序功能)
返回键值对
- public Map.Entry<K,V> ceilingEntry(K key):返回一个键-值映射关系,它与大于等于给定键的最小键关联;如果不存在这样的键,则返回 null。
- public Map.Entry<K,V> floorEntry(K key):返回一个键-值映射关系,它与小于等于给定键的最大键关联;如果不存在这样的键,则返回 null。
- public Map.Entry<K,V> higherEntry(K key):返回一个键-值映射关系,它与严格大于给定键的最小键关联;如果不存在这样的键,则返回 null。
- public Map.Entry<K,V> lowerEntry(K key):返回一个键-值映射关系,它与严格小于给定键的最大键关联;如果不存在这样的键,则返回 null。
- public Map.Entry<K,V> firstEntry():返回一个与此映射中的最小键关联的键-值映射关系;如果映射为空,则返回 null。
- public Map.Entry<K,V> lastEntry():返回与此映射中的最大键关联的键-值映射关系;如果映射为空,则返回 null。
- public Map.Entry<K,V> pollFirstEntry():移除并返回与此映射中的最小键关联的键-值映射关系;如果映射为空,则返回 null。
- public Map.Entry<K,V> pollLastEntry():移除并返回与此映射中的最大键关联的键-值映射关系;如果映射为空,则返回 null。
返回键
- public K ceilingKey(K key):返回大于等于给定键的最小键;如果不存在这样的键,则返回 null。
- public K floorKey(K key):返回小于等于给定键的最大键;如果不存在这样的键,则返回 null。
- public K higherKey(K key):返回严格大于给定键的最小键;如果不存在这样的键,则返回 null。
- public K lowerKey(K key):返回严格小于给定键的最大键;如果不存在这样的键,则返回 null。
- public K firstKey():返回此映射中当前第一个(最低)键。
- public K lastKey():返回映射中当前最后一个(最高)键。
4.4 java.util 类 Hashtable<K,V>
- 此类实现一个哈希表,该哈希表将键映射到相应的值。
- 同步,线程安全。
特殊方法(其余参考HashMap即可)
- public Enumeration elements():返回此哈希表中的值的枚举。
- public Enumeration keys():返回此哈希表中的键的枚举。
- protected void rehash():增加此哈希表的容量并在内部对其进行重组,以便更有效地容纳和访问其元素。当哈希表中的键的数量超出哈希表的容量和加载因子时,自动调用此方法。
4.5 java.util 接口 Map.Entry<K,V>
- public static interface Map.Entry<K,V>,Map接口的内部接口。
- 定义了数据类型为映射项(键-值对)。
抽象方法 getKey
, getValue
, setValue
- boolean equals(Object o):比较指定对象与此项的相等性。
- K getKey():返回与此项对应的键。
- V getValue():返回与此项对应的值。
- int hashCode():返回此映射项的哈希码值。
- V setValue(V value):用指定的值替换与此项对应的值。
知识扩展
java中外部接口与内部接口的使用
新建一个非抽象类(普通类)实现接口如下:
1、普通类实现了接口,那么就必须实现接口中的所有方法
2、那么反过来没有实现接口中的方法的类就是抽象类
3、一个类可以实现多个接口
这里用内部类的好处就是:
1、当你只实现外部接口,那么只需实现外部接口的方法即可(内部接口是调不到的)。
2、而实现内部接口的方式是“外部接口.内部接口”,那么就可以实现内部接口的方法了。通过这个方法,可以将外部接口和内部接口分开实现,一般内部接口中的方法只在 3、内部接口也是一种数据类型。
参考链接:https://www.jianshu.com/p/ab539e9a7955
4.6 java.util 类 AbstractMap.SimpleEntry<K,V>
- 是AbstractMap的内部类,实现了 Map.Entry<K,V>
- 维护键和值的 Entry。可以使用 setValue 方法更改值。
- 具体方法看 Map.Entry<K,V>即可。
4.7 综合比较
底层实现 | 是否线程安全 | |
---|---|---|
HashMap<K,V> | hash表(元素为链表的数组) | 不安全 |
TreeMap<K,V> | 树(三叉链表) | 不安全 |
Hashtable<K,V> | hash表(元素为链表的数组) | 安全 |