java - HashMap 如何保存和查找键

标签 java hashmap

我遇到了有关 HashMap 的问题。经过一番调试没有结果后,我编写了一小段代码来测试HashMap。但结果却更加令人困惑!

public static void main(String[] args) {
    Point a = new Point(0, 0);          // java.awt.Point
    Map<Point, Integer> map = new HashMap<Point, Integer>();
    map.put(a, 0);
    System.out.println(map.containsKey(new Point(0, 0)));    // true
    a.x = 1;
    System.out.println(map.containsKey(new Point(0, 0)));    // false
    System.out.println(map.containsKey(new Point(1, 0)));    // false
    System.out.println(map.containsKey(a));                  // false
}

我期望第二个或第三个输出能给我一个真实的结果,而第四个输出肯定是真实的。但事实似乎并不认同。


关于我改变 key 的意图,我使用 map 来保存一些小怪。生物具有 Point 字段,并且 map 的键使用相同的引用。然后我也许可以通过它的协调来寻找生物并且也可以轻松地改变协调。

最佳答案

您可以在 source code 中查找。并理解它,尽管并不像我想象的那么容易。

问题是,当您更改 x 的值时,哈希树中的对象似乎位于错误的位置,我将对此进行说明。

您将 key 放入一棵树中,如下所示:

.../-- Point(0,0)
root
---\.. nothing

如果将 Point(1,0) 放入其中,它将如下所示:

.../.. nothing
root
...\.. Point(1,0)

因此,当您更改 key 时,树看起来像这样:

.../.. Point(1,0)
root
...\.. nothing

现在您寻找Point(1,0),并且 map 遍历了该键应属于的较低分支,但什么也没有。当您查找 Point(0,0) 时,它会遍历存在错误键的上分支。

因此,永远不要更改对象 .hashCode() 中的值,这一点很重要。相反,使用该对象的新实例进行替换或使用该对象的克隆来放置在 HashMap 中。

或者,如果您想更改键,您可以将其从 map 中删除,更改它然后将其放回原处。如下所示:

public static void main(String[] args) {
    Point a = new Point(0, 0);          // java.awt.Point
    Map<Point, Integer> map = new HashMap<Point, Integer>();
    map.put(a, 0);
    System.out.println(map.containsKey(new Point(0, 0)));    // true
    Integer value = map.remove(a);
    a.x = 1;
    map.put(a,value);
    System.out.println(map.containsKey(new Point(0, 0)));    // false
    System.out.println(map.containsKey(new Point(1, 0)));    // true
    System.out.println(map.containsKey(a));                  // true
}

您可能希望将remove、alter 和put 方法转移到对象内自己的方法以使其可用。您可以调用它 setAndRelocate(int newX, int newY, Map container) 并将其放回到常规代码中的一行。

关于java - HashMap 如何保存和查找键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23075576/

相关文章:

java - 如何更改实际复选框内 J 复选框的背景颜色

java - 在 HashMap 中找不到自定义对象?

Java HashMap.containsKey() 不调用 equals()

java - jfreechart图表面板自动调整大小显示所有缩放图表

java - 从java类调用url一个接一个用于登录,另一个用于Web服务调用

java - 为java应用程序创建窗口服务

java - Spring Elasticsearch HashMap[String, String] 映射值不能not_analyzed

java - ArrayList vs HashMap——大量的迭代和对象操作

java - 带对象键的 HashMap

java - 如何创建包含所有java类常量的HashMap或Arraylist