Map
// 不可变的映射
Map<String, String> immutable2 = Collections.singletonMap("Son-Goku", "未知");
// 不可变的映射
// Map<String, String> immutable2 = Collections.<String, Integer>emptyMap();//right
Map<String, Integer> immutableMap2 = Collections.emptyMap();
// 不修改的映射
Map<String, String> unModify1 = Map.of("骆宾王", "唐朝", "李煜", "唐朝");
// 不修改的映射
Map<String, String> unModify2 = Map.ofEntries(Map.entry("曹操", "三国"), Map.entry("曹植", "三国"));
// 可变集合
Map<String, String> map = new HashMap<>(unModify1);
Java技术手册的示例
// 新建一个空映射
Map<String, Integer> m = new HashMap<>();
// 不可变的映射,只包含一个键值对
Map<String, Integer> singleton = Collections.singletonMap("test", -1);
// 注意,极少使用下述句法显式指定通用方法emptyMap()的参数类型
// 得到的映射不可变
// Map<String, Integer> empty = Collections.emptyMap();//right
Map<String, Integer> empty = Collections.<String, Integer>emptyMap();
// 使用put()方法填充映射,把数组中的元素映射到元素的索引上
String[] words = {"this", "is", "a", "test"};
for (int i = 0; i < words.length; i++) {
m.put(words[i], i); // 注意,int会自动装包成Integer
}
// 一个键只能映射一个值
// 不过,多个键可以映射同一个值
for (int i = 0; i < words.length; i++) {
m.put(words[i].toUpperCase(), i);
}
// putAll()方法从其他映射中复制键值对
m.putAll(singleton);
// 使用get()方法查询映射
for (int i = 0; i < words.length; i++) {
if (m.get(words[i]) != i) throw new AssertionError();
}
// 测试映射中是否有指定的键和值
m.containsKey(words[0]); // true
m.containsValue(words.length); // false
// 映射的键、值和键值对都可以看成集合
Set<String> keys = m.keySet();
Collection<Integer> values = m.values();
Set<Map.Entry<String, Integer>> entries = m.entrySet();
// 映射和上述几个集合都有有用的toString()方法
System.out.printf("Map: %s%nKeys: %s%nValues: %s%nEntries: %s%n",
m, keys, values, entries);
// 可以迭代这些集合
// 多数映射都没定义迭代的顺序(不过SortedMap定义了)
for (String key : m.keySet()) System.out.println(key);
for (Integer value : m.values()) System.out.println(value);
// Map.Entry<K,V>类型表示映射中的一个键值对
for (Map.Entry<String, Integer> pair : m.entrySet()) {
// 打印键值对
System.out.printf("'%s' ==> %d%n", pair.getKey(), pair.getValue());
// 然后把每个Entry对象的值增加1
pair.setValue(pair.getValue() + 1);
}
// 删除键值对(假删)
m.put("testing", null); // 映射到null上可以“擦除”一个键值对
m.get("testing"); // 返回null
m.containsKey("testing"); // 返回true:键值对仍然存在
m.remove("testing"); // 删除键值对
m.get("testing"); // 还是返回null
m.containsKey("testing"); // 这次返回false
// 也可以把映射视作集合,然后再删除
// 不过,向集合中添加键值对时不能这么做
m.keySet().remove(words[0]); // 等同于m.remove(words[0]);
// 删除一个值为2的键值对——这种方式一般效率不高,用途有限
m.values().remove(2);
// 删除所有值为4的键值对
m.values().removeAll(Collections.singleton(4));
// 只保留值为2和3的键值对
m.values().retainAll(Arrays.asList(2, 3));
// 还可以通过迭代器删除
Iterator<Map.Entry<String, Integer>> iter = m.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry<String, Integer> e = iter.next();
if (e.getValue() == 2) iter.remove();
}
// 找出两个映射中都有的值
// 一般来说,addAll()和retainAll()配合keySet()和values()使用,可以获取交集和并集
Set<Integer> v = new HashSet<Integer>(m.values());
v.retainAll(singleton.values());
// 其他方法
m.clear(); // 删除所有键值对
m.size(); // 返回键值对的数量:目前为0
m.isEmpty(); // 返回true
m.equals(empty); // true:实现Map接口的类覆盖了equals()方法
Map的类型嵌套
// 可以用这个结构表示某个部门下的员工姓名
Map<String, List<String>> time2person = new HashMap<>();