Map是什么
Map
用来存放键值对数据,可以看做是键值对的集合。
Map
不能包含重复的键,也就意味着每个键只能映射到最多一个值。Map
没有规定不能存放为null
的值。
Java平台提供三种通用的Map
实现类:HashMap
, TreeMap
, LinkedHashMap
。三者的行为和性能可以类比HashSet
,TreeSet
,LinkedHashSet
。
Map提供的接口
作为一个集合,自然是需要提供增删改查这类接口。来看看Map
都提供了什么:
- 添加修改操作:
对于// 向Map中添加或者更新值。返回先前映射的元素,或者null,如果不存在。 public V put(K key, V value); public void putAll(Map<? extends K,? extends V> map);
put
操作,如果Map
已经包含了当前的key
,则会用更新原有值为新的value
。 - 删除操作:
// 返回被删除的元素,或者如果该元素不存在则返回null public V remove(Object key); public void clear();
- 查询操作:
// 返回Map中键值对个数 public int size(); // 返回key映射的值,如果不存在则返回null V get(Object key); /** * 返回包含的键的集 * 注意:返回的Set不支持添加操作。并且修改返回的Set或者原有Map将会相互影响 */ public Set<K> keySet(); /** * 返回包含的所有值的集合 * 注意:修改原有Map或者返回的集合将会相互影响。 * 返回的集合支持remove, removeAll, retainAll以及clear操作,不支持add, addll操作。 */ public Collection<V> values(); /** * 返回一个包含所有映射内容的集形式,每条映射内容保存于Entry中 * 同样修改返回的Set或者原有Map将会相互影响 */ public Set<Map.Entry<K,V>> entrySet();
- 测试操作:
public boolean containsKey(Object key); public boolean containsValue(Object value); public boolean isEmpty(); public boolean equals(Object object);
- 其他:
public int hashCode();
查询操作里面,keySet()
,entrySet()
,values()
方法返回了Map
的集合视图,可以方便使用Collection
接口形式进行操作。
另外,所有的通用Map
实现都提供将Map
作为参数的构造函数,类似Collection
,这将很方便的用于拷贝生成一个新的Map
实现,而不用考虑以前的实现类型。
基本操作的例子
下面的例子用来统计参数表中的每个词出现的次数,并保存在Map中。
package com.shane.collection;
import java.util.HashMap;
import java.util.Map;
/**
* Created by Shane on 2016/6/25.
*/
public class Freq {
public static void main(String[] args) {
Map<String, Integer> m = new HashMap<String, Integer>();
// Initialize frequency table from command line
for (String a : args) {
Integer freq = m.get(a);
m.put(a, (freq == null) ? 1 : freq + 1);
}
System.out.println(m.size() + " distinct words:");
System.out.println(m);
}
}
上面唯一需要注意的就是通过判断freq
是否等于null,来确定是不是第一次添加,因为等Map中没有包含某个key时,返回的值为null。
在命令行下,切换到编译后的class文件最顶层,执行下面的命令:
java com.shane.collection.Freq if it is to be it is up to me to delegate
注意,这里com.shane.collection
为Freq
类所在的包。
测试结果如下:
// HashMap
8 distinct words:
{delegate=1, be=1, me=1, is=2, it=2, to=3, up=1, if=1}
// TreeMap
8 distinct words:
{be=1, delegate=1, if=1, is=2, it=2, me=1, to=3, up=1}
// LinkedHashMap
8 distinct words:
{if=1, it=2, is=2, to=3, be=1, up=1, me=1, delegate=1}
通过传入不同的Map
实现,可以得到不同的结果。可以看到TreeMap
以字母顺序返回结果,LinkedHashMap
则以第一次出现的单词的先后顺序返回。这也印证了它们各自的特性。
多值Map(Multimaps)
这里指的是一个Map,可以映射每个key到多个values。Java集合框架并没有包含一个接口用于多值Map,主要是因为这个并不是那么常用。通常利用将一个key映射到一个List来达到多值映射的目的。
比如:
Map<String, List<String>> = new HashMap<String, List<String>>;