返回

Java HashMap 中通过值获取键的最佳实践

java

从 Java HashMap 中获取键的最佳实践

问题:

在 Java HashMap 中存储键值对时,有时我们需要通过值获取键。然而,HashMap 中没有直接的方法可以做到这一点。因此,我们必须采用迂回的方法来获取键。

解决方案:

1. 使用 entrySet() 和 stream()

entrySet() 方法返回一个包含 HashMap 中所有键值对的 Set。我们可以使用 stream() 在此集合上进行流式操作,过滤出值与我们目标值匹配的条目,然后使用 getKey() 方法提取相应的键:

Map<String, String> ftw = new HashMap<>();
ftw.put("key1", "value1");
ftw.put("key2", "foo");
ftw.put("key3", "value3");

String key = ftw.entrySet().stream()
        .filter(entry -> entry.getValue().equals("foo"))
        .map(Map.Entry::getKey)
        .collect(Collectors.joining());

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

2. 使用 for-each 循环

我们可以使用 for-each 循环遍历 HashMap 的 entrySet(),并检查每个值是否与目标值匹配。如果匹配,则获取相应的键:

Map<String, String> ftw = new HashMap<>();
ftw.put("key1", "value1");
ftw.put("key2", "foo");
ftw.put("key3", "value3");

String key = null;
for (Map.Entry<String, String> entry : ftw.entrySet()) {
    if (entry.getValue().equals("foo")) {
        key = entry.getKey();
        break;
    }
}

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

3. 使用 Java 8 的 getOrDefault() 方法

Java 8 引入了 getOrDefault() 方法,它允许我们使用默认值来获取不存在的值。我们可以使用该方法来获取键值对,其中键不存在:

Map<String, String> ftw = new HashMap<>();
ftw.put("key1", "value1");
ftw.put("key2", "foo");
ftw.put("key3", "value3");

String key = ftw.getOrDefault("foo", null);

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

最佳方法的比较

以上方法各有优缺点:

  • entrySet() + stream():效率高,特别是对于大型 HashMap
  • for-each 循环:简单易懂,但效率稍低
  • getOrDefault():简洁,但仅当我们确定键存在时才适用

对于大多数情况,entrySet() + stream() 方法是获取 Java HashMap 中键的最佳方法,因为它提供了最佳的效率和灵活性。

常见问题解答:

  1. 我应该何时使用 entrySet() + stream() 方法?
    当需要从大型 HashMap 中获取键时,可以使用 entrySet() + stream() 方法。

  2. 为什么 for-each 循环的效率较低?
    for-each 循环必须遍历整个 HashMap,而 entrySet() + stream() 方法仅需要遍历匹配的键值对。

  3. getOrDefault() 方法有什么限制?
    getOrDefault() 方法仅适用于我们确定键存在的情况。

  4. 如何处理不存在的键?
    在使用 entrySet() + stream() 方法时,我们可以使用 Collectors.joining(null) 来返回 null 作为不存在的键。使用 for-each 循环时,我们可以在未找到匹配项时将其设置为 null。对于 getOrDefault() 方法,我们可以提供一个默认值。

  5. 这些方法的复杂度是多少?
    entrySet() + stream() 方法的时间复杂度为 O(n),其中 n 是 HashMap 中的键值对数。for-each 循环的时间复杂度也是 O(n)。getOrDefault() 方法的时间复杂度为 O(1),因为它直接从 HashMap 中获取键值对。