日期:2014-05-20  浏览次数:20726 次

set中真的不能添加重复元素吗?
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进来后再修改对象的值。