12.1 Map集合
Map集合用于保存具有映射关系的数据,key和value都可以是任意类型的数据,key不允许重复。Map中包括一个内部类Entry,该类封装了一个key-value对。
Map接口中定义了如下常用方法:
- void clear():删除该Map对象中的所有key-value对。
- boolean containsKey(Object key):查询Map中是否包含指定的key,如果包含则返true。
- boolean containsValue(Object value):查询Map中是否包含一个或多个value,如果包含则返回true。
- Set entrySet():返回Map中包含的key-value对所组成的Set集合,每个集合元素都是Map.Entry对象。
- Object get(Object key):返回指定key所对应的value,如果不包含该key则返回null。
- boolean isEmpty():查询该Map 是否为空,即不包含key-value对时,如果为空则返回true。
- Set keySet():返回该Map中所有key组成的Set集合。
- Object put(Object key, Object value):添加一个key-value对,如果当前Map中已有一个与该key相等的key-value对,则新的key-value对会覆盖原来的key-value对,并返回被覆盖的值。
- void putAll(Map m):将指定Map中的key-value对复制到本Map中。
- Object remove(Object key):删除指定key所对应的key-value对,返回被删除key所关联的value,如果该key不存在,则返回null。
- int size():返回该Map里的key-value对的个数。
- Collection values():返回该Map里所有value组成的Collection。
Entry包含如下三个方法:
- Object getKey():返回该Entry里包含的key值。
- Object getValue():返该Entry里包含的value 值。
- Object setValue(V value):设置该Entry里包含的value值,并返回新设置的value值。
Java8为Map新增的方法:
- Object compute(Object key, BiFunction remappingFunction):使用remappingFunction根据原key-value对计算一个新的value。只要新value不为null,就覆盖原value;如果原value不为null,新value为null,则删除原key-value对,如果原新value都为null,则返回null,不进行任何操作。
- Object computeIfAbsent(Object key, Function mappingFunction):如果key对应的value为null,则使用mappingFunction根据key计算一个新的结果,如果新结果不为null则赋值给value;如果此Map不包含此key,则可能添加一组key-value对。
- Object computeIfPresent(Object key, BiFunction remappingFunction):如果key对应的value不为null,则使用remappingFunction根据key、value计算一个新的结果,如果新结果不为null则赋值给value;如果计算结果为null,则删除key-value对。
- void forEach(BiConsumer action):遍历key-value对的方法,接口方法将传入两个参数,即key和value。
- Object getOrDefault(Object key, V defaultValue):获取key对应的value,如果key不存在,则返回默认值。
- Object merge(Object key, Object value, BiFunction remappingFunction):获取key对应的value。如果value为null,则直接用向原value传入上面value值;如果value不为null,则根据原value和上面value计算一个新的结果去覆盖原value。
- Object putIfPresent(Object key, Object value):如果key对应的value为null,则赋值新value。
- Object replace(Object key, Object value):将key对应的value替换为新value。如果key不存在,则不会增加新的key-value对,并返回null。
- Object replace(K key, V oldValue, V newValue):若找到指定的key-value对,则用新value替换旧value,并返回true,否则返回false。
- Object replaceAll(BiFunction function):使用function对原key-value对计算产生一个新value。
- Object remove(Object key, Object value):删除指定key、value所对应的key-value对。成功删除返回true,否则返回false。
12.2 HashMap类
Java8改进了HashMap的实现,在key冲突时依然具有较好的性能。
Hash允许使用null作为key或value。为了成功的在HashMap中存储、获取对象,key的对象必须实现hashCode方法和equals方法,key的判定标准和重写规则与HashSet相同,value的判定标准为:只要两个对象通过equals方法比较返回ture即可。
可变类作为key时,可能的错误与HashSet相同,即只能删除key没有被修改过的key-value对。
12.3 LinkedHashMap类
LinkedHashMap是HashMap的子类,使用双向链表维护key-value对的次序,迭代顺序与key-value对的插入顺序保持一致。
12.4 Properties类
Properties是Hashtable的子类,处理属性文件时比较方便。Properties里的key、value都是字符串类型。
定义了如下三个操作方法:
- String getProperty(String key):获取Properties中指定属性名对应的属性值,类似于Map的
get(Object key)方法。
- String getProperty(String key, String defaultValue):该方法与前一个方法基本相似。该方法多一个功能,如果Properties中不存在指定的key时,则该方法指定默认值。
- Object setProperty(String key, String value):设置属性值。
两个读写Field文件的方法:
- void load(InputStream is):从属性文件中加载key-value对,把加载到的一key-value对追加到Properties里,不保证key-value对的顺序。
- void store(OuputStream out, String comments):将Properties中的key-value对输出到指定的属性文件中。
12.5 TreeMap类
TreeMap类实现了SortedMap接口,采用红黑树结构存储key-value对,根据key进行排序。可以采用自然排序或定制排序两种方式。如果两个key比较时返回0,则认为两个key相等。equals和比较方法重写时应保持一致。
TreeMap增加的方法:
- Map.Entry firstEntry():返该Map中最小key所对应的key-value对。Map为空则返回null。
- Object firstKey():返回该Map中的最小key值。Map为空返回null。
- Map.Entry lastEntry():返回Map中最大key所对应的key-value对,Map为空或不存在这样的key-value 对,则都返可null。
- Object lastKey():返该Map中的最大key值,如果Map为空或不存在此key,则都返回null。
- Map.Entry higherEntry(Object key):返回Map中大于指定key的最小key所对应的key-value 对。如果该Map为空,则返回null。
- Object higherKey(Obiect o):返回该Map中位于key后一位的key值(即大于指定key的最小key值)。如果该Map 为空或不存在这样的key-value对,则都返回null。
- Map.Entry lowerEntry(Object o):返回该Map中位于key前一位的key-value对(即小于指定key的最大key 所对应的key-value对)。如果该Map为空或不存在这样的key-value对,则都返回null。
- Object lowerKey(Object key):返回该Map中位于key前一位的key值(即小于指定key的最大
key值)。如果该Map为空或不存在这样的key,则都返回null。
- NavigableMap subMap(Object fromKey, boolean fromInclusive, Object toKey, boolean toInclusive):返回该Map的子Map,其key的范围是从fromKey(是否包括取决于第二个参数)到toKey(是否包括取决于第四个参数)。
- SortedMap subMap(Object fromKey, Object toKey):返回该Map的子Map,其key的范围是从fromKey(包括)到toKey(不包括)。
- SortedMap tailMap(Object fromKey):返回该Map 的子Map,其 key的范围是大fromKey(包括)的所有key。
- NavigableMap tailMap(Object fromKey, boolean inclusive):返回该Map的子Map,其key的范围是大于fromKey(是否包括取决于第二个参数)的所有key。
- SortedMap headMap(Object toKey):返回该Map的子Map,其key的范围是小于toKey(不包括)的所有key。
- NavigableMap headMap(Object toKey, boolean inclusive): 返回该Map的子Map,其key范围是小于toKey(是否包括取决于第二个参数)的所有key。
12.6 WeakHashMap类
用法与HashMap基本相似。
WeakHashMap的key只保留了对实际对象的弱引用,这代表如果WeakHashMap对象的key所引用的对象没有被其他强引用变量所引用,则这些key所引用的对象可能被垃圾回收,WeakHashMap也可能自动删除这些key对应的key-value对。
当回收了该key所对应的实际对象之后,WeakHashMap会自动删除该key对应的key-value对。
12.7 IdentityHashMap类
用法与HashMap基本相似。
在IdentityHashMap中,当且仅当两个key以==比较相等时,才认为两个key相等。IdentityHashMap允许key和value的值为null。
12.8 EnumMap类
EnumMap中的所有key都必须是同一个枚举类的枚举值。创建EnumMap时,必须显示或隐式指定枚举类。EnumMap提供了根据枚举类创建对象的构造器。
EnumMap具有如下特征:
- EnumMap内部以数组形式保存,数据紧凑、高效。
- EnumMap根据key在枚举类中的顺序维护key-value对的顺序。
- EnumMap不允许使用null作为key,但允许使用null作为value。
12.9 各Map实现类的性能分析
TreeMap通常比HashMap要慢,尤其是插入、删除key-value对时。但TreeMap的key-value对总是处于有序状态。在需要快速查询的Map集合时,可以选择使用HashMap;在需要一个元素能排序的Map集合时,可以选择使用TreeMap。
LinkedHashMap比HashMap慢,因为内部使用链表维护key-value对的添加顺序。
IdentityHashMap性能没有什么出色之处,实现方式与HashMap基本相似。
EnumMap性能最好,但它只能以某一个枚举类的枚举值作为key。
12.10 HashSet和HashMap的性能选项
都是使用hash算法来决定元素或key的存储位置,并通过hash算法控制集合的大小。hash表里可以存储元素的位置被称为“桶”,发生“hash冲突”时,以链表形式存储冲突的元素。
HashSet和HashMap的hash表包含如下属性:
- 容量(capacity):hash表中桶的数量。
- 初始化容量(initial capacity):创建hash表时桶的数量。HashSet和HashMap两个集合都允许在构造器中指定初始化容量。
- 尺寸(size):当前hash表中记录的数量。
- 负载因子(load factor):负载因子=size/capacity。负载因子为0时,表明hash为空表。
- 负载极限:决定了hash表的最大填满程度。当hash表中的负载因子到达负载极限时,hash表就会成倍的增加容量,并将原有对象放入新桶内。默认负载极限为0.75。