7.5 Map
Map 有时也被称为字典,或关联数组。
Map 中 key 无序,不能重复;value 可以重复。
Map 接口里定义了如下常用方法:
- void clear():删除该 Map 对象中所有 key-value 对。
- boolean containsKey(Object key):查询 Map 中是否包含指定 key。
- boolean containsValue(Object value)
- Set entrySet():返回 Map 中所包含的 key-value 对所组成的 Set 集合,每个集合元素都是 Map.Entry(Entry 是 Map 的内部类)对象。
- Object get(Object key):返回指定 key 所对应的 value。
- boolean isEmpty():查询该 Map 是否为空,若是则返回 true。
- Set keySet():返回该 Map 中所有 key 所组成的 Set 集合。
- Object put(Object key, Object value):添加一个 key-value 对,若 key 以存在,则新的 key-value 对会覆盖旧的。
- void putAll(Map m):添加集合 m 中的所有 key-value 对。
- Object remove(Object key):删除指定 key 所对应的 key-value 对,删除成功,则返回其 value;若该 key 不存在,则返回 null。
- int size():返回该 Map 里 key-value 对的个数。
- Collection values():返回该 Map 里所有 value 组成的 Collection。
Map 中包含一个内部类:Entry。该类封装了一个 key-value 对,Entry 包含三个方法:
- Object getKey():返回该 Entry 里包含的 key 值。
- Object getValue():返回该 Entry 里包含的 value 值。
- Object setVaule(V value):设置该 Entry 里包含的 value 值,并返回旧的 value 值。
7.6 HashMap 和 Hashtable 实现类
Hashtable 是一个古老的 Map 实现类,从 JDK1.0 起就出现了。
HashMap 和 Hashtable 两点典型区别:
- Hashtable 线程安全,HashMap 线程不安全,所以 HashMap 性能更高一些。
- Hashtable 不允许使用 null 作为 key 和 value,如果把 null 值放进 Hashtable 中,会引发 NullPointerException 异常;而 HashMap 可以使用 null 作为 key 或 value。
HashMap、Hashtable 的特点:
- 不保证 key-value 对的顺序。
- 判断两个 key 相等的标准:两个 key 通过 equals 方法返回 true,两个 key 的 hashCode 值也相等。
- 判断两个 value 相等的标准:两个 value 通过 equals 比较返回 true。
- 包含一个 containsValue 方法用于判断是否包含指定的 value。
7.6.1 LinkedHashMap
LinkedHashMap 是 HashMap 的子类,使用双向链表来维护 key-value 对的插入顺序。迭代输出 LinkedHashMap 的元素时,将会按 key-value 对的添加顺序输出。
7.6.2 Properties
Properties 类是 Hashtable 类的子类。
由于属性文件里的属性名、属性值只能是字符串类型,所以 Properties 里的 key、value 都是字符串类型。
Properties 里的方法:
- String getProperty(String key):获取指定属性名所对应的属性值。
- String getProperty(String key, String defaultValue):与前一个方法基本相似,但多一个功能:如果 Properties 中不存在指定的 key 时,返回默认值 defaultValue。
- Object setProperty(String key, String value):设置属性值。
- void load(InputStream inputStream):将属性文件(以输入流表示)中的属性名=属性值加载到 Properties 里。(由于 Properties 是 Hashtable 的子类,故不能保证 key-value 对之间的顺序)
- void store(OutputStream out, String comments):将 Properties 中的 key-value 对写入指定的属性文件(以输出流表示)。
7.7 SortedMap 接口和 TreeMap 实现类
SortedMap 是 Map 的子接口,TreeMap 是 SortedMap 的实现类。
TreeMap 基于红黑树对所有的 key 进行排序,排序方式有两种:
- 自然排序:TreeMap 的所有 key 必须实现 Comparable 接口,而且所有 key 应该是同一个类的对象,否则会抛出 ClassCastException 异常。
- 定制排序:创建 TreeMap 时,传入一个 Comparator 对象,该对象负责对 TreeMap 中所有 key 进行排序,此时 key 不要求实现 Comparable 接口。
TreeMap 中判断两个 key 相等的标准是两个 key 通过 equals 比较返回 true,通过 compareTo 比较返回0。
TreeMap 中根据 key 顺序来访问 Map 中 key-value 对的方法:
- Map.Entry firstEntry():返回该 Map 中最小 key 所对应的 key-value 对,如果 Map 为空,则返回 null 。
- Map.Entry lastEntry()
- Object firstKey():返回该 Map 中最小的 key 值。如果该 Map 为空,则返回 null。
- Object lastKey()
- Map.Entry higherEntry(Object key):返回该 Map 中位于指定 key 后一个位的 key-value 对。如果该 Map 为空,则返回 null。
- Map.Entry lowerEntry(Object key)
- Object higherKey(Object key):返回位于指定 key 后一位的 key 值。若无,则返回 null。
- Object lowerEntry(Object key)
- NavigableMap subMap(Object fromKey, boolean fromInclusive, Object toKey, boolean toInclusive):返回该 Map 的子 Map,其 key 的范围从 fromKey (是否包含取决于第二个参数),到 toKey (是否包含取决于第四个元素)。
- NavigableMap tailMap(Object fromKey, boolean inclusive)
- NavigableMap headMap(Object toKey, boolean inclusive)
- SortedMap subMap(Object fromKey, Object toKey):返回该 Map 的子 Map,其 key 的范围从 fromKey (包括)到 toKey (不包括)。
- SortedMap tailMap(Object fromKey)
- SortedMap headMap(Object toKey)
7.8 WeakHashMap 实现类
WeakHashMap 与 HashMap 的用法基本相似,区别在于:
- HashMap 的 key 保留对实际对象的强引用,因此,只要该 HashMap 对象不被销毁,key 所引用的对象就不会被垃圾回收。
- WeakHashMap 的 key 只保留对实际对象的弱引用,key 所引用的对象可能会被垃圾回收,之后 WeakHashMap 会删除对应的 key-value 对。
如果需要使用 WeakHashMap 的 key 来保留对象的弱引用,则不要让该 key 所引用的对象具有任何强引用,否则将失去使用 WeakHashMap 的意义。
7.9 IdentityHashMap 实现类
IdentityHashMap 与 HashMap 基本相似,区别是:
- HashMap 中两个 key 相等的标准是:通过 equals 方法比较返回 true,并且 hashCode 的值相等;
- IdentityHashMap 中两个 key 相等的标准是:key1 == key2。
7.10 EnumMap 实现类
EnumMap 的特点:
- 所有 key 都必须是同一个枚举类的枚举值。
- 创建 EnumMap 时必须显式或隐式指定它对应的枚举类。
- 在内部以数组的形式保存。
- 根据 key 的自然顺序(即枚举值在枚举类中的定义顺序)来维护 key-value 对的顺序。
- 不允许使用 null 作为 key 值,但可以作为 value 值。
例子:
enum Season {
SPRING,SUMMER,FALL,WINTER;
}
public class Test {
public static void main(String[] agrs) {
EnumMap m = new EnumMap(Season.class);
m.put(Season.SPRING, "春天");
}
}