插入HashMap与Hashset

时间:2018-05-05 08:06:42

标签: java collections hashmap hashset

HashMap的情况下,如果密钥重复,它会将旧值替换为新值。对于HashSet,项目根本不会插入。由于HashSet正在内部实施HashMap。为什么这两个插入处理方式不同?

1 个答案:

答案 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'}]

此外,您也不应该依赖它,因为其内部实施细节可以在以后的版本中更改,HashMapHashSet使用equals方法检查是否对象是一样的。如果你有一个equals返回true的两个对象,但是你仍然想要区别对待,那么实体设计中很可能存在一些问题,但是在极少数情况下会产生预期效果,在这种情况下,您可以查看IdentityHashMap