Java HashMap 教程显示了如何使用 Java HashMap 集合。
Java HashMap
HashMap 是一个存储键值对的容器。 每个键与一个值关联。 HashMap
中的键必须唯一。 HashMap
在其他编程语言中称为关联数组或词典。 HashMaps
占用更多内存,因为每个值还有一个键。 删除和插入操作需要固定的时间。 HashMaps
可以存储空值。
HashMaps
不维持秩序。
Map.Entry 表示HashMap
中的键/值对。 HashMap's
entrySet()
返回包含在映射中的映射的Set
视图。 使用keySet()
方法检索一组键。
Java HashMap
层次结构
HashMap
扩展了AbstractMap
并实现了Map
。 Map
提供了包括get()
,put()
,size()
或isEmpty()
的方法签名。
Java HashMap
构造函数
HashMap()
-构造一个空的HashMap()
,其默认初始容量(16)和默认负载因子(0.75)。HashMap(int initialCapacity)
-构造一个空的HashMap()
,具有给定的初始容量和默认的负载系数(0.75)。HashMap(int initialCapacity, float loadFactor)
-使用给定的初始容量和负载因子构造一个空的HashMap()
。HashMap(Map<? extends K,? extends V> m)
—构造一个新的HashMap()
,其映射与给定的Map
相同。
K
是映射键的类型,V
是映射值的类型。
Java HashMap
方法
下表提供了几种HashMap
方法。
修饰符和类型 | 方法 | 描述 |
---|---|---|
void |
clear() |
从映射中删除所有映射。 |
Object |
clone() |
返回 HashMap 实例的浅表副本:键和值本身不会被克隆。 |
boolean |
containsKey(Object key) |
如果此映射包含指定键的映射,则返回 true。 |
Set<Map.Entry<K, V>> |
entrySet() |
返回此映射中包含的映射的 Set 视图。 |
boolean |
isEmpty() |
如果此映射为空,则返回 true。 |
Set<K> |
keySet() |
返回此映射中包含的键的 Set 视图。 |
V |
put(K key, V value) |
向映射添加新的映射。 |
V |
remove(Objec key) |
如果存在,则从此映射中删除指定键的映射。 |
V |
get(Object key) |
返回指定键所映射到的值;如果此映射不包含键的映射关系,则返回 null。 |
void |
forEach(BiConsumer<? super K, ? super V> action) |
在此映射中为每个条目执行给定的操作,直到所有条目都已处理或该操作引发异常。 |
V |
replace(K key, V value) |
仅当当前映射到某个值时,才替换指定键的条目。 |
int |
size() |
返回此映射中的键值映射数。 |
Collection<V> |
values() |
返回此映射中包含的值的Collection 视图。 |
在本教程中,我们将使用其中的几种方法。
Java HashMap
创建
用new
关键字创建HashMap
。
Map<String, String> capitals = new HashMap<>();
我们在尖括号之间指定键的类型和值。 由于类型推断,因此不必在声明的右侧提供类型。
Java HashMap put()
put()
方法用于向映射添加新的映射。
capitals.put("svk", "Bratislava");
第一个参数是键,第二个是值。
Java HashMap remove()
remove()
方法用于从映射中删除一对。
capitals.remove("pol");
参数是要从映射中删除其映射的键。
Java HashMap
初始化
从 Java 9 开始,我们有了用于HashMap
初始化的工厂方法。
com/zetcode/HashMapInit.java
package com.zetcode;
import java.util.Map;
import static java.util.Map.entry;
// factory initialization methods since Java 9
public class HashMapInit {
public static void main(String[] args) {
// up to 10 elements:
Map<Integer, String> colours = Map.of(
1, "red",
2, "blue",
3, "brown"
);
System.out.println(colours);
// any number of elements
Map<String, String> countries = Map.ofEntries(
entry("de", "Germany"),
entry("sk", "Slovakia"),
entry("ru", "Russia")
);
System.out.println(countries);
}
}
该示例使用Map.of
和Map.ofEntries
初始化哈希图。 这两个工厂方法返回不可修改的映射。
com/zetcode/HashMapInit2.java
package com.zetcode;
import java.util.HashMap;
import java.util.Map;
// up to Java 8
public class HashMapInit2 {
public static void main(String[] args) {
Map<String, String> countries = new HashMap<>() {{
put("de", "Germany");
put("sk", "Slovakia");
put("ru", "Russia");
}};
System.out.println(countries);
}
}
在此示例中,我们创建了一个可修改的哈希图。 这种初始化方式称为双括号哈希图初始化。
Java HashMap
大小示例
HashMap
的大小由size()
方法确定。
com/zetcode/HashMapSize.java
package com.zetcode;
import java.util.HashMap;
import java.util.Map;
public class HashMapSize {
public static void main(String[] args) {
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
这是示例的输出。
Java HashMap get()
要从HashMap
检索值,我们使用get()
方法。 它以键作为参数。
com/zetcode/HashMapRetrieve.java
package com.zetcode;
import java.util.HashMap;
import java.util.Map;
public class HashMapRetrieve {
public static void main(String[] args) {
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"
键的值。
Java HashMap clear()
clear()
方法从HashMap
中删除所有对。
com/zetcode/HashMapClear.java
package com.zetcode;
import java.util.HashMap;
import java.util.Map;
public class HashMapClear {
public static void main(String[] args) {
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()
方法,我们检查映射是否为空。
Java HashMap containsKey()
如果映射包含指定键的映射,则containsKey()
方法返回 true。
com/zetcode/HashMapContainsKey.java
package com.zetcode;
import java.util.HashMap;
import java.util.Map;
public class HashMapContainsKey {
public static void main(String[] args) {
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
这是输出。
Java HashMap replace()
有replace()
方法使程序员可以替换条目。
replace(K key, V value)
仅当当前映射到某个值时,此方法才替换指定键的条目。
replace(K key, V oldValue, V newValue)
仅当当前映射到指定值时,此方法才替换指定键的条目。
com/zetcode/HashMapReplace.java
package com.zetcode;
import java.util.HashMap;
import java.util.Map;
public class HashMapReplace {
public static void main(String[] args) {
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
This is the output.
Java HashMap
转换为List
在下一个示例中,我们将HashMap
条目转换为条目列表。
com/zetcode/HashMapConvert.java
package com.zetcode;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class HashMapConvert {
public static void main(String[] args) {
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()
迭代HashMap
我们使用 Java 8 forEach()
方法来迭代HashMap
的键值对。 forEach()
方法对映射的每个元素执行给定的操作,直到所有元素都已处理或该操作引发异常。
com/zetcode/HashMapForEach.java
package com.zetcode;
import java.util.HashMap;
import java.util.Map;
public class HashMapForEach {
public static void main(String[] args) {
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 表达式迭代了HashMap
和forEach()
。
capitals.forEach((k, v) -> System.out.format("%s: %s%n", k, v));
使用forEach()
,我们遍历了映射的所有对。
使用增强的for
循环迭代HashMap
Java 5 中引入的增强的 for 循环可用于对HashMap
进行迭代。
com/zetcode/HashMapEnhancedFor.java
package com.zetcode;
import java.util.HashMap;
import java.util.Map;
public class HashMapEnhancedFor {
public static void main(String[] args) {
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
变量。
Java HashMap
迭代键
我们可能只想遍历HashMap
的键。
com/zetcode/HashMapKeys.java
package com.zetcode;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class HashMapKeys {
public static void main(String[] args) {
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
映射的键。
Set<String> keys = capitals.keySet();
用keySet()
方法检索HashMap
的密钥,该方法返回密钥Set
。 密钥必须唯一; 因此,我们有一个Set
。 Set
是一个不包含重复元素的集合。
keys.forEach(System.out::println);
我们用forEach()
遍历键集。
Java HashMap
迭代值
我们可能只想对HashMap
的值进行迭代。
com/zetcode/HashMapValues.java
package com.zetcode;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class HashMapValues {
public static void main(String[] args) {
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
的值。
Collection<String> vals = capitals.values();
HashMap
的值通过values()
方法检索。
vals.forEach(System.out::println);
我们使用forEach()
遍历集合。
HashMap 过滤
可以使用 Java Stream API 的filter()
方法过滤HashMap
。
com/zetcode/HashMapFilter.java
package com.zetcode;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class HashMapFilter {
public static void main(String[] args) {
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(map -> map.getValue().length() == 6)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
filteredCapitals.entrySet().forEach(System.out::println);
}
}
在示例中,我们将映射过滤为仅包含值大小等于 6 的对。
czk=Prague
ger=Berlin
pol=Warsaw
This is the output.
其他语言的 Java HashMap 等效项
Ruby 具有哈希,Perl 具有哈希,PHP 具有数组,Python 具有字典,C# 具有字典,JavaScript 具有映射。
ruby_hash.rb
#!/usr/bin/ruby
stones = { 1 => "garnet", 2 => "topaz",
3 => "opal", 4 => "amethyst"
}
stones.each { |k, v| puts "Key: #{k}, Value: #{v}" }
这是 Ruby 中的哈希。
perl_hash.py
#!/usr/bin/perl
my %stones = ( 1 => "garnet", 2 => "topaz",
3 => "opal", 4 => "amethyst" );
while ( my (k,v) = each %stones ) {
print "k:v\n";
}
这是一个 Perl 哈希。
php_array.php
<?php
stones = [
1 => "garnet",
2 => "topaz",
3 => "opal",
4 => "amethyst"
];
foreach (stones as key =>value) {
echo "key:value\n";
}
?>
这是一个 PHP 数组。
python_dictionary.py
#!/usr/bin/python
stones = { 1 : "garnet",
2 : "topaz",
3 : "opal",
4 : "amethyst" }
for key, value in stones.items():
print("{}: {}".format(key, value))
这是 Python 字典。
csharp_dictionary.cs
using System;
using System.Collections.Generic;
public class DictionaryExample {
static void Main() {
Dictionary<int, string> stones = new Dictionary<int, string> {
{ 1, "garnet" },
{ 2, "topaz" },
{ 3, "opal" },
{ 4, "amethyst" },
};
Console.WriteLine("Keys and values of the dictionary:");
foreach(KeyValuePair<int, string> kvp in stones) {
Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
}
}
}
这是 C# 词典。
javascript_map.js
var stones = new Map();
stones.set(1, 'garnet');
stones.set(2, 'topaz');
stones.set(3, 'opal');
stones.set(4, 'amethyst');
stones.forEach(function(value, key) {
console.log(key + ': ' + value);
});
这是一个 JavaScript 映射。
在本教程中,我们介绍了 Java HashMap
集合。