【问题标题】:How to find a key that corresponds to a value in a hashmap without iterating the table (Java)如何在不迭代表的情况下找到与哈希图中的值对应的键(Java)
【发布时间】:2014-03-05 20:17:51
【问题描述】:

我正在尝试为修改 put 函数的 HashMap 创建一个扩展。目标是让 put 函数不允许重复值。因此,如果有人在键/值 (A,a) 已经在映射中时尝试插入键/值 (B,a),那么它将用 (B,a) 替换键/值 (A,a) ) 而不是创建一个新的键/值对。

我遇到的问题是我不知道如何在不迭代表的情况下找到与值对应的键(我不能这样做,因为表是私有变量并且我无法访问它从我的功能扩展中)。

我还尝试使用 keySet() 检索键集,目的是在每个键上运行 get() 操作,但是 set 变量真的让我感到困惑,我不确定如何正确迭代和对单个元素运行 get() 操作。

编辑: 这是我到目前为止所拥有的: 导入 java.util.*;

公共类 UniqueHashMap 扩展 HashMap {

public V put(K key, V value) {

    boolean contains = containsValue(value);
    if (contains == true)
        // INSERT CODE HERE
    else
        return super.put(key, value);

}

}

在 if 语句中,我想做的是能够: 1)找到“value”对应的key。 2) 删除密钥。 3) 插入新的键/值对。

我遇到问题的部分是 1)因为我见过的大多数解决方案都需要访问地图(我不知道如何获得,因为它是 HashMap 中的私有变量)。我可以使用 keySet() 访问键,但我不知道如何在各个键上迭代地运行 get() 操作,因为我对 set 变量感到困惑。

【问题讨论】:

  • 你为什么不简单地交换键和值?似乎是在重新发明轮子。
  • 您似乎错误地使用了 HashMap。键应该是表示值的唯一限定符。我同意@Smutje - 听起来你的价值实际上就是你的关键。
  • 我不想交换键和值。我希望键和值都是唯一的。

标签: java loops hashmap


【解决方案1】:

一种方法:

import java.util.HashMap;
import java.util.Map.Entry;

public class MyHashMap<K, V> {
    private HashMap<K, V> map;

    void put(K key, V value) {
        if (map.containsValue(value)) {
            K keyToRemove = findKeyByValue(value);
            map.remove(keyToRemove);
            map.put(key, value);
        } else {
            map.put(key, value);
        }
    }

    private K findKeyByValue(V val) {
        for (Entry<K, V> e : map.entrySet()) {
            if (val == e.getValue())
                return e.getKey();
        }
        return null;
    }
}

但请注意,这样你将失去 HashMap 的 put 方法的恒定复杂性。

编辑:包括一个可编译的类

【讨论】:

  • 感谢您的回复。我试过了,但问题是我无权访问 Entry,因为它不是 HashMap 中的公共变量。我可以使用 keySet() 获取键列表,但是我不知道如何对键进行单独的 get() 操作,因为变量类型似乎存在一些问题。
  • 您无法访问该条目是什么意思? EntrySet 是一个公共方法 (docs.oracle.com/javase/7/docs/api/java/util/…)。通过迭代它,您可以获得每个条目。
  • 当我尝试运行它时,我得到错误:Entry is not public in HashMap;无法从外部包访问。抱歉 - 我多年来没有做过太多编程,而且是 Java 新手。
  • 我粘贴了一个可编译的类;看我编辑的帖子。这对我行得通。你有哪个java版本?
  • 运行最新版本的 Java。虽然仍然得到同样的错误。我编辑了我的原始帖子以显示我的代码。我尝试在我自己的代码下方插入您的 findKeyByValue 函数,但我收到有关无法访问条目的错误。
【解决方案2】:

我认为您正在寻找的是entrySet()Map 方法。这允许您一起迭代键和对应值对:

public void put(K key, V val) {
  Iterator<Map.Entry<K, V>> entries = entrySet().iterator();
  while (entries.hasNext()) {
    if (entries.next().getValue().equals(val)) {
      entries.remove();
      break;
    }
  }
  super.put(key, val);
}

【讨论】:

  • 啊哈!非常感谢!终于让这个工作了!感谢大家的帮助!
【解决方案3】:

您可以扩展 HashMap(最好自己实现 Map 并使用 HashMap 来实现它,以防他们添加更多添加方法),并覆盖每个添加方法:

If HashMap contains the key already
    grab the instance that the key refers to and remove it from the map, and re-put that instance into the map with the supplied key instead of the old key
Else
    Just put with the supplied key and value.

使用内部 HashSet 跟踪上次与键关联的值,这样您就可以对上面的 If 部分执行 O(1) 删除。

【讨论】:

    【解决方案4】:

    使用Google GuavaBiMap。它旨在处理这种情况,因为它是一个双向地图。

    你会打电话给Object key = myBiMap.inverse().get( myValue );

    【讨论】:

      猜你喜欢
      • 2010-12-03
      • 2020-12-13
      • 2016-01-05
      • 2019-10-16
      • 1970-01-01
      • 1970-01-01
      • 2019-09-08
      • 1970-01-01
      • 2018-11-15
      相关资源
      最近更新 更多