ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
{% raw %} # Java `HashMap`教程 原文:http://zetcode.com/java/hashmap/ Java `HashMap`教程显示了如何使用 Java `HashMap`集合。 ## Java `HashMap` `HashMap`是一个存储键值对的容器。 每个键与一个值关联。 `HashMap`中的键必须唯一。 `HashMap`在其他编程语言中称为关联数组或词典。 `HashMaps`占用更多内存,因为每个值还有一个键。 删除和插入操作需要固定的时间。 `HashMaps`可以存储空值。 `HashMaps`不维持秩序。 `Map.Entry`表示`HashMap`中的键/值对。 `HashMap`的`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`。 ```java Map<String, String> capitals = new HashMap<>(); ``` 我们在尖括号之间指定键的类型和值。 由于类型推断,因此不必在声明的右侧提供类型。 ## Java `HashMap put()` `put()`方法用于向映射添加新的映射。 ```java capitals.put("svk", "Bratislava"); ``` 第一个参数是键,第二个是值。 ## Java `HashMap remove()` `remove()`方法用于从映射中删除一对。 ```java capitals.remove("pol"); ``` 参数是要从映射中删除其映射的键。 ## Java `HashMap`初始化 从 Java 9 开始,我们有了用于`HashMap`初始化的工厂方法。 `com/zetcode/HashMapInit.java` ```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` ```java package com.zetcode; import java.util.HashMap; import java.util.Map; // up to Java8 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` ```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()`确定其大小。 然后,我们删除一些对,然后再次确定其大小。 我们将发现结果打印到控制台。 ```java capitals.put("svk", "Bratislava"); capitals.put("ger", "Berlin"); ``` 使用`put()`,我们将新的对添加到`HashMap`中。 ```java int size = capitals.size(); ``` 在这里,我们得到映射的大小。 ```java capitals.remove("pol"); capitals.remove("ita"); ``` 使用`remove()`,我们从映射中删除了两对。 ```java The size of the HashMap is 6 The size of the HashMap is 4 ``` 这是示例的输出。 ## Java `HashMap get()` 要从`HashMap`检索值,我们使用`get()`方法。 它以键作为参数。 `com/zetcode/HashMapRetrieve.java` ```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); } } ``` 在示例中,我们从映射中检索两个值。 ```java String cap2 = capitals.get("svk"); ``` 在这里,我们得到一个具有`"svk"`键的值。 ## Java `HashMap clear()` `clear()`方法从`HashMap`中删除所有对。 `com/zetcode/HashMapClear.java` ```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"); } } } ``` 在该示例中,我们删除了所有元素,并将映射的大小打印到控制台。 ```java capitals.clear(); ``` 我们用`clear()`删除所有对。 ```java 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` ```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); } } } ``` 在示例中,我们检查映射是否包含两个键。 ```java 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`语句根据映射是否包含给定键输出消息。 ```java HashMap contains ger key HashMap does not contain rus key ``` 这是输出。 ## Java `HashMap replace()` 有`replace()`方法使程序员可以替换条目。 ```java replace(K key, V value) ``` 仅当当前映射到某个值时,此方法才替换指定键的条目。 ```java replace(K key, V oldValue, V newValue) ``` 仅当当前映射到指定值时,此方法才替换指定键的条目。 `com/zetcode/HashMapReplace.java` ```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()`。 ```java capitals.replace("day", "Sunday"); ``` 在这里,我们替换`"day"`键的值。 ```java capitals.replace("country", "Russia", "Great Britain"); ``` 在这种情况下,由于键当前未设置为`"Russia"`,因此不会替换该值。 ```java capitals.replace("colour", "blue", "green"); ``` 由于旧值正确,因此将替换该值。 ```java country=Poland colour=green day=Sunday ``` 这是输出。 ## Java `HashMap`转换为`List` 在下一个示例中,我们将`HashMap`条目转换为条目列表。 `com/zetcode/HashMapConvert.java` ```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` 我们使用 Java8 `forEach()`方法来迭代`HashMap`的键值对。 `forEach()`方法对映射的每个元素执行给定的操作,直到所有元素都已处理或该操作引发异常。 `com/zetcode/HashMapForEach.java` ```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()`。 ```java capitals.forEach((k, v) -> System.out.format("%s: %s%n", k, v)); ``` 使用`forEach()`,我们遍历了映射的所有对。 ## 使用增强的`for`循环迭代`HashMap` Java 5 中引入的增强的`for`循环可用于对`HashMap`进行迭代。 `com/zetcode/HashMapEnhancedFor.java` ```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`。 ```java 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` ```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`映射的键。 ```java Set<String> keys = capitals.keySet(); ``` 用`keySet()`方法检索`HashMap`的键,该方法返回键`Set`。 键必须唯一; 因此,我们有一个`Set`。 `Set`是一个不包含重复元素的集合。 ```java keys.forEach(System.out::println); ``` 我们用`forEach()`遍历键集。 ## Java `HashMap`迭代值 我们可能只想对`HashMap`的值进行迭代。 `com/zetcode/HashMapValues.java` ```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`的值。 ```java Collection<String> vals = capitals.values(); ``` `HashMap`的值通过`values()`方法检索。 ```java vals.forEach(System.out::println); ``` 我们使用`forEach()`遍历集合。 ## `HashMap`过滤 可以使用 Java 流 API 的`filter()`方法过滤`HashMap`。 `com/zetcode/HashMapFilter.java` ```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 的对。 ```java czk=Prague ger=Berlin pol=Warsaw ``` 这是输出。 ## 其他语言的 Java `HashMap`等效项 Ruby 具有哈希,Perl 具有哈希,PHP 具有数组,Python 具有字典,C# 具有字典,JavaScript 具有映射。 `ruby_hash.rb` ```java #!/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` ```java #!/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` ```java <?php $stones = [ 1 => "garnet", 2 => "topaz", 3 => "opal", 4 => "amethyst" ]; foreach ($stones as $key => $value) { echo "$key: $value\n"; } ?> ``` 这是一个 PHP 数组。 `python_dictionary.py` ```java #!/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` ```java 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` ```java 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`集合。 您可能也对相关教程感兴趣: [Java 中的`HashMap`迭代](/java/hashmapiterate/), [Java `ArrayList`教程](/articles/javaarraylist/), [Java `HashSet`教程](/java/hashset), [Java `static`关键字](/java/statickeyword/) 和 [Java 教程](/lang/java/)。 列出[所有 Java 教程](/all/#java)。 {% endraw %}