ZetCode

Java 中的 HashMap 迭代

最后修改时间:2023 年 9 月 20 日

在本文中,我们将展示如何在 Java 中迭代 HashMap

Java HashMap

HashMap 是一个存储键值对的容器。每个键与一个值相关联。HashMap 中的键必须是唯一的。HashMap 在其他编程语言中称为关联数组或字典。HashMap 占用更多内存,因为每个值都有一个键。删除和插入操作需要恒定的时间。HashMap 可以存储空值。

Map.Entry 表示 HashMap 中的一个键值对。HashMapentrySet 返回包含在映射中的 Set 视图。一组键通过 keySet 方法检索。

使用 forEach 的 HashMap 迭代

在第一个示例中,我们使用 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, Integer> items = new HashMap<>();
        items.put("coins", 5);
        items.put("pens", 2);
        items.put("chairs", 7);

        items.forEach((k, v) -> {
            System.out.format("key: %s, value: %d%n", k, v);
        });
    }
}

在代码示例中,我们使用 lambda 表达式通过 forEach 迭代 HashMap

Map<String, Integer> items = new HashMap<>();
items.put("coins", 5);
items.put("pens", 2);
items.put("chairs", 7);

创建一个包含几对键值对的 HashMap

items.forEach((k, v) -> {
    System.out.format("key: %s, value: %d%n", k, v);
});

forEach 使代码更简洁。

使用 Stream API 的 HashMap 迭代

Stream 是来自源的元素序列,该源支持顺序和并行聚合操作。源可以是集合、IO 操作或数组,它们向流提供数据。

com/zetcode/HashMapStreamEx.java
package com.zetcode;

import java.util.HashMap;

public class HashMapStreamEx {

    public static void main(String[] args) {

        HashMap<String, Integer> items = new HashMap<>();
        items.put("coins", 5);
        items.put("pens", 2);
        items.put("chairs", 7);

        items.entrySet().stream().forEach(e -> {
            System.out.format("key: %s, value: %d%n", e.getKey(), e.getValue());
        });
    }
}

该示例使用 stream API 迭代 HashMap。我们使用 entrySet 方法获取条目集,并从条目集中使用 stream 方法获取流。稍后,我们使用 forEach 迭代流。

使用增强的 for 循环的 HashMap 迭代

增强的 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) {

        HashMap<String, Integer> items = new HashMap();
        items.put("coins", 5);
        items.put("pens", 2);
        items.put("chairs", 7);

        for (Map.Entry<String, Integer> pair: items.entrySet()) {
            System.out.format("key: %s, value: %d%n", pair.getKey(), pair.getValue());
        }
    }
}

在该示例中,我们使用增强的 for 循环迭代 HashMap

for (Map.Entry<String, Integer> pair: items.entrySet()) {
    System.out.format("key: %s, value: %d%n", pair.getKey(), pair.getValue());
}

在每个 for 循环中,一个新的键值对被分配给 pair 变量。


可以通过类型推断来简化该示例。

com/zetcode/HashMapEnhancedFor2.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 (var pair: capitals.entrySet()) {

            System.out.format("%s: %s%n", pair.getKey(), pair.getValue());
        }
    }
}

在 for 循环中,我们使用 var 关键字;Java 会自动推断类型。

使用 Iterator 的 HashMap 迭代

在以下示例中,我们使用 IteratorMap.Entry 迭代 HashMap

com/zetcode/HashMapIterator.java
package com.zetcode;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class HashMapIterator {

    public static void main(String[] args) {

        Map<String, Integer> items = new HashMap<>();
        items.put("coins", 5);
        items.put("pens", 2);
        items.put("chairs", 7);

        Iterator<Map.Entry<String, Integer>> it = items.entrySet().iterator();

        while (it.hasNext()) {
            Map.Entry<String, Integer> pair = it.next();

            System.out.format("key: %s, value: %d%n", pair.getKey(),
                    pair.getValue());
        }
    }
}

在代码示例中,我们检索键值对上的迭代器,并在 while 循环中迭代映射。

Iterator<Map.Entry<String, Integer>> it = items.entrySet().iterator();

我们获取迭代器对象。首先,我们使用 entrySet 方法获取条目集,然后从条目集使用 iterator 方法获取迭代器。

while (it.hasNext()) {

如果迭代具有更多元素,则迭代器的 hasNext 方法返回 true。

Map.Entry<String, Integer> pair = it.next();

next 方法返回下一对。

System.out.format("key: %s, value: %d", pair.getKey(),
        pair.getValue());

使用 getKeygetValue 方法,我们获取该对的键和值。

以下示例相同,但使用 for 循环而不是 while 循环。

com/zetcode/HashMapIterator2.java
package com.zetcode;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class HashMapIterator2 {

    public static void main(String[] args) {

        Map<String, Integer> items = new HashMap<>();
        items.put("coins", 5);
        items.put("pens", 2);
        items.put("chairs", 7);

        for (Iterator<Map.Entry<String, Integer>> it = items.entrySet().iterator();
                it.hasNext();) {

            Map.Entry<String, Integer> pair = it.next();
            System.out.format("key: %s, value: %d%n", pair.getKey(), pair.getValue());
        }
    }
}

在该示例中,我们使用迭代器和 for 循环迭代 HashMap

在下一个示例中,我们使用 HashMapkeySet 方法迭代键集,该方法返回包含在此映射中的键的 Set 视图。这种迭代效率较低。

com/zetcode/HashMapIterator3.java
package com.zetcode;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

public class HashMapIterator3 {

    public static void main(String[] args) {

        Map<String, Integer> items = new HashMap<>();
        items.put("coins", 5);
        items.put("pens", 2);
        items.put("chairs", 7);

        Iterator<String> it = items.keySet().iterator();

        while (it.hasNext()) {
            String key = it.next();

            System.out.format("key: %s, value: %d%n", key,
                    items.get(key));
        }
    }
}

在该示例中,我们使用迭代器迭代映射的键集。迭代器在 while 循环中使用,以遍历映射的键。该键稍后用于获取相应的值。

Iterator<String> it = items.keySet().iterator();

我们获取键集的迭代器对象。

while (it.hasNext()) {

在 while 循环中,我们遍历 HashMap 的键。

String key = it.next();

检索下一个键。

System.out.format("key: %s, value: %d%n", key,
        items.get(key));

使用 get 方法检索值。

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, Integer> items = new HashMap<>();
        items.put("coins", 5);
        items.put("pens", 2);
        items.put("chairs", 7);

        Set<String> keys = items.keySet();

        keys.forEach(System.out::println);
    }
}

该示例迭代 HashMap 的键。

Set<String> keys = items.keySet();

HashMap 的键使用 keySet 方法检索,该方法返回一个 Set 键。键必须是唯一的;因此,我们有一个 SetSet 是一个不包含重复元素的集合。

keys.forEach(System.out::println);

我们使用 forEach 遍历键集。

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, Integer> items = new HashMap<>();
        items.put("coins", 5);
        items.put("pens", 2);
        items.put("chairs", 7);

        Collection<Integer> vals = items.values();

        vals.forEach(System.out::println);
    }
}

该示例迭代 HashMap 的值。

Collection<Integer> vals = items.values();

HashMap 的值使用 values 方法检索。

vals.forEach(System.out::println);

我们使用 forEach 遍历集合。

迭代包含 ArrayList 的 HashMap

HashMap 可以包含列表作为值。在这种情况下,我们需要一个额外的循环。

com/zetcode/HashMapList.java
package com.zetcode;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HashMapList {

    public static void main(String[] args) {

        Map<String, List<String>> m = new HashMap<>();

        m.put("colours", Arrays.asList("red", "green", "blue"));
        m.put("sizes", Arrays.asList("small", "medium", "big"));

        for (Map.Entry<String, List<String>> me : m.entrySet()) {

            String key = me.getKey();
            List<String> values = me.getValue();

            System.out.println("Key: " + key);
            System.out.print("Values: ");

            for (String e : values) {

                System.out.printf("%s ", e);
            }

            System.out.println();
        }
    }
}

在该示例中,我们迭代一个包含 ArrayLists 作为值的 HashMap。我们使用两个 for 循环。

Map<String, List<String>> m = new HashMap<>();

m.put("colours", Arrays.asList("red", "green", "blue"));
m.put("sizes", Arrays.asList("small", "medium", "big"));

我们定义一个将 ArrayLists 作为值的 HashMap

for (Map.Entry<String, List<String>> me : m.entrySet()) {

使用增强的 for 循环,我们遍历条目集。每个条目都有一个键字符串和一个列表值。

String key = me.getKey();

我们使用 getKey 方法获取键。

List<String> values = me.getValue();

我们使用 getValue 获取列表。

for (String e : values) {

    System.out.printf("%s ", e);
}

在内部 for 循环中,我们迭代值列表。

HashMap 过滤

可以使用 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().startsWith("B"))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

        filteredCapitals.entrySet().forEach(System.out::println);
    }
}

在该示例中,我们有一个国家/地区的映射及其首都。我们过滤该映射,使其仅包含值以 B 开头的键值对。

来源

Java HashMap - 语言参考

在本文中,我们展示了如何在 Java 中迭代 HashMap

作者

我叫 Jan Bodnar,是一位充满热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直撰写编程文章。到目前为止,我已经撰写了 1,400 多篇文章和 8 本电子书。我拥有超过十年的编程教学经验。

列出所有Java教程