Java Map映射接口的用法(非常详细)
Collection 接口操作的时候每次都会向集合中增加一个元素,但是如果现在增加的元素是一个键值对,可以使用 Map 接口完成。
Map 接口是一个专门用来存储键/值对的对象。在 Map 接口中存储的关键字和值都必须是对象,并要求关键字唯一,而值可以重复。
Map 接口常用的实现类有 HashMap 类、LinkedHashMap 类、TreeMap 类和 Hashtable 类,前三个类的行为和性能与 Set 接口实现类 HashSet、LinkedHashSet 及 TreeSet 类似。
Map 接口及实现类的层次关系如下图所示:

图 1 Map接口及实现类的层次结构
Map<K,V> 接口定义在 java.util 包中,主要定义三类操作方法:修改、查询和集合视图。
1) 修改操作向映射中添加和删除键值对,具体方法如下:
2) 查询操作获得映射的内容,具体方法如下。
3) 集合视图允许将键、值或条目(键值对)作为集合处理,具体方法如下:
在 Map 接口中还包含一个 Map.Entry<K, V> 接口。它是一个使用 static 定义的内部接口,所以就是一个外部接口。其方法描述如下:
【实例】创建一个 HashMap 集合,向其中加入一些键值对,然后根据键获取值,并输出集合中所有键值对。
另外在 HashMap 中的 key 允许为 null。可以把 HashMapDemo.java 修改为如下代码:
TreeMap 类实现了 SortedMap 接口。SortedMap 接口能保证各项按关键字升序排序。TreeMap 类的构造方法如下:
对于程序 HashMapDemo.java 来说,如果希望键按照字母顺序输出,仅将 HashMap 类改为 TreeMap 类即可。
【实例】创建 TreeMap 类集合,向其中添加键值对,然后输出。
任何非 null 对象都可以作为哈希表的关键字和值。但是要求作为关键字的对象必须实现 hashCode() 方法和 equals() 方法,以使对象的比较成为可能。
有两个参数影响一个 Hashtable 类实例的性能:初始容量(initial capacity)和装填因子(load factor)。
Hashtable 类的构造方法如下:
下面的代码创建了一个包含数字的哈希表对象,使用数字名作为关键字:
要检索其中的数字,可以使用如下代码:
Map 对象与 Hashtable 对象的区别如下:
Map 接口是一个专门用来存储键/值对的对象。在 Map 接口中存储的关键字和值都必须是对象,并要求关键字唯一,而值可以重复。
Map 接口常用的实现类有 HashMap 类、LinkedHashMap 类、TreeMap 类和 Hashtable 类,前三个类的行为和性能与 Set 接口实现类 HashSet、LinkedHashSet 及 TreeSet 类似。
Hashtable 类是 Java 早期版本提供的类,经过修改实现了 Map 接口。
Map 接口及实现类的层次关系如下图所示:

图 1 Map接口及实现类的层次结构
Map<K,V> 接口定义在 java.util 包中,主要定义三类操作方法:修改、查询和集合视图。
1) 修改操作向映射中添加和删除键值对,具体方法如下:
- public V put(K key,V value):将指定的值与此映射中的指定键关联。
- public V remove(K key):如果存在一个键的映射关系,则将其从此映射中移除。
- public void putAll(Map<? extends K,? extends V> m):从指定映射中将所有映射关系复制到此映射中。
2) 查询操作获得映射的内容,具体方法如下。
- public V get(k key):返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
- public boolean containsKey(Object key):如果此映射包含指定键的映射关系,则返回 true。
- public boolean containsValue(Object value):如果此映射将一个或多个键映射到指定值,则返回 true。
3) 集合视图允许将键、值或条目(键值对)作为集合处理,具体方法如下:
- public Collection<V> values():返回此映射中包含的值的 Collection 接口视图。
- public Set<K> keySet():返回此映射中包含的键的 Set 接口视图
- public Set entrySet():返回此映射中包含的映射关系的 Set 接口视图。
在 Map 接口中还包含一个 Map.Entry<K, V> 接口。它是一个使用 static 定义的内部接口,所以就是一个外部接口。其方法描述如下:
- public V setValue(V value):用指定的值替换与此项对应的值。
- public K getKey():返回与此项对应的键。
- public V getValue():返回与此项对应的值。
- public boolean equals(Object o):比较指定对象与此项的相等性。如果给定对象也是一个映射项,并且两个项表示相同的映射关系,则返回 true。
Java Map接口的实现类
Map 接口常用的实现类有 HashMap 类、TreeMap 类和 Hashtable 类。1) HashMap类与LinkedHashMap类
HashMap 类的构造方法如下:- HashMap():创建一个空的映射对象,使用默认的装填因子(0.75)。
- HashMap(int initialCapacity):用指定的初始容量和默认的装填因子(0.75)创建一个映射对象。
- HashMap(int initialCapacity, float loadFactor):用指定的初始容量和指定的装填因子创建一个映射对象。
- HashMap(Map t):用指定的映射对象创建一个新的映射对象。
【实例】创建一个 HashMap 集合,向其中加入一些键值对,然后根据键获取值,并输出集合中所有键值对。
import java.util.HashMap; import java.util.Map; public class HashMapDemo { public static void main(String[] args) { Map<String, String> all = new HashMap<String, String>(); all.put("BJ", "Beijing"); all.put("NJ", "NanJing"); String value = all.get("BJ"); // 根据 key 查询 value System.out.println(value); System.out.println(all.get("TJ")); System.out.println(all); } }程序执行结果为:
Beijing
null
{BJ=Beijing, NJ=NanJing}
另外在 HashMap 中的 key 允许为 null。可以把 HashMapDemo.java 修改为如下代码:
import java.util.HashMap; import java.util.Map; public class HashMapDemo1 { public static void main(String[] args) { Map<String, String> all = new HashMap<String, String>(); all.put("BJ", "BeiJing"); all.put("NJ", "NanJing"); all.put(null, "NULL"); System.out.println(all.get(null)); } }运行结果输出:
NULL
LinkedHashMap 类是 HashMap 类的子类,它保持键的顺序与插入的顺序一致。它的构造方法与 HashMap 的构造方法类似,在此不再赘述。2) TreeMap类
HashMap 子类中的 key 都是无序存放。如果希望有序(按 key 排序),可以使用 TreeMap 类完成。但是需要注意的是,由于此类需要按照 key 进行排序,而且 key 本身也是对象,那么对象所在的类就必须实现 Comparable 接口。TreeMap 类实现了 SortedMap 接口。SortedMap 接口能保证各项按关键字升序排序。TreeMap 类的构造方法如下:
- TreeMap():创建根据键的自然顺序排序的空的映射。
- TreeMap(Comparator c):根据给定的比较器创建一个空的映射。
- TreeMap(Map m):用指定的映射创建一个新的映射,根据键的自然顺序排序。
- TreeMap(SortedMap m):在指定的 SortedMap 对象中创建新的 TreeMap 对象。
对于程序 HashMapDemo.java 来说,如果希望键按照字母顺序输出,仅将 HashMap 类改为 TreeMap 类即可。
【实例】创建 TreeMap 类集合,向其中添加键值对,然后输出。
import java.util.Map; import java.util.TreeMap; public class TreeMapDemo { public static void main(String[] args) { Map<String, String> all = new TreeMap<String, String>(); all.put("BJ", "BeiJing"); all.put("NJ", "NanJing"); String value = all.get("BJ"); // 根据 key 查询 value System.out.println(value); System.out.println(all.get("TJ")); System.out.println(all); } }程序执行结果为:
BeiJing
null
{BJ=BeiJing, NJ=NanJing}
3) Hashtable类
Hashtable 类实现了一种哈希表,是 Java 早期版本提供的一个存放键值对的实现类,现在也属于集合框架。但哈希表对象是同步的,即是线程安全的。任何非 null 对象都可以作为哈希表的关键字和值。但是要求作为关键字的对象必须实现 hashCode() 方法和 equals() 方法,以使对象的比较成为可能。
有两个参数影响一个 Hashtable 类实例的性能:初始容量(initial capacity)和装填因子(load factor)。
Hashtable 类的构造方法如下:
- Hashtable():使用默认的初始容量(11)和默认的装填因子(0.75)创建一个空的哈希表。
- Hashtable(int initialCapacity):使用指定的初始容量和默认的装填因子(0.75)创建一个空的哈希表。
- Hashtable(int initialCapacity, float loadFactor):使用指定的初始容量和指定的装填因子创建一个空的哈希表。
- Hashtable(Map<? extends K, ? extends V> t) 使用给定的 Map 对象创建一个哈希表。
下面的代码创建了一个包含数字的哈希表对象,使用数字名作为关键字:
Hashtable numbers = new Hashtable(); numbers.put("one", new Integer(1)); numbers.put("two", new Integer(2)); numbers.put("three", new Integer(3));
要检索其中的数字,可以使用如下代码:
Integer n = (Integer) numbers.get("two"); if (n != null) { System.out.println("two = " + n); }
Map 对象与 Hashtable 对象的区别如下:
- Map 接口类提供了集合查看方法而不直接支持通过枚举对象(Enumeration)的迭代。集合查看大大地增强了接口的表达能力。
- Map 接口类允许通过键、值或键值对迭代,而 Hashtable 类不支持第三种方法。
- Map 接口类提供了安全的方法在迭代中删除元素,而 Hashtable 类不支持该功能。
- Map 接口类修复了 Hashtable 类的一个小缺陷。在 Hashtable 类中有一个 contains() 方法,当 Hashtable 类包含给定的值时,该方法返回 true。该方法可能引起混淆,因此 Map 接口将该方法改为 containsValue(),这与另一个方法 containsKey() 一致。