我有一个定义节点的类(一个有三个双坐标的点).
public class Node {
private final double x, y, z;
public Node() {
}
public Node(final double x, final double y, final double z) {
this.x = x;
this.y = y;
this.z = z;
}
public void setCoordinates(final double x, final double y, final double z) {
this.x = x;
this.y = y;
this.z = z;
}
}
Run Code Online (Sandbox Code Playgroud)
我需要创建很多节点并给它们整数ID,但我必须避免重复.
创建节点的方法如下所示:
private Node vertex = new Node(0, 0, 0);
private final AtomicInteger nodeCounter = new AtomicInteger();
private final Map<Node, Integer> nodeList = new HashMap<>();
public int addNode(final double x, final double y, final double z) {
vertex.setCoordinates(x, y, z);
int nodeId;
if(nodeList.get(vertex) == null) {
nodeId = nodeCounter.incrementAndGet();
nodeList.put(new Node(x, y, z), nodeId);
} else {
nodeId = nodeList.get(vertex);
}
return nodeId;
}
Run Code Online (Sandbox Code Playgroud)
当然,这不起作用,因为总是返回的get功能.HashMapnull
所以我想我需要覆盖类中的hashCode方法Node.
我在这里看到如何为单个double做到这一点,但我不知道如何创建一个考虑节点的三个坐标的哈希函数.
我是否还必须覆盖该equals功能?或者hashCode函数是否足够?
所以我想我需要覆盖
hashCodeNode类中的方法.
这只是交易的一部分.您还需要覆盖equals以使您的类作为哈希映射的键工作:
@Override
public int hashCode() {
return 31*31*Double.valueOf(x).hashCode()
+ 31*Double.valueOf(y).hashCode()
+ Double.valueOf(z).hashCode();
}
@Override
public boolean equals(Object other) {
if (!(other instanceof Node)) {
return false;
}
Node n = (Node)other;
return x == n.x && y == n.y && z == n.z;
}
Run Code Online (Sandbox Code Playgroud)
在Java 8+中,Double.valueOf(x).hashCode()应该替换Double.hashCode(x)为避免不必要的装箱:
@Override
public int hashCode() {
return 31*31*Double.hashCode(x)
+ 31*Double.hashCode(y)
+ Double.hashCode(z);
}
Run Code Online (Sandbox Code Playgroud)
我是否还必须覆盖该
equals功能?或者hashCode功能足够吗?
是的,你必须始终覆盖equals沿hashCode(为什么?)
| 归档时间: |
|
| 查看次数: |
276 次 |
| 最近记录: |