使用自定义Pair对象作为键访问HashMap值

时间:2015-03-09 23:53:16

标签: java hashmap

我是Java的新手。我正在写一个2D游戏,我决定使用HashMap存储我的地图数据,因为我需要支持我的地图坐标的负指数。这是因为地图的大小可以在游戏中增长。

我编写了一个自定义Pair类,用于存储最终的x和y值。我使用这个Pair对象作为我的HashMap的关键。我的值是自定义Cell类的实例。

我已将HashMap声明如下:

HashMap<Pair, Cell> tiles = new HashMap<Pair, Cell>();

接下来,我使用以下命令向我的地图添加条目:

tiles.put(new Pair(0,0), new Cell());

0,0显然是我对这个细胞唯一的x,y坐标。

如何使用HashMap的.get()方法访问Cell的字段和方法,特定于单个Pair?例如Pair(0,0)或Pair(0,1)。如果键只是一个字符串或一个int,我就没有问题。我只是想不出如何为具有特定坐标的对象格式化我的键。

4 个答案:

答案 0 :(得分:3)

您需要覆盖equals类的hashCodePair方法。现在,如果您有两个Pair实例:

Pair p1 = new Pair(0,0);
Pair p2 = new Pair(0,0);

你的程序中的这两个实例被认为是平等的,因此如果你说:

tiles.put(p1, XXX);
tiles.put(p2, YYY);

行为会使你的地图有两个不同的键,有两个不同的值 - 我相信你想要的是一个键,这些语句执行后的最后一个值YYY。

在实现hashCodeequals之后,您可以编写一个静态帮助器方法,用一些给定的坐标实例化一个新的Pair,并执行一个地图查找:

static Cell lookup(int x, int y) {
    return tiles.get(new Pair(x, y));
}

这是一个基本的Pair类,可以帮助您入门:

public class Pair {

    private final int x;
    private final int y;

    public Pair(final int x, final int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (!(o instanceof Pair)) {
            return false;
        }

        final Pair pair = (Pair) o;

        if (x != pair.x) {
            return false;
        }
        if (y != pair.y) {
            return false;
        }

        return true;
    }

    @Override
    public int hashCode() {
        int result = x;
        result = 31 * result + y;
        return result;
    }
}

答案 1 :(得分:1)

你只需写下tiles.get(new Pair(0, 0)),就像你为put做的那样。

答案 2 :(得分:1)

您需要覆盖.equals()类型的方法.hashCode()Pair()。为了在HashMap中使用类型,需要它们。等于可以检查2个值是否相等:

@Override public boolean equals(Object o) {
    if(this == o) return true;
    if(!(o instanceof Pair)) return false;
    Pair p = (Pair)o;
    return p.x == x && p.y == y;
}

对于hashCode,您必须生成一个唯一的值:

private volatile int hashCode; // define this as a member of the class

@Override public int hashCode() {
    int result = hashCode;
    if(result == 0) {
        result = 17 * x + 31 * y;
        hashCode = result;
    }
    return result;
}

然后你可以通过简单地调用

来访问(0,0)的单元格
tiles.get(new Pair(0, 0));

答案 3 :(得分:0)

您需要覆盖hashCode()。类似的东西:

public int hashCode() {
    return 17 * this.key + 31 * this.value;
}