java 带有覆盖等于和 hashCode 的 HashMap 不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10702259/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
HashMap with override equals and hashCode not working
提问by Ravi Parekh
Sorry ... about this silly/stupid question, guys:
对不起......关于这个愚蠢/愚蠢的问题,伙计们:
Why aren't equals()
and hashCode()
being applied?
为什么不equals()
和hashCode()
被应用?
Currently they are only working as I expected for HashSet
.
目前他们只按我的预期工作HashSet
。
UPDATE
更新
EVEN key value 5 is repeated but it doesn't call equals and hashCode.
偶数键值 5 被重复,但它不会调用 equals 和 hashCode。
I want to apply it also on Value.
我也想将它应用于价值。
As just like HashSet calls equal and hashCode in this example, why hashMap is not being called equals and hashCode even if for key.
就像这个例子中 HashSet 调用 equal 和 hashCode 一样,为什么 hashMap 不被称为 equals 和 hashCode 即使是键。
UPDATE2 - ANSWER
UPDATE2 - 答案
HashMap's key(class->HashCode, equals) would be called. Thank you All. I was little bit confused on this. :)
HashMap 的 key(class->HashCode, equals) 将被调用。谢谢你们。我对此有点困惑。:)
public class Employee {
int id;
String name;
int phone;
public Employee(int id, String name, int phone) {
this.id = id;
this.name = name;
this.phone = phone;
}
// Getter Setter
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Employee other = (Employee) obj;
System.out.println("Employee - equals" + other.getPhone());
if (this.id != other.id) {
return false;
}
if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
return false;
}
if (this.phone != other.phone) {
return false;
}
return true;
}
@Override
public int hashCode() {
System.out.println("Employee - hashCode" );
int hash = 3;
hash = 67 * hash + this.id;
hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0);
hash = 67 * hash + this.phone;
return hash;
}
}
____________________________________________________________________________________
public class MapClass {
public static void main(String[] args) {
Map<Integer,Employee> map = new HashMap<Integer,Employee>();
map.put(1, new Employee(1, "emp", 981));
map.put(2, new Employee(2, "emp2", 982));
map.put(3, new Employee(3, "emp3", 983));
map.put(4, new Employee(4, "emp4", 984));
map.put(5, new Employee(4, "emp4", 984));
**//UPDATE**
map.put(5, new Employee(4, "emp4", 984));
System.out.println("Finish Map" + map.size());
Set<Employee> set = new HashSet<Employee>();
set.add(new Employee(1, "emp", 981));
set.add(new Employee(2, "emp2", 982));
set.add(new Employee(2, "emp2", 982));
set.add(new Employee(3, "emp3", 983));
set.add(new Employee(4, "emp4", 984));
set.add(new Employee(4, "emp4", 984));
System.out.println(set.size());
}
}
OUTPUT IS
输出是
Finish Map5
Employee - hashCode
Employee - hashCode
Employee - hashCode
Employee - equals982
Employee - equals982
Employee - hashCode
Employee - hashCode
Employee - hashCode
Employee - equals984
Employee - equals984
4
回答by Hovercraft Full Of Eels
EVEN key value 5 is repeated but it doesn't call equals and hashCode
偶数键值 5 被重复,但它不调用 equals 和 hashCode
Yes it does call hashCode, on the key, the Integer.
是的,它确实在键上调用了 hashCode,整数。
I want to apply it also on Value
我也想将它应用到 Value
Dose of reality: Java HashMaps don't work that way. They check the key only for duplicates, not the value, and this is as it should be.
现实情况:Java HashMap 不是那样工作的。他们只检查键是否重复,而不是值,这是应该的。
If you want Employee's hash to be checked in the Map, then it mustbe the key. Period.
如果您希望在 Map 中检查 Employee 的哈希值,那么它必须是键。时期。
Another possible solution is to download one of the multimaps that are available.
另一种可能的解决方案是下载一个可用的多地图。
Editto see that it's calling hashCode and equals, change your Map's key type to something like so:
编辑以查看它正在调用 hashCode 和 equals,将 Map 的键类型更改为如下所示:
class MyInt {
private Integer i;
public MyInt(Integer i) {
this.i = i;
}
public Integer getI() {
return i;
}
@Override
public int hashCode() {
System.out.println("MyInt HashCode: " + i.hashCode());
return i.hashCode();
}
@Override
public boolean equals(Object obj) {
System.out.printf("MyInt equals: [%s, %s]%n", i, obj);
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MyInt other = (MyInt) obj;
if (i == null) {
if (other.i != null)
return false;
} else if (!i.equals(other.i))
return false;
return true;
}
@Override
public String toString() {
return i.toString();
}
}
Then fill your Map like so:
然后像这样填充你的地图:
Map<MyInt,Employee> map = new HashMap<MyInt,Employee>();
map.put(new MyInt(1), new Employee(1, "emp", 981));
map.put(new MyInt(2), new Employee(2, "emp2", 982));
map.put(new MyInt(3), new Employee(3, "emp3", 983));
map.put(new MyInt(4), new Employee(4, "emp4", 984));
map.put(new MyInt(5), new Employee(4, "emp4", 984));
map.put(new MyInt(5), new Employee(4, "emp4", 984));
and you'll see:
你会看到:
MyInt HashCode: 1
MyInt HashCode: 2
MyInt HashCode: 3
MyInt HashCode: 4
MyInt HashCode: 5
MyInt HashCode: 5
MyInt equals: [5, 5]
回答by jeff
HashMap uses equals/hashCode of the Key value (in your case Integer). I think that's what you are asking, right?
HashMap 使用 Key 值的 equals/hashCode(在您的情况下为 Integer)。我想这就是你要问的,对吧?
The reason why you have duplicates in your map, is you are using a new key for the same Employee.
您的地图中有重复项的原因是您正在为同一个员工使用新键。
map.put(4, new Employee(4, "emp4", 345));
map.put(5, new Employee(4, "emp4", 345)); // You are using 5 as the key
// for the "same" object you did
// in the previous line
If you did something like
如果你做了类似的事情
// in main
addEmployee(new Employee(4, "emp4", 345));
addEmployee(new Employee(4, "emp4", 345));
private void addEmployee(Employee e)
{
map.put(e.getId(), e);
}
Then you would not see any duplicates in your collection.
这样您就不会在您的收藏中看到任何重复项。
回答by esej
HashMap uses the keys as index, not the values. (That is hashCode(), and maybe equals() gets called on the Integer class in your code above)
HashMap 使用键作为索引,而不是值。(那是 hashCode(),并且可能在上面的代码中的 Integer 类上调用了 equals())
回答by Alex Lockwood
You are using a HashMap<Integer, Employee>
, it looks like, so the Integer
s will be hashed. Since the keys are 1,2,3,4,5
, the size of your HashMap
should be 5.
您正在使用 a HashMap<Integer, Employee>
,看起来像,所以Integer
s 将被散列。由于键是1,2,3,4,5
,所以你的大小HashMap
应该是 5。