我有一个HashMap<Point, T>
数据结构,它包含几个映射到类T
的其他实例的点。当我的类被实例化时,这个映射给出了一些默认值:
T t1 = new T();
T t2 = new T();
Point p1 = new Point(0, 1);
Point p2 = new Point(0, 2);
HashMap<Point, T> map = new HashMap<Point, T>();
static {
map.put(p1, t1);
map.put(p2, t2);
}
在我的代码中,我将接收包含x
和y
值的事件。当我收到其中一个事件时,我正在尝试使用传递的Point
和x
创建一个新的y
对象,然后像这样从地图中检索值:
Point p = new Point(event.getX(), event.getY); // Assume (x, y) = (0, 1) (p1)
if(p.equals(p1)
T t = map.get(p);
虽然在这种情况下p
等于p1
(使用(x,y)=(0,1)我从{{1}返回null
值我认为这是因为map
中的hashCode()
方法使用了Point (Point2D)
之外的其他方法来计算唯一的哈希,它应该防止冲突。
我的问题是:如何使用新实例equals
从map
中检索值?是否有其他适合用例的数据结构?
我想我可以使用p
或其他一些映射,例如toString()
,或者我可以扩展HashMap<String, T>
类和Point
Override
方法以适应我的目的。但是,如果有一种更清洁的方式我会喜欢听到它,这些方式会感到“hacky”。
答案 0 :(得分:5)
如果两个对象根据
equals(Object)
方法相等,则在两个对象中的每一个上调用hashCode
方法必须产生相同的整数结果。
在您的情况下,似乎两个Point
个对象相等(根据equals
方法),但它们的哈希码是不同的。这意味着您需要修复equals
和hashCode
函数,使其保持一致。
答案 1 :(得分:2)
您可以尝试编写一个自包含的示例,例如我们可以运行的
Map<Point, String> map = new LinkedHashMap<>();
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++)
map.put(new Point(i, j), "(" + i + "," + j + ")");
// test the map
int misMatches = 0;
for (int i = 0; i < 10; i++)
for (int j = 0; j < 10; j++) {
String expected = "(" + i + "," + j + ")";
String text = map.get(new Point(i, j));
if (!expected.equals(text)) {
System.err.println("Expected <" + expected + "> but got <" + text + ">");
misMatches++;
}
}
System.out.println(misMatches + " mis-matches found.");
打印
0 mis-matches found.
答案 2 :(得分:2)
我认为Point类的equals()或hashcode()没有任何问题。试试这个:
public static void main(String args[]) {
Map<Point, Integer> map = new HashMap<Point, Integer>();
Point p1 = new Point(0, 1);
Point p2 = new Point(0, 2);
map.put(p1,1);
map.put(p2,2);
Point p = new Point(0, 1);
if(p.equals(p1)){
System.out.println(map.get(p));
}
else{
System.out.println("not");
}
}
它产生了正确的结果。
我猜你没有正确地初始化地图。
答案 3 :(得分:1)
hashCode()应使用与equals()相同的属性,以保持一致。
另请参阅:What issues should be considered when overriding equals and hashCode in Java?