import java.util.*;
class U {
int x;
U(int x) {
this.x = x;
}
}
public class G {
public U a = new U(22);
public U b = new U(23);
Integer y = 22;
Integer r = 23;
void a() {
Map<U, Integer> set = new HashMap<U, Integer>();
set.put(a, y);
set.put(a, r);
set.put(b, y);
System.out.print(set.size() + " ");
}
public static void main(String[] args) {
G m = new G();
m.a();
}
}
我总是对地图和列表感到困惑。 我知道当map将密钥放入集合时,它会调用hashcode,如果存储桶相同,则调用equal方法。但是,我了解到如果类覆盖这两种方法,则不会存储重复的键。例如包装类:String实现自己的hashcode和equal方法。此外,如果您不这样做,则会调用唯一的哈希码,并将重复的密钥存储在集合中。
但是在上面的例子中,类U没有实现hashcode和equal方法。但是,Map不允许重复键。
我检查了SIZE:它的2 它应该是3,因为我的U类没有实现hashcode也不等。
请告诉我提前致谢
答案 0 :(得分:7)
HashMap
不允许重复的密钥
如果您没有提供hashcode()
和equals()
来自超级类的extends
(对于您的情况,它是java.lang.Object
),并且该实现提供了相同对象的相同哈希码和同一对象上的equals()
返回true
public boolean equals(Object obj) {
return (this == obj);
}
以及
答案 1 :(得分:1)
您使用U
的同一个实例作为密钥两次:
set.put(a, y);
set.put(a, r);
你提到的U
类没有实现hashCode()
,所以默认实现是Object#hashCode
,它显然是相同的,因为它是同一个实例。因此,地图将仅包含第二个条目。但是,如果您尝试以下操作,最终会有两个单独的条目:
set.put(new U(22), y);
set.put(new U(22), r);
但一般情况下,您始终希望为用作地图键的任何类实施equals()
和hashCode()
- 否则您无法查看该值而无法访问实例它存储为!
答案 2 :(得分:0)
通过设计哈希映射不添加重复键。它将使用该键替换映射中当前项的值。见http://docs.oracle.com/javase/7/docs/api/java/util/HashMap.html#put%28K,%20V%29
答案 3 :(得分:0)
如果您想添加重复的密钥,请尝试以下方法:
Map<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>();
map.put(1, new ArrayList<Integer>());
map.get(1).add(1);
map.get(1).add(2);