I have Set of that structure. I do not have duplicates but when I call:
set.add(element)
-> and there is already exact element I would like the old to be replac
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);
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.
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 key
s represent the HashSet's
values, this one is said to be "untouched".
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);