8.6 Java 8增强的Map集合
8.6 Java 8增强的Map集合
Map
用于保存具有映射关系的数据,因此Map
集合里保存着两组值,一组值用于保存Map
里的key
,另外一组值用于保存Map
里的value
,key
和value
都可以是任何引用类型的数据。
Map的key不可重复
Map
的key
不允许重复,即同一个Map
对象的任何两个key
通过equals()
方法比较总是返回false
一个key对应一个value
key
和value
之间存在单向一对一关系,即通过指定的key
,总能找到唯一的、确定的value
。
根据key来获取value
从Map
中取出数据时,只要给出指定的key
,就可以取出对应的value
。
如果把Map
的两组值拆开来看,Map
里的数据有如图8.7所示的结构。
Map中的所有key可以看成一个Set集合
从图8.7中可以看出,如果把Map
里的所有key
放在一起来看,它们就组成了一个Set
集合(所有的key
没有顺序,key
与key
之间不能重复)。
keySet()方法
实际上Map
确实包含了一个keySet()
方法,用于返回Map
里所有key
组成的Set
集合。
方法 | 描述 |
---|---|
Set<K> keySet() |
Returns a Set view of the keys contained in this map. |
不仅如此,Map
里key
集和Set
集合里元素的存储形式也很像,Map
子类和Set
子类在名字上也惊人地相似,比如Set
接口下有HashSet
、 LinkedHashSet
、 SortedSet
(接口)、 TreeSet
、 EnumSet
等子接口和实现类,而Map
接口下则有HashMap
、 LinkedHashMap
、 SortedMap
(接口)、 TreeMap
、 EnumMap
等子接口和实现类。正如它们的名字所暗示的,Map
的这些实现类和子接口中key
集的存储形式和对应Set
集合中元素的存储形式完全相同。
提示
Set
与Map
之间的关系非常密切。虽然Map
中放的元素是key-value
对,Set
集合中放的元素是单个对象,但如果把key-value
对中的value
当成key
的附庸:key
在哪里, value
就跟在哪里。这样就可以像对待Set
一样来对待Map
了。事实上,Map
提供了一个Entry
内部类来封装key-value
对,而计算Entry
存储时则只考虑Entry
封装的key
。
Map 接口的内部接口Entry |
描述 |
---|---|
static interface Map.Entry<K,V> |
A map entry (key-value pair). |
Java使用Map来实现Set
从Java
源码来看,Java
是先实现了Map
,然后通过包装一个所有value
都为null
的Map
就实现了Set
集合。
Map中的的所有value可以看成一个List集合
如果把Map
里的所有value
放在一起来看,它们又非常类似于一个List
:
- 元素与元素之间可以重复,每个元素可以根据索引来查找,只是
Map
中的索引不再使用整数值,而是以另一个对象作为索引。 - 如果需要从
List
集合中取出元素,则需要提供该元素的数字索引; - 如果需要从
Map
中取出元素,则需要提供该元素的key
索引。
因此,Map
有时也被称为字典
,或关联数组
。
Map接口方法
Map
接口中定义了如下常用方法。
添加元素的方法
方法 | 描述 |
---|---|
V put(K key, V value) |
添加一个key-value 对,如果当前Map 中已有一个与该key 相等的key-value 对,则新的key-value 对会覆盖 原来的key-value 对。 |
void putAll(Map<? extends K,? extends V> m) |
将指定Map 中的key-value 对复制到当前Map 中。 |
查询方法
方法 | 描述 |
---|---|
Object get(Object key) |
返回指定key 所对应的value ;如果此Map 中不包含该key ,则返回null 。 |
int size() |
返回该Map 里的key-value 对的个数。 |
删除元素的方法
方法 | 描述 |
---|---|
V remove(Object key) |
删除指定key 所对应的key-value 对,返回被删除key 所关联的value ,如果该key 不存在,则返回null 。 |
default boolean remove(Object key, Object value) |
这是Java8 新增的方法,删除指定key ,value 所对应的key-value 对。如果从该Map 中成功地删除该key-value 对,该方法返回true ,否则返回false 。 |
void clear() |
删除该Map 对象中的所有key-value 对. |
判断方法
方法 | 描述 |
---|---|
boolean isEmpty() |
查询该Map 是否为空(即不包含任何key-value 对),如果为空则返回true 。 |
boolean containsKey(object key) |
查询Map 中是否包含指定的key ,如果包含则返回true |
boolean containsValue(Object value) |
Returns true if this map maps one or more keys to the specified value. |
返回集合
方法 | 描述 |
---|---|
Set keySet() |
返回该Map 中所有key 组成的Set 集合。 |
Set entrySet() |
返回Map 中包含的key-value 对所组成的Set 集合,每个集合元素都是 Map.Entry 对象(Entry 是Map 的内部类)。 |
Collection values() |
返回该Map 里所有 value 组成的 Collection |
Map的实现类
Map
接口提供了大量的实现类,典型实现如HashMap
和Hashtable
等、 HashMap
的子类LinkedHashMap
,还有SortedMap
子接口及该接口的实现类TreeMap
,以及WeakHashMap
、IdentityHashMap
等。下面将详细介绍Map
接口实现类。
Map的内部类Entry
Map
中包括一个内部类Entry
,该类封装了一个key-value
对。 Entry
包含如下三个方法。
Mapt.Entry 内部接口的方法 |
描述 |
---|---|
K getKey() |
返回该Entry 里包含的key 值。 |
V getValue() |
返回该Entry 里包含的value 值。 |
V setValue(V value) |
设置该Entry 里包含的value 值,并返回新设置的value 值。 |
Map
集合最典型的用法就是成对地添加
、删除
key-value
对,接下来即可判断该Map
中是否包含指定key
,是否包含指定value
,也可以通过Map
提供的keySet()
方法获取所有key
组成的集合,进而遍历Map
中所有的key-value
对。
程序 Map接口基本用法
下面程序示范了Map
的基本功能。
1 | import java.util.*; |
运行结果:
1 | 10 |
上面程序中先示范了向Map
中成对地添加key-value
对。添加key-value
对时,Map
允许多个value
重复,但如果添加key-value
对时Map
中已有重复的key
,那么新添加的value
会覆盖该key
原来对应的value
并返回被覆盖的value
。
程序接下来的代码分别判断了Map
集合中是否包含指定的key
、是否包含指定的value
。
使用foreach循环 遍历Map集合
程序中的foreach
循环用于遍历Map
集合:
- 先调用
Map
集合的keySet()
获取包含所有key
的Set集合, - 然后使用
foreach
循环来遍历这个Set集合中的key, - 最后根据
key
来获取对应的value
。
所有的Map
实现类都重写了toString()
方法,调用Map
对象的toString()
方法总是返回如下格式的字符串:{key1=value,key2=value2…}
.