HashMap有什么问题?

时间:2013-11-20 13:19:09

标签: 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? 为什么它在形状中找不到currShape

1 个答案:

答案 0 :(得分:1)

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

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