eggyal
eggyal

Reputation: 125955

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

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?

Upvotes: 9

Views: 94

Answers (1)

luk2302
luk2302

Reputation: 57174

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);
    }
}

Upvotes: 7

Related Questions