在HashMap
的情况下,如果密钥重复,它会将旧值替换为新值。对于HashSet
,项目根本不会插入。由于HashSet
正在内部实施HashMap
。为什么这两个插入处理方式不同?
答案 0 :(得分:1)
HashMap
会将旧的值替换为新的值。
例如:
Map<Integer, String> map = new HashMap<>();
map.put(1, "first put");
System.out.println(map.get(1)); // <-- prints `first put`
map.put(1, "second put");
System.out.println(map.get(1)); // <-- prints `second put`
所以基本上当新值到达时,地图中已经存在一个键,它只是替换了该键的值,因为即使键是相同的,新值也可能与此键中的值不同。地图。
如果是HashSet
,则只有键,没有值。因此,当已经存在的key
到来时,就会有,它已经存在了。
关于HashSet
的内部实施,实际上它在内部使用HashMap
,但它的作用是,它只创建一个object
:
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
当您add
设置一些key
时,它只会在此地图上调用put(key, present)
,对所有条目使用相同的对象(为了不分配大量无用的对象:
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
总而言之,确实HashSet
使用内部HashMap
,当您将某些内容添加到哈希地图时,始终会分配新值而不是旧值,但key
不是#39; t,并且HashSet
使用其键作为HashMap中的键,然后如果您在HashSet
中放入重复键,则它不会删除旧键。
例如:
假设我们有一些实体类有2个字段,int id
和字符串name
,但只有id
参与equals
方法实现。
Entity entity1 = new Entity(1, "some name");
Entity entity2 = new Entity(1, "some other name");
System.out.println(entity1.equals(entity2)); // returns true
Map<Integer, Entity> map = new HashMap<>();
map.put(entity1.id, entity1);
map.put(entity2.id, entity2);
System.out.println(map.get(entity1.id).name); // returns "some other name"
Map<Entity, String> keyMap = new HashMap<>();
keyMap.put(entity1, entity1.name);
keyMap.put(entity2, entity2.name);
System.out.println(keyMap.keySet()); // returns [Entity{id=1, name='some name'}]
System.out.println(keyMap.values()); // returns [some other name]
Set<Entity> set = new HashSet<>();
set.add(entity1);
set.add(entity2);
System.out.println(new ArrayList<>(set)); // returns [Entity{id=1, name='some name'}]
此外,您也不应该依赖它,因为其内部实施细节可以在以后的版本中更改,HashMap
和HashSet
使用equals
方法检查是否对象是一样的。如果你有一个equals
返回true
的两个对象,但是你仍然想要区别对待,那么实体设计中很可能存在一些问题,但是在极少数情况下会产生预期效果,在这种情况下,您可以查看IdentityHashMap
。