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

问一个 基础问题Set m = new HashSet(ls);
去掉重复数据,下面有两种写法:
1.                 List   ls   =   new   ArrayList();
                ls.add(new   String( "a "));
                ls.add(new   String( "a "));
                Set   m   =   new   HashSet(ls);
                System.out.println(m.size());

2.                 List   ls   =   new   ArrayList();
                ls.add(new   String[]   { "aa ",   "bb "});
                ls.add(new   String[]   { "aa ",   "bb "});
                Set   m   =   new   HashSet(ls);
                System.out.println(m.size());
运行后可以看到程序1输出的是1,而程序2输出的却是2。
本意是想用Set   m   =   new   HashSet(ls);去掉重复数据的,没想到碰到String[]类型的对象就不好用了。有谁知道是什么原因,请告知,谢谢!

------解决方案--------------------
Set中是采用equals来比较两个元素是否相同的。

String strA = new String( "a ");
String strB = new String( "a ");
那么strA.equals(strB)返回的结果是true。在向Set中添加时,认为这两个元素相同。

String[] arrA = new String[]{ "aa ", "bb "};
String[] arrB = new String[]{ "aa ", "bb "};
那么arrA.equals(arrB)返回false。在向Set中添加时,认为这两个元素不同。
------解决方案--------------------
String 与 String[] 当然不同。
前者,只是一种普通数据类型,比较的是其存储的字串内容。
后者,是数组对象,比较时是比较这些数组对象是否是同一个数组对象,而你用两次new String[]出来的数组对象肯定是不同的数组对象,所以被认为没有重复(地址)的数组对象。
------解决方案--------------------
数组尽管也是对象,不过跟一般的不同,没法override equals和hashCode方法,所以楼主的需求是达不到的
楼主既然用容器了,就不要再用数组了,不觉得矛盾吗?
还有,既然用到了HashSet,还要考虑覆盖hashCode方法,光equals还不够
------解决方案--------------------
如果一个数组作为一个单元的,不妨自己封装一个类,equals和hashCode方法override一下,也很方便的
------解决方案--------------------
比较数组元素是否相等用Arrays.equals(array1,array2);

数组本身.equals(另一个数组)=false;
------解决方案--------------------
是写个类来代替你原本String[]的功能,比如
class Unit{
private String[]values;
public boolean equals(Object o){
return o instanceof Unit && java.util.Arrays.equals((Unit)o.values, this.values);
}

public int hashCode(){//hashCode的算法可以自己随便定,但是要尽量减少hash值的重复
int hash=0;
for(int i=0; values!=null&&i <values.length; i++)
hash+=values[i].hashCode();

return hash;
}
}
------解决方案--------------------
然后你HashSet里存储的就是Unit的instances
------解决方案--------------------
ls.add(new String[] { "aa ", "bb "});
ls.add(new String[] { "aa ", "bb "});

你这不是把一个String[]作为一个存储单元考虑的吗
我给你的Unit类不是有一个private String[]values的吗,只不过包装了一下

楼主如果仍旧是以单个的String为单位的话,即你存储后只是想保留 "aa ", "bb ",就别用数组了,如果是这个意思的话,楼主的思想都是错的

------解决方案--------------------