Java HashMap
HashMap 实现了 Map 接口,其内部利用键的哈希值保证键的唯一性。在本教程中,我们将通过示例了解 Java HashMap 类及其各种操作。
在本教程中,我们将通过示例了解 Java HashMap 类及其各种操作。
Java 集合框架的 HashMap
类提供散列表数据结构的功能。
HashMap
将元素按键/值对存储,在这个结构中,我们通过键是来关联值,并且键具有唯一性。
HashMap
类实现了 Map 接口,其内部利用键的哈希值保证键的唯一性。
创建 HashMap
我们导入 java.util.HashMap
类后,就可以通过构造方法创建 HashMap
对象了。
HashMap<K, V> numbers = new HashMap<>();
在上面的代码中,我们创建了一个名为 numbers
的 HashMap 对象。 这里,K
代表键类型,V
代表值的类型。例如,
HashMap<String, Integer> numbers = new HashMap<>();
键是 String
类型,的值是 Integer
类型。
示例 1:在 Java 中创建 HashMap
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<String, Integer> languages = new HashMap<>();
languages.put("Java", 8);
languages.put("JavaScript", 1);
languages.put("Python", 3);
System.out.println("HashMap: " + languages);
}
}
输出
HashMap: {Java=8, JavaScript=1, Python=3}
在上面的例子中,我们创建了一个 HashMap
对象 languages
,并使用了 put()
向添加键值对数据。
Java HashMap 的基本操作
HashMap
类提供了许多方法来执行不同的操作。主要包括:
- 添加元素
- 访问元素
- 更改元素
- 删除元素
向 HashMap 添加元素
put()
方法用于将键值对元素添加到 HashMap 。例如,
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<String, Integer> numbers = new HashMap<>();
System.out.println("Initial HashMap: " + numbers);
numbers.put("One", 1);
numbers.put("Two", 2);
numbers.put("Three", 3);
System.out.println("HashMap after put(): " + numbers);
}
}
输出
Initial HashMap: {}
HashMap after put(): {One=1, Two=2, Three=3}
注意声明,
numbers.put("One", 1);
在这里,我们使用 put()
方法添加 String
类型的键和 Integer
类型的值到 Hash Map 中。
访问 HashMap 元素
get()
方法获取指定的键对应的值。例如,
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<Integer, String> languages = new HashMap<>();
languages.put(1, "Java");
languages.put(2, "Python");
languages.put(3, "JavaScript");
System.out.println("HashMap: " + languages);
String value = languages.get(1);
System.out.println("Value at index 1: " + value);
}
}
输出
HashMap: {1=Java, 2=Python, 3=JavaScript}
Value at index 1: Java
在上面的例子中,注意表达式,
languages.get(1);
在这里, get()
方法将键作为其参数并返回与键关联的值。
我们还可以访问键,值和键/值使用 HashMap 中的对作为一组的意见 keySet()
, values()
和 entrySet()
分别的方法。例如,
我们还可以使用以下方法:
keySet()
: 返回所有键的 Set 集合values()
: 返回所有值的集合entrySet()
:返回所有键值对条目的 Set 集合
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<Integer, String> languages = new HashMap<>();
languages.put(1, "Java");
languages.put(2, "Python");
languages.put(3, "JavaScript");
System.out.println("HashMap: " + languages);
System.out.println("Keys: " + languages.keySet());
System.out.println("Values: " + languages.values());
System.out.println("Key/Value mappings: " + languages.entrySet());
}
}
输出
HashMap: {1=Java, 2=Python, 3=JavaScript}
Keys: [1, 2, 3]
Values: [Java, Python, JavaScript]
Key/Value mappings: [1=Java, 2=Python, 3=JavaScript]
更改 HashMap 值
replace()
方法更改指定的键关联的值。例如,
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<Integer, String> languages = new HashMap<>();
languages.put(1, "Java");
languages.put(2, "Python");
languages.put(3, "JavaScript");
System.out.println("Original HashMap: " + languages);
// 修改键 2 对应的值
languages.replace(2, "C++");
System.out.println("HashMap using replace(): " + languages);
}
}
输出
Original HashMap: {1=Java, 2=Python, 3=JavaScript}
HashMap using replace(): {1=Java, 2=C++, 3=JavaScript}
移除 HashMap 元素
remove()
方法删除并返回指定键对应的条目。例如,
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<Integer, String> languages = new HashMap<>();
languages.put(1, "Java");
languages.put(2, "Python");
languages.put(3, "JavaScript");
System.out.println("HashMap: " + languages);
// 删除键 2 对应的条目
String value = languages.remove(2);
System.out.println("Removed value: " + value);
System.out.println("Updated HashMap: " + languages);
}
}
输出
HashMap: {1=Java, 2=Python, 3=JavaScript}
Removed value: Python
Updated HashMap: {1=Java, 3=JavaScript}
我们也可以根据键和值删除对应的键值对条目。例如,
remove(2, "C++");
此处,该方法仅在删除键位 2
值位 "C++"
的键值对条目。只有键和值都匹配的条目才会被删除。如果删除成功返回 true
,否则返回 false
。
HashMap 的其他方法
clear()
: 清空HashMap
。compute()
: 根据指定的键计算新值,并更新到条目。computeIfAbsent()
: 当指定键不存在或对应的值为null
时,根据键计算新值,并更新。computeIfPresent()
: 当指定键不存在且对应的值不为null
时,重新根据键计算新值并更新。merge()
: 将指定键的条目中的值与新指定的值通过指定的接口函数合并,并更新为合并后的值。如果指定的键不存在或者对应的值为 null,则更新为新指定的值。clone()
: 克隆Hashmap
containsKey()
: 检查 Hashmap 中是否存在指定的键containsValue()
: 检查Hashmap
中是否包含指定的值size()
: 返回HashMap
中键值对条目的数量isEmpty()
: 检查Hashmap
是否为空
遍历 HashMap
我们可以使用 Java for-each 循环遍历 Hashmap
的每个条目。例如,
import java.util.HashMap;
import java.util.Map.Entry;
public class Main {
public static void main(String[] args) {
// create a HashMap
HashMap<Integer, String> languages = new HashMap<>();
languages.put(1, "Java");
languages.put(2, "Python");
languages.put(3, "JavaScript");
System.out.println("HashMap: " + languages);
// 只遍历键
System.out.print("Keys: ");
for (Integer key : languages.keySet()) {
System.out.print(key);
System.out.print(", ");
}
// 只遍历值
System.out.print("\nValues: ");
for (String value : languages.values()) {
System.out.print(value);
System.out.print(", ");
}
// 遍历键值对条目
System.out.print("\nEntries: ");
for (Entry<Integer, String> entry : languages.entrySet()) {
System.out.print(entry.getKey() + "=" + entry.getValue());
System.out.print(", ");
}
}
}
输出
HashMap: {1=Java, 2=Python, 3=JavaScript}
Keys: 1, 2, 3,
Values: Java, Python, JavaScript,
Entries: 1=Java, 2=Python, 3=JavaScript,
请注意,我们在上面的示例中使用了 Map.Entry
类。它是 Map
接口中的嵌套类,它代表了一个键值对条目。 Map.Entry
类由 3 个主要的方法:
getKey()
: 返回键值对条目中的键getValue()
: 返回键值对条目中的值setValue(V value)
: 设置键值对条目中的值。
从其他 Map 创建 HashMap
在 Java 中,我们还可以从其他映射创建 HashMap。例如,
import java.util.HashMap;
import java.util.TreeMap;
public class Main {
public static void main(String[] args) {
// 创建 TreeMap
TreeMap<String, Integer> evenNumbers = new TreeMap<>();
evenNumbers.put("Two", 2);
evenNumbers.put("Four", 4);
System.out.println("TreeMap: " + evenNumbers);
// 从现有的 map 创建一个 HashMap 对象
HashMap<String, Integer> numbers = new HashMap<>(evenNumbers);
numbers.put("Three", 3);
System.out.println("HashMap: " + numbers);
}
}
输出
TreeMap: {Four=4, Two=2}
HashMap: {Two=2, Three=3, Four=4}
在上面的例子中,我们创建了一个名为 evenNumbers
的 TreeMap
对象。 注意这面的语句:
numbers = new HashMap<>(evenNumbers)
在这里,我们使用了带参数的构造方法 HashMap(Map<? extends K, ? extends V> m)
,将一个现有的 Map 对象转为 HashMap 对象。
HashMap 容量和负载因子
在创建 HashMap 时,我们通过构造函数指定它的初始容量大小,由两个相关的构造函数:
HashMap(int initialCapacity)
: 指定初始容量大小,负载因子默认为0.75f
HashMap(int initialCapacity, float loadFactor)
: 指定初始容量大小和负载因子
参数如下:
initialCapacity
: 初始容量大小,默认为 16loadFactor
: 负载因子,负载因子默认为0.75f
。浮负载因子用来指示当容量达到指定的负载占比时,就要对容量扩容。
例如:
HashMap<K, V> numbers = new HashMap<>(8, 0.6f);
这里,
- 初始容量为
8
: 初始分配的大小为 8 - 负载因子为
0.6f
: 意味着每当使用量超过 60% 时,就要对底层的存储扩容,一般是变为原来的 2 倍。