Replacing a HashSet Java member

不问归期 提交于 2019-12-01 15:40:38

Do a remove before each add:

 someSet.remove(myObject);
 someSet.add(myObject);

The remove will remove any object that is equal to myObject. Alternatively, you can check the add result:

 if(!someSet.add(myObject)) {
     someSet.remove(myObject);
     someSet.add(myObject);
 }

Which would be more efficient depends on how often you have collisions. If they are rare, the second form will usually do only one operation, but when there is a collision it does three. The first form always does two.

If the set already contains an element that equals() the element you are trying to add, the new element won't be added and won't replace the existing element. To guarantee that the new element is added, simply remove it from the set first:

set.remove(aWordInfo);
set.add(aWordInfo);

Try something as follows (this will only make sense if the equals and hashCode depends on one field, but the other fields could have different values):

if(!set.add(obj)) {
    //set already contains the element (not the same object though) 
    set.remove(obj); //remove the one in  the set
    set.add(obj); //add the new one
}

Check out the documentation for the Set.add method

If this set already contains the element, the call leaves the set unchanged and returns false.

I was working on a problem where I had a set then I wanted to replace/override some of the objects with objects from another set.

In my case what I ended up doing was creating a new set and putting the overrides in first then adding the current objects second. This works because a set won't replace any existing objects when adding new objects.

If you have:

Set<WordInfo> currentInfo;
Set<WorldInfo> overrides;

Instead of:

for each override, replace the object in current info

I did:

Set<WordInfo> updated = new HashSet<>();
updated.addAll(overrides);
updated.addAll(currentInfo);

Check the HashSet code within the JDK. When an element is added and is a duplicate, the old value is replaced. Folk think that the new element is discarded, it's wrong. So, you need no additional code in your case.

UPDATED---------------------

I re-read the code in JDK, and admit a mistake that I've made.

When put is made, the VALUE is replaced not the KEY from an HashMap.

Why am I talking about Hashmap??!! Because if you look at the HashSet code, you will notice:

public boolean add(E e) {
    return map.put(e, PRESENT)==null;
}

So the PRESENT value is replaced with the new one as shown in this portion of code:

      public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key);
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

But I agree, the key isn't replaced, and since the keys represent the HashSet's values, this one is said to be "untouched".

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!