Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What possible reason could there be for removing an element from a HashSet immediately prior to re-adding it?

Tags:

java

set

I've stumbled across some code that is broadly along the following lines, but cannot for the life of me fathom why the author is attempting to remove bar from bars before then adding it:

import java.util.Set;
import java.util.HashSet;

class Foo {

  private final Set<Object> bars = new HashSet<>();

  public void addBar(final Object bar) {
    bars.remove(bar);  // WHY ????
    bars.add(bar);
  }

  public Object[] getBars() {
    return bars.toArray(new Object[0]);
  }
}

All that I can come up with is that it's in anticipation of (or legacy from) a different Set implementation that's sensitive to insertion order, such as java.util.LinkedHashSet (although there's nothing about the code or use case that suggests insertion order would be of any interest) - but perhaps there's something else I'm missing?

like image 525
eggyal Avatar asked Oct 31 '18 09:10

eggyal


People also ask

How do I remove an element from a HashSet?

HashSet remove() method is used to remove a particular element from a HashSet.

Can we remove element from Set while iterating?

An element can be removed from a Collection using the Iterator method remove(). This method removes the current element in the Collection. If the remove() method is not preceded by the next() method, then the exception IllegalStateException is thrown.

What happens if a duplicate element object is added to a HashSet?

Duplicates: HashSet doesn't allow duplicate values. HashMap stores key, value pairs and it does not allow duplicate keys. If the key is duplicate then the old key is replaced with the new value.

How do I remove the first element from a HashSet in Java?

To remove a single element from a HashSet, use the remove() method.


1 Answers

If you have a class Bar that has fields that are not included in the equals check then this code causes the new instance (with potentially different contents) to be in the Set vs. the old instance remaining in the Set:

public static void main(String[] args) {
    Set<Object> bars = new HashSet<Object>();
    Bar bar1 = new Bar(1, 2);
    Bar bar2 = new Bar(1, 3);

    bars.add(bar1);
    bars.add(bar2); // no effect since bar1.equals(bar2)
    // only bar1 in the set

    bars.remove(bar2); // removes bar1 since bar1.equals(bar2)
    bars.add(bar2);
    // only bar2 in the set
}

static class Bar {
    int field1;
    int field2;

    public Bar(int field1, int field2) {
        this.field1 = field1;
        this.field2 = field2;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Bar)) return false;
        Bar bar = (Bar) o;
        return field1 == bar.field1;
    }

    @Override
    public int hashCode() {
        return Objects.hash(field1);
    }
}
like image 159
luk2302 Avatar answered Sep 24 '22 09:09

luk2302