# Java 中的`HashMap`迭代

原文：http://zetcode.com/java/hashmapiterate/

Java 教程中的`HashMap`迭代演示了如何迭代 Java 中的`HashMap`。

## Java `HashMap`

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

`Map.Entry`表示`HashMap`中的键/值对。 `HashMap`的`entrySet()`返回包含在映射中的映射的`Set`视图。 使用`keySet()`方法检索一组键。

## 使用`forEach()`的`HashMap`迭代

在第一个示例中，我们使用 Java8 `forEach()`方法来迭代`HashMap`的键值对。 `forEach()`方法对映射的每个元素执行给定的操作，直到所有元素都已处理或该操作引发异常。

`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, 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 表达式迭代了`HashMap`和`forEach()`。

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

```

用两对创建一个`HashMap`。

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

```

`forEach()`使代码更简洁。

## 使用流 API 的`HashMap`迭代

流是来自源的一系列元素，支持顺序和并行聚合操作。 源可以是将数据提供给流的集合，IO 操作或数组。

`HashMapStreamApi.java`

```java
package com.zetcode;

import java.util.HashMap;

public class HashMapStreamApi {

    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());
        });
    }
}

```

该示例使用流 API 在`HashMap`上进行迭代。 我们使用`entrySet()`方法获得条目集，并使用`stream()`方法从条目集中获得流。 稍后，我们使用`forEach()`遍历流。

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

Java 5 中引入的增强的`for`循环可用于对`HashMap`进行迭代。

`HashMapEnhancedFor.java`

```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`。

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

```

在每个`for`周期中，都将新的键值对分配给`pair`变量。

## 使用`Iterator`的`HashMap`迭代

在下面的示例中，我们使用`Iterator`和`Map.Entry`遍历`HashMap`。

`HashMapIterator.java`

```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`循环中对映射进行迭代。

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

```

我们得到了迭代器对象。 首先，我们使用`entrySet()`方法获得条目集，然后使用`iterator()`方法从条目集中获得迭代器。

```java
while (it.hasNext()) {

```

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

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

```

`next`方法返回下一对。

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

```

使用`getKey()`和`getValue()`方法，我们可以获得键对和值。

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

`HashMapIterator2.java`

```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`。

在下一个示例中，我们使用`HashMap`的`keySet()`方法在迭代器上迭代键集，该方法返回此映射中包含的键的`Set`视图。 此迭代效率较低。

`HashMapIterator3.java`

```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`循环中使用迭代器来遍历映射的键。 以后使用该键获取相应的值。

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

```

我们得到键集的迭代器对象。

```java
while (it.hasNext()) {

```

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

```java
String key = it.next();

```

检索下一个键。

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

```

使用`get()`方法检索该值。

## `HashMap`迭代键

我们可能只需要遍历`HashMap`的键。

`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, 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`的键。

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

```

用`keySet()`方法检索`HashMap`的键，该方法返回键`Set`。 键必须唯一； 因此，我们有一个`Set`。 `Set`是一个不包含重复元素的集合。

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

```

我们用`forEach()`遍历键集。

## `HashMap`迭代值

我们可能只需要迭代`HashMap`的值。

`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, 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`的值。

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

```

`HashMap`的值通过`values()`方法检索。

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

```

我们使用`forEach()`遍历集合。

## 在包含`ArrayList`的`HashMap`上进行迭代

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

`HashMapList.java`

```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`循环。

```java
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`。

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

```

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

```java
String key = me.getKey();

```

我们通过`getKey()`方法获得键。

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

```

我们用`getValue()`获得列表。

```java
for (String e : values) {

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

```

在内部`for`循环中，我们遍历值列表。

## `HashMap`过滤

可以使用流 API 的`filter()`方法过滤`HashMap`。

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

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

```

在此示例中，我们有一个国家及其首都的映射。 我们将映射过滤为仅包含值以 B 开头的对。

在本教程中，我们展示了如何迭代 Java 中的`HashMap`。 您可能也对相关教程感兴趣： [Java `HashMap`教程](/java/hashmap/)， [Java8 `forEach`教程](/articles/java8foreach/)，[用 Java 读取文本文件](/articles/javareadtext/)，[读写 ICO Java 中的图像](/articles/javaico/)， [Java Swing 教程](/tutorials/javaswingtutorial/)，[Java 教程](/lang/java/)，[用 Java 显示图像](/java/displayimage/)。