HashMap 是用新的 value 替换旧的,当您使用相同的键插入它时。
示例:
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,没有价值。因此,当已经存在的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不是,并且作为@ 987654336@ 使用它的键作为 HashMap 中的键,那么如果你把重复的键放在HashSet 它不会删除旧的。
示例:
假设我们有一些实体类,它有 2 个字段,int id 和 string 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。