Java HashMap
最后修改日期:2024年2月21日
在本文中,我们将展示如何使用 Java HashMap 集合。
HashMap 是一个存储键值对的容器。每个键都与一个值相关联。HashMap 中的键必须是唯一的。在其他编程语言中,HashMap 被称为关联数组或字典。HashMap 占用更多内存,因为每个值都有一个键。删除和插入操作花费恒定时间。HashMap 可以存储空值。
HashMap 不维护顺序。
Map.Entry 表示 HashMap 中的一个键值对。HashMap 的 entrySet 返回包含在该映射中的映射的 Set 视图。可以使用 keySet 方法检索键的集合。
HashMap 扩展了 AbstractMap 并实现了 Map。Map 提供了方法签名,包括 get、put、size 或 isEmpty。
HashMap 构造函数
HashMap— 构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空HashMap。HashMap(int initialCapacity)— 构造一个具有给定初始容量和默认加载因子 (0.75) 的空HashMap。HashMap(int initialCapacity, float loadFactor)— 构造一个具有给定初始容量和加载因子的空HashMap。HashMap(Map m)— 构造一个新的HashMap,其映射与给定的Map相同。
K 是映射键的类型,V 是映射值的类型。
HashMap 方法
下表提供了一些 HashMap 方法。
| 修饰符和类型 | 方法 | 描述 |
|---|---|---|
| void | clear() | 从映射中删除所有映射。 |
| 对象 | clone() | 返回 HashMap 实例的浅拷贝:键和值本身不会被克隆。 |
| V boolean | containsKey(Object key) | 如果此映射包含指定键的映射,则返回 true。 |
| Set |
entrySet() | 返回包含在此映射中的映射的 Set 视图。 |
| 布尔值 | isEmpty() | 如果此映射为空,则返回 true。 |
| Set |
keySet() | 返回包含在此映射中的键的 Set 视图。 |
| V | put(K key, V value) | 将新映射添加到映射。 |
| V | remove(Object key) | 如果存在,则从此映射中删除指定键的映射。 |
| V | get(Object key) | 返回指定键映射到的值,如果此映射不包含该键的映射,则返回 null。 |
| void | forEach(BiConsumeraction) | 对此映射中的每个条目执行给定的操作,直到所有条目都已处理完毕或该操作引发异常。 |
| V | replace(K key, V value) | 仅当指定键当前映射到某个值时,才替换该键的条目。 |
| int | size() | 返回此映射中的键值映射的数量。 |
| Collection |
values() | 返回包含在此映射中的值的 Collection 视图。 |
在本文中,我们将使用其中的几种方法。
HashMap 创建
HashMap 使用 new 关键字创建。
Mapcapitals = new HashMap<>();
我们在尖括号之间指定键和值的类型。由于类型推断,没有必要在声明的右侧提供类型。
put 方法
put 方法用于向映射添加新的映射。
capitals.put("svk", "Bratislava");
第一个参数是键,第二个参数是值。
remove 方法
remove 方法用于从映射中删除一个键值对。
capitals.remove("pol");
参数是要从映射中删除其映射的键。
HashMap 初始化
自 Java 9 以来,我们有用于 HashMap 初始化的工厂方法。
import java.util.Map;
import static java.util.Map.entry;
void main() {
Map colours = Map.of(1, "red", 2, "blue", 3, "brown");
System.out.println(colours);
Map countries = Map.ofEntries(
entry("de", "Germany"),
entry("sk", "Slovakia"),
entry("ru", "Russia"));
System.out.println(countries);
}
该示例使用 Map.of 和 Map.ofEntries 来初始化哈希映射。这两个工厂方法返回不可修改的映射。
import java.util.HashMap;
import java.util.Map;
// up to Java 8
void main() {
Map countries = new HashMap<>() {
{
put("de", "Germany");
put("sk", "Slovakia");
put("ru", "Russia");
}
};
System.out.println(countries);
}
在此示例中,我们创建一个可修改的哈希映射。这种初始化方式被称为双括号哈希映射初始化。
size 方法
HashMap 的大小由 size 方法确定。
import java.util.HashMap;
import java.util.Map;
void main() {
Map<String, String> capitals = new HashMap<>();
capitals.put("svk", "Bratislava");
capitals.put("ger", "Berlin");
capitals.put("hun", "Budapest");
capitals.put("czk", "Prague");
capitals.put("pol", "Warsaw");
capitals.put("ita", "Rome");
int size = capitals.size();
System.out.printf("The size of the HashMap is %d%n", size);
capitals.remove("pol");
capitals.remove("ita");
size = capitals.size();
System.out.printf("The size of the HashMap is %d%n", size);
}
在代码示例中,我们创建一个 HashMap 并使用 size 确定其大小。然后,我们删除一些键值对并再次确定其大小。我们将结果打印到控制台。
capitals.put("svk", "Bratislava");
capitals.put("ger", "Berlin");
使用 put,我们将新的键值对添加到 HashMap 中。
int size = capitals.size();
这里我们获取映射的大小。
capitals.remove("pol");
capitals.remove("ita");
使用 remove,我们从映射中删除两个键值对。
The size of the HashMap is 6 The size of the HashMap is 4
get 方法
要从 HashMap 检索值,我们使用 get 方法。它接受一个键作为参数。
import java.util.HashMap;
import java.util.Map;
void main() {
Map<String, String> capitals = new HashMap<>();
capitals.put("svk", "Bratislava");
capitals.put("ger", "Berlin");
capitals.put("hun", "Budapest");
capitals.put("czk", "Prague");
capitals.put("pol", "Warsaw");
capitals.put("ita", "Rome");
String cap1 = capitals.get("ita");
String cap2 = capitals.get("svk");
System.out.println(cap1);
System.out.println(cap2);
}
在该示例中,我们从映射中检索两个值。
String cap2 = capitals.get("svk");
这里我们获取具有 "svk" 键的值。
clear 方法
clear 方法从 HashMap 中删除所有键值对。
import java.util.HashMap;
import java.util.Map;
void main() {
Map<String, String> capitals = new HashMap<>();
capitals.put("svk", "Bratislava");
capitals.put("ger", "Berlin");
capitals.put("hun", "Budapest");
capitals.put("czk", "Prague");
capitals.put("pol", "Warsaw");
capitals.put("ita", "Rome");
capitals.clear();
if (capitals.isEmpty()) {
System.out.println("The map is empty");
} else {
System.out.println("The map is not empty");
}
}
在该示例中,我们删除所有元素并将映射的大小打印到控制台。
capitals.clear();
我们使用 clear 删除所有键值对。
if (capitals.isEmpty()) {
System.out.println("The map is empty");
} else {
System.out.println("The map is not empty");
}
使用 isEmpty 方法,我们检查映射是否为空。
containsKey 方法
如果该映射包含指定键的映射,则 containsKey 方法返回 true。
import java.util.HashMap;
import java.util.Map;
void main() {
Map<String, String> capitals = new HashMap<>();
capitals.put("svk", "Bratislava");
capitals.put("ger", "Berlin");
capitals.put("hun", "Budapest");
capitals.put("czk", "Prague");
capitals.put("pol", "Warsaw");
capitals.put("ita", "Rome");
String key1 = "ger";
String key2 = "rus";
if (capitals.containsKey(key1)) {
System.out.printf("HashMap contains %s key%n", key1);
} else {
System.out.printf("HashMap does not contain %s key%n", key1);
}
if (capitals.containsKey(key2)) {
System.out.printf("HashMap contains %s key%n", key2);
} else {
System.out.printf("HashMap does not contain %s key%n", key2);
}
}
在该示例中,我们检查映射是否包含两个键。
if (capitals.containsKey(key1)) {
System.out.printf("HashMap contains %s key%n", key1);
} else {
System.out.printf("HashMap does not contain %s key%n", key1);
}
此 if 语句根据映射是否包含给定的键打印一条消息。
HashMap contains ger key HashMap does not contain rus key
replace 方法
有一些 replace 方法使程序员能够替换条目。
replace(K key, V value)
仅当指定键当前映射到某个值时,此方法才替换该键的条目。
replace(K key, V oldValue, V newValue)
仅当指定键当前映射到指定值时,此方法才替换该键的条目。
import java.util.HashMap;
import java.util.Map;
void main() {
Map<String, String> capitals = new HashMap<>();
capitals.put("day", "Monday");
capitals.put("country", "Poland");
capitals.put("colour", "blue");
capitals.replace("day", "Sunday");
capitals.replace("country", "Russia", "Great Britain");
capitals.replace("colour", "blue", "green");
capitals.entrySet().forEach(System.out::println);
}
在该示例中,我们使用 replace 替换映射中的键值对。
capitals.replace("day", "Sunday");
这里我们替换 "day" 键的值。
capitals.replace("country", "Russia", "Great Britain");
在这种情况下,该值不会被替换,因为该键当前未设置为 "Russia"。
capitals.replace("colour", "blue", "green");
因为旧值是正确的,所以该值被替换。
country=Poland colour=green day=Sunday
将 HashMap 转换为 List
在下一个示例中,我们将 HashMap 条目转换为条目列表。
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
void main() {
Map<String, String> colours = Map.of(
"AliceBlue", "#f0f8ff",
"GreenYellow", "#adff2f",
"IndianRed", "#cd5c5c",
"khaki", "#f0e68c"
);
Set<Map.Entry<String, String>> entries = colours.entrySet();
List<Map.Entry<String, String>> mylist = new ArrayList<>(entries);
System.out.println(mylist);
}
entrySet 返回映射的集合视图,该视图稍后传递给 ArrayList 的构造函数。
使用 forEach 迭代
我们使用 forEach 方法来迭代 HashMap 的键值对。forEach 方法对映射的每个元素执行给定的操作,直到所有元素都已处理完毕或该操作引发异常。
import java.util.HashMap;
import java.util.Map;
void main() {
Map<String, String> capitals = new HashMap<>();
capitals.put("svk", "Bratislava");
capitals.put("ger", "Berlin");
capitals.put("hun", "Budapest");
capitals.put("czk", "Prague");
capitals.put("pol", "Warsaw");
capitals.put("ita", "Rome");
capitals.forEach((k, v) -> System.out.format("%s: %s%n", k, v));
}
在代码示例中,我们使用 lambda 表达式通过 forEach 迭代 HashMap。
capitals.forEach((k, v) -> System.out.format("%s: %s%n", k, v));
使用 forEach,我们迭代映射的所有键值对。
使用增强的 for 循环迭代
可以使用增强的 for 循环来迭代 HashMap。
import java.util.HashMap;
import java.util.Map;
void main() {
Map<String, String> capitals = new HashMap<>();
capitals.put("svk", "Bratislava");
capitals.put("ger", "Berlin");
capitals.put("hun", "Budapest");
capitals.put("czk", "Prague");
capitals.put("pol", "Warsaw");
capitals.put("ita", "Rome");
for (Map.Entry<String, String> pair: capitals.entrySet()) {
System.out.format("%s: %s%n", pair.getKey(), pair.getValue());
}
}
在该示例中,我们使用增强的 for 循环迭代 HashMap。
for (Map.Entry<String, String> pair: capitals.entrySet()) {
System.out.format("%s: %s%n", pair.getKey(), pair.getValue());
}
在每个 for 循环中,一个新的键值对被分配给 pair 变量。
使用类型推断,我们可以稍微缩短代码。
import java.util.HashMap;
import java.util.Map;
void main() {
Map<String, String> capitals = new HashMap<>();
capitals.put("svk", "Bratislava");
capitals.put("ger", "Berlin");
capitals.put("hun", "Budapest");
capitals.put("czk", "Prague");
capitals.put("pol", "Warsaw");
capitals.put("ita", "Rome");
for (var pair: capitals.entrySet()) {
System.out.format("%s: %s%n", pair.getKey(), pair.getValue());
}
}
我们通过在 for 循环中使用 var 关键字来缩短代码。
迭代键
我们可能只想迭代 HashMap 的键。
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
void main() {
Map<String, String> capitals = new HashMap<>();
capitals.put("svk", "Bratislava");
capitals.put("ger", "Berlin");
capitals.put("hun", "Budapest");
capitals.put("czk", "Prague");
capitals.put("pol", "Warsaw");
capitals.put("ita", "Rome");
Set<String> keys = capitals.keySet();
keys.forEach(System.out::println);
}
该示例迭代 capitals 映射的键。
Setkeys = capitals.keySet();
HashMap 的键通过 keySet 方法检索,该方法返回一个键的 Set。键必须是唯一的;因此,我们有一个 Set。Set 是一个不包含重复元素的集合。
keys.forEach(System.out::println);
我们使用 forEach 遍历键的集合。
迭代值
我们可能只想迭代 HashMap 的值。
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
void main() {
Map<String, String> capitals = new HashMap<>();
capitals.put("svk", "Bratislava");
capitals.put("ger", "Berlin");
capitals.put("hun", "Budapest");
capitals.put("czk", "Prague");
capitals.put("pol", "Warsaw");
capitals.put("ita", "Rome");
Collection<String> vals = capitals.values();
vals.forEach(System.out::println);
}
该示例迭代 HashMap 的值。
Collectionvals = capitals.values();
HashMap 的值通过 values 方法检索。
vals.forEach(System.out::println);
我们使用 forEach 遍历该集合。
过滤 HashMap
可以使用 Java Stream API 的 filter 方法过滤 HashMap。
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
void main() {
Map<String, String> capitals = new HashMap<>();
capitals.put("svk", "Bratislava");
capitals.put("ger", "Berlin");
capitals.put("hun", "Budapest");
capitals.put("czk", "Prague");
capitals.put("pol", "Warsaw");
capitals.put("ita", "Rome");
Map<String, String> filteredCapitals = capitals.entrySet().stream()
.filter(e -> e.getValue().length() == 6)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
filteredCapitals.entrySet().forEach(System.out::println);
}
在该示例中,我们过滤映射以仅包含其值的长度等于六的键值对。
czk=Prague ger=Berlin pol=Warsaw
映射列表
在下一个示例中,我们有一个映射列表。
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
void main() {
Map<String,Integer> fruits1 = new HashMap<>();
fruits1.put("oranges", 2);
fruits1.put("bananas", 3);
Map<String,Integer> fruits2 = new HashMap<>();
fruits2.put("plums", 6);
fruits2.put("apples", 7);
List<Map<String,Integer>> all = new ArrayList<>();
all.add(fruits1);
all.add(fruits2);
all.forEach(e -> e.forEach((k, v) -> System.out.printf("k: %s v %d%n", k, v)));
}
我们定义两个映射并将它们插入到一个列表中。然后我们使用两个 forEach 循环迭代该列表。
k: oranges v 2 k: bananas v 3 k: plums v 6 k: apples v 7
来源
在本文中,我们介绍了 Java HashMap 集合。
作者
列出所有Java教程。