英文:
How to use an Object array as a key in hashmap
问题
我有一个名为 Position[]
的对象数组,它返回一个 Position 对象的数组。我想将其用作哈希映射的键,如下所示:HashMap<Position[],Double> h = new HashMap<>();
我理解,即使元素相同,数组也会有不同的哈希码。所以我尝试重写 equals 和 hashcode 方法。这是我的尝试:
public class Key {
private Position p1;
private Position p2;
public Key(Position p1, Position p2){
this.p1 = p1;
this.p2 = p2;
}
@Override
public boolean equals(Object object) {
if (!(object instanceof Key)) {
return false;
}
Key newKey = (Key) object;
return this.hashCode() == newKey.hashCode(); //有点取巧的方式
}
@Override
public int hashCode(){
int result = 17;
result = 31 * result + this.p1.hashCode();
result = 31 * result + this.p2.hashCode();
return result;
}
}
所以我不得不将我的映射更改为 HashMap<Key,Double>
,然而,每当我使用键获取值时仍然返回 null。
Key 构造函数中可以传递的示例为 G2 G4
或 E4 E6
等。
我该如何实现才能使比较真正起作用呢?
谢谢。
英文:
I have an object array called Position[]
that returns an array of Position objects. I would like to use this as my key for a hashmap for the following: HashMap<Position[],Double> h = new HashMap<>();
I understand that arrays have different hashcodes even if the elements are the same. So I went ahead and tried to override the equals and hashcode. This was my attempt:
public class Key {
private Position p1;
private Position p2;
public Key(Position p1, Position p2){
this.p1 = p1;
this.p2 = p2
}
@Override
public boolean equals(Object object) {
if (!(object instanceof Key)) {
return false;
}
Key newKey = (Key) object;
return this.hashCode()== newKey.hashCode(); //bit of a hack way
}
@Override
public int hashCode(){
int result = 17;
result = 31 * result + this.p1.hashCode();
result = 31 * result + this.p2.hashCode();
return result;
}
}
So I had to change my map to HashMap<Key,Double>
However, when ever i go to get the value using the key is still returns null.
An example of what can be passed into they constructor of Key are G2 G4
or E4 E6
ETC.
How would I go about achieving this so that the comparisons actually work?
Thanks.
答案1
得分: 1
你可以创建一个特殊的包装对象,使用Arrays.deepEquals(Object[], Object[])
和Arrays.deepHashCode(Object[])
来实现equals(Object)
和hashCode()
方法,将Position[]
作为Map
中的键。
import java.util.Arrays;
public final class PositionArrayKey {
private final Position[] array;
public PositionArrayKey(Position[] array) {
this.array = array;
}
@Override
public boolean equals(Object object) {
if (object == this) return true;
if (!(object instanceof PositionArrayKey)) return false;
return Arrays.deepEquals(this.array, ((PositionArrayKey) object).array);
}
@Override
public int hashCode() {
return Arrays.deepHashCode(this.array);
}
}
这样可以将经过包装的Position[]
数组实例作为键存储在映射中,例如:
Map<PositionArrayKey, Object> map = new HashMap<>();
map.put(new PositionArrayKey(new Position[]{...}), ...);
Object value = map.get(new PositionArrayKey(new Position[]{...}), ...);
(假设在此示例中,两个
Position[]
数组在深度上是相等的)
请注意,对于大型数组,调用equals(Object)
和hashCode()
可能会导致性能下降。如果有必要,你可以修改上述代码片段,为较大的数组缓存Arrays.deepHashCode(this.array)
的结果。
英文:
You can create a special wrapper object to use Position[]
as a key in a Map
, using Arrays.deepEquals(Object[], Object[])
and Arrays.deepHashCode(Object[])
in the implementations of equals(Object)
and hashCode()
.
import java.util.Arrays;
public final class PositionArrayKey {
private final Position[] array;
public PositionArrayKey(Position[] array) {
this.array = array;
}
@Override
public boolean equals(Object object) {
if (object == this) return true;
if (!(object instanceof PositionArrayKey)) return false;
return Arrays.deepEquals(this.array, ((PositionArrayKey) object).array);
}
@Override
public int hashCode() {
return Arrays.deepHashCode(this.array);
}
}
This enables storing Position[]
array instances as keys in map, when wrapped. E.g.
Map<PositionArrayKey, Object> map = new HashMap<>();
map.put(new PositionArrayKey(new Position[]{...}), ...);
Object value = map.get(new PositionArrayKey(new Position[]{...}), ...);
> (assuming that both of the Position[]
arrays are deeply equal in this example)
Note that for large arrays, performance for invoking equals(Object)
and hashCode()
may be slow. You can modify the above snippet to cache the result Arrays.deepHashCode(this.array)
for larger arrays, if you find it necessary.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论