- Java code
import java.util.HashSet;import java.util.Iterator;import java.util.Set;public class Test{ public static void main(String[] args) { Set<Element> set = new HashSet<Element>(); Element i1 = new Element(1); Element i2 = new Element(2); Element i3 = new Element(3); set.add(i1); set.add(i2); set.add(i3); System.out.println("Before changed:"); printSet(set); i1.setValue(2); System.out.println(i1.equals(i2)); System.out.println("After changed:"); printSet(set); } public static void printSet(Set set) { Iterator it = set.iterator(); while (it.hasNext()) { System.out.println(it.next()); } }}class Element{ private int value; public Element(int value) { this.value = value; } public void setValue(int value) { this.value = value; } public int getValue() { return this.value; } @Override public String toString() { return "" + this.value; } @Override public boolean equals(Object obj) { if(this ==(Element)obj) return true; if (!(obj instanceof Element)) { return false; } if (((Element) obj).getValue() == this.getValue()) { return true; } return false; } @Override public int hashCode() { return 37 + this.value; }}
在网上看到这个程序,这种先增加再修改的方法导致set有重复元素,是否违背了set的设计初衷呢
------解决方案--------------------
首先我不认为,这个反面的用例在瞎搞;相反我认为这个是对hashSet内部实现的比较了解的
基础上,对set规则的刻意破坏。set在添加元素时,依赖hashCode,
Equals两个函数的返回值。而楼主的用例,是在元素添加set以后,刻意去修还元素的数字以达到
修改hashCode,equals返回值,这是set出现“重复”也是自然的了。简单的说,set只在加入是会
检查数据的重复性,加入后就不管了(其实set也管不了)。
------解决方案--------------------
这个接口的API文档说的多好:
Note: Great care must be exercised if mutable objects are used as set elements. The behavior of a set is not specified if the value of an object is changed in a manner that affects equals comparisons while the object is an element in the set.
------解决方案--------------------
脑残好多啊。
Set只在add的时候保证唯一性,你add进来后再改Set就管不了了。
也就是说,Set中是可以存在非唯一性的情况的。
当然,正常情况下我们要避免add进来后再修改对象的值。