Skip to content

Instantly share code, notes, and snippets.

@filpano
Created May 15, 2019 14:00
Show Gist options
  • Save filpano/306556360f86b20085c8ab04809c0984 to your computer and use it in GitHub Desktop.
Save filpano/306556360f86b20085c8ab04809c0984 to your computer and use it in GitHub Desktop.
Set Hashcode contract violation example
import java.util.Set;
import java.util.HashSet;
import java.util.stream.Collectors;
public class HelloWorld{
public static void main(String []args){
Set<Obj> set = new HashSet<>();
Obj a = new Obj("a");
Obj b = new Obj("b");
set.add(a);
set.add(b);
System.out.println("Equal: " + a.equals(b)); // false
System.out.println("Set contains a: " + set.contains(a)); // true
System.out.println("Set contains b: " + set.contains(b)); // true
b.setName("a");
System.out.println("Equal: " + a.equals(b)); // true
System.out.println("Set contains a: " + set.contains(a)); // true
System.out.println("Set contains b: " + set.contains(b)); // true <-- false positive; undefined behaviour since Set contract was broken.
b.setName("c");
System.out.println("Equal: " + a.equals(b)); // false
System.out.println("Set contains a: " + set.contains(a)); // true
System.out.println("Set contains b: " + set.contains(b)); // false <-- set contract broken
System.out.println(set.stream().map(Obj::toString).collect(Collectors.joining(", "))); // a, c
}
static class Obj {
private String name;
public Obj(String name) {
this.name = name;
}
public int hashCode() {
return name.hashCode();
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object other) {
if (other == this) {
return true;
}
if (!(other instanceof Obj)) {
return false;
}
Obj o = (Obj) other;
return this.name == o.name;
}
@Override
public String toString() {
return name;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment