java - HashMap 有什么问题?

标签 java user-interface hashmap

我的代码:

这是一个GUI程序

我画了一些矩形,并将它们放入 HashMap 形状中(使用 addShape()); currShape 指向鼠标所按住的形状。 当鼠标按下(mousePressed())时,我想更改该项目,但尽管hashCode()和equal()相同,但我找不到它。

HashMap<Shape, ShapeInfo> shapes;
private Shape currShape = null;

public void addShape(Point point)
{
    switch (actState)
    {
    case DRAWREC:
        currShape = new Rectangle(point);
        break;

    case DRAWCIR:
        currShape = new Ellipse2D.Double(point.getX(), point.getY(), 10.0, 10.0);
        break;

    case DRAWLIN:
        currShape = new Line2D.Double(point.getX(), point.getY(), point.getX(), point.getY());
        break;

    default:
        break;
    }
    shapes.put(currShape, new ShapeInfo(false, color));
    repaint();
}


public Shape findShape(Point point)
{
    int curx = point.x, cury = point.y;

    for (Shape shape : shapes.keySet())
    {
        if (shape instanceof Rectangle)
        {
            Rectangle rec = (Rectangle)shape;
            if (!drawCompleted(rec) && (rec.contains(point) ||
                rec.contains(curx, cury - ShapeInfo.SIZE) || rec.contains(curx, cury + ShapeInfo.SIZE) ||
                rec.contains(curx - ShapeInfo.SIZE, cury) || rec.contains(curx + ShapeInfo.SIZE, cury)))
                return shape;
        }
    }
    return null;
}



public void mousePressed(MouseEvent event)
{
        Shape shape = findShape(event.getPoint());
    System.out.println(shape);
    if (currShape != null && currShape != shape)
        setComplted();

    currShape = shape;
    if (event.getButton() == MouseEvent.BUTTON1 && 
        currShape == null || drawCompleted(currShape))
        addShape(event.getPoint());

    posState = getPos(event.getPoint());
}


public void setComplted()
{
    try 
    {
        System.out.println("Completed");
        System.out.println(shapes.size());
        for (Shape shape : shapes.keySet())
        {
            if (shape.equals(currShape))
                System.out.println("equal : " + shape + ":" + shape.hashCode());
            else
                System.out.println(shape + ":" + shape.hashCode());
        }


        System.out.println("Current" + ":" + currShape + ":" + currShape.hashCode());

        System.out.println(shapes.containsKey(currShape) + "\n");


    }
    catch (Exception error)
    {
        error.printStackTrace();
    }
}

结果是

equal
java.awt.Rectangle[x=199,y=37,width=176,height=194]:776675328
java.awt.Rectangle[x=199,y=37,width=176,height=194]:776675328
false

hashCode() 是一样的,equals() 返回 true,但是为什么 containKey 返回 false? 为什么在shapes中找不到currShape

最佳答案

问题是 Rectangle 是一个可变类,可变类的实例不是好的哈希键。添加它们后,您不得修改它们。如果您在添加后修改它们,它们的哈希码会发生变化,并且查找可能会失败。迭代时您仍然会遇到该对象,但依赖哈希码(及其不变性)的所有操作都将失败。

请注意,如果您不需要在 equals 方法意义上查找相等实例,但想要查找实例,则可以使用 IdentityHashMap 。这将忽略形状的状态并找到实例,即使发生变异,但是,例如创建一个等效的矩形来查找匹配项是行不通的。你不能两者兼得。

关于java - HashMap 有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20097112/

相关文章:

java - LeanFT & Java : Run tests in Docker containers

user-interface - 下拉列表 Windows Phone 7

java - 为什么散列集合需要根据教学负载因子调整大小,为什么我们不能等到集合满了

java - 将值与文本文件中 HashMap 中的键相关联 [Java]

java - libsvm java 中的交叉验证准确性

java - HBase java.lang.OutOfMemoryError 错误

java - Commons 编解码器中的 Base64.decode(privateKeyString, Base64.DEFAULT)

java - 固定尺寸 Swing GUI 在使用不同分辨率时发生变化

javascript - 如果不使用 "background-attachment: fixed !important; "渐变就不起作用?还有什么选择呢?

java - Map 上的集合操作