去掉重复数据,下面有两种写法:
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[]类型的对象就不好用了。有谁知道是什么原因,请告知,谢谢!

解决方案 »

  1.   

    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中添加时,认为这两个元素不同。
      

  2.   

    String 与 String[] 当然不同。
    前者,只是一种普通数据类型,比较的是其存储的字串内容。
    后者,是数组对象,比较时是比较这些数组对象是否是同一个数组对象,而你用两次new String[]出来的数组对象肯定是不同的数组对象,所以被认为没有重复(地址)的数组对象。
      

  3.   

    数组尽管也是对象,不过跟一般的不同,没法override equals和hashCode方法,所以楼主的需求是达不到的
    楼主既然用容器了,就不要再用数组了,不觉得矛盾吗?
    还有,既然用到了HashSet,还要考虑覆盖hashCode方法,光equals还不够
      

  4.   

    如果一个数组作为一个单元的,不妨自己封装一个类,equals和hashCode方法override一下,也很方便的
      

  5.   

    to theforever(碧海情天):
    我觉得你说的用词 不恰当啊。String 当然是对象,而你说的“普通数据类型”好像这个概念可以理解成“基本数据类型”那当然不是对象了,如果你说的是别的什么东东在下就不知道了。至于你说的“后者,是数组对象,比较时是比较这些数组对象是否是同一个数组对象,而你用两次new String[]出来的数组对象肯定是不同的数组对象,所以被认为没有重复(地址)的数组对象。”我就更不敢苟同了,equals比较得是 对象的内容,和地址没有任何关系,你就是 new 一百个String("abc"),他们也是不同的对象,但是用equals比较的结果是true.
    个人意见,呵呵。
      

  6.   

    比较数组元素是否相等用Arrays.equals(array1,array2);数组本身.equals(另一个数组)=false;
      

  7.   

    to believefym(feng):
    如果一个数组作为一个单元的,不妨自己封装一个类,equals和hashCode方法override一下,也很方便的
    ------------------------------------------------------------------------------
    能否说的详细些?你的意思是说要自己写一个类BHashSet来extendsHashSet吗?然后重写方法equals和hashCode?
      

  8.   

    是写个类来代替你原本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;
      }
    }
      

  9.   

    然后你HashSet里存储的就是Unit的instances
      

  10.   

    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;
      }
    }
    不太明白你写得这个类我要怎么用?能否细说一下?谢谢!
    String[] 对象我只是用来存储数据,然后我要去掉重复的就可以了。
      

  11.   

    ls.add(new String[] {"aa", "bb"});
    ls.add(new String[] {"aa", "bb"});你这不是把一个String[]作为一个存储单元考虑的吗
    我给你的Unit类不是有一个private String[]values的吗,只不过包装了一下楼主如果仍旧是以单个的String为单位的话,即你存储后只是想保留"aa","bb",就别用数组了,如果是这个意思的话,楼主的思想都是错的
      

  12.   

    believefym(feng),大概你没有明白我的意思.我现在有一个List 里面有几千个String[]对象.对于重复的数据只留一条.你的Unit Class似乎不好用吧??
      

  13.   

    believefym(feng),大虾的东东怎么用的啊?
      

  14.   

    楼主,你说的重复到底是什么意思
    你举个例子吧
    ls.add(new String[] {"aa", "bb"});
    ls.add(new String[] {"aa", "bb"});
    结果是什么?
      

  15.   

    List ls = new ArrayList();
    ls.add(new String[] {"aa", "bb"});
    ls.add(new String[] {"aa", "bb"});
    ...
    ...// todo process ls.remove repeated data我要得到没有重复数据的ls对象.即:这个对象new String[] {"aa", "bb"}在ls 里面有两个,我只想留一个.
    最后得到的结果是
    ls里面只有一个new String[] {"aa", "bb"}对象.上面只是举个例子,因为List里面有很多数据几千条,都是String[]对象,有很多重复的,对于重复的String[]对象我只想留一个.这次明白了吗?
      

  16.   

    再看看我的Unit类
    加个构造方法
    public Unit(String[]sa){
      this.values = sa;
    }ls.add(new Unit(new String[]{"aa","bb"}));//保证Unit的实例的唯一性,即保证String[]的唯一性,因为数组的特殊性,没有重写equals、hashCode方法来保证唯一性,无法实现楼主的需求。拿Unit包装一下String[]来间接实现达到目的。还不懂的话,我就无语了
      

  17.   

    在JAVA里面数组也是做为引用来处理的..
      而在JAVA如果没有在类中实现equals()的方法时,会默认为跟'=='相同,'=='含义应该知道吗?
    [摘自JAVA API中的Object equals()方法]
    Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。所以,你的两个字符串数组并不相等,因为它们的引用并不相同.当经过重写believefym(feng)提示的equals()和hashCode()方法后,可以实现当值相等时,那么euqals()返回true.而楼主的第一个程序,中间的String对象,因为JAVA本身已经重写了equals()和hashCode()方法.如下:[摘自JAVA src.zip中的java/lang/String.java]
        public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) {
    char v1[] = value;
    char v2[] = anotherString.value;
    int i = offset;
    int j = anotherString.offset;
    while (n-- != 0) {
        if (v1[i++] != v2[j++])
    return false;
    }
    return true;
        }
    }
    return false;
        }    public int hashCode() {
    int h = hash;
    if (h == 0) {
        int off = offset;
        char val[] = value;
        int len = count;            for (int i = 0; i < len; i++) {
                    h = 31*h + val[off++];
                }
                hash = h;
            }
            return h;
        }所以,JAVA会自动调用这两个方法,来进行对象的相等比较.   在这其中,要区别的是引用的默认比较规则.看下这篇文章吧!
    Java新手入门的30个基本概念[3] 
    http://community.csdn.net/Expert/topic/5310/5310996.xml?temp=7.429141E-02希望能够对你有点帮助...
      

  18.   

    to liput():
    "而在JAVA如果没有在类中实现equals()的方法时,会默认为跟'=='相同,'=='含义应该知道吗?"
    你说的这句话不对!!equals()和"=="是不一样的,即使不实现equals()方法,你用equals()和"=="也是不一样的!这是相当基础的知识。"=="比较的是地址,equals()比较的是内容。
    至于这个"Java新手入门的30个基本概念[3] 
    http://community.csdn.net/Expert/topic/5310/5310996.xml?temp=7.429141E-02"我想我不用看了。
    不过,到是有一个问题真要请教您了,public int hashCode() 这个方法是怎么个用法,您能给讲明白吗?
      

  19.   

    public boolean equals(Object obj) {
    return (this == obj);
        }这个是Object类equals方法的源代码,“这是相当基础的知识。"=="比较的是地址,equals()比较的是内容。”如果你没有override equals方法,谁知道你要比较的是内容,谁知道这个内容是怎么比较的
    楼主,基础有待提高
      

  20.   

    to believefym(feng):
    这下我就明白了,当我用Set set = new HashSet(ls);的时候,在构造HashSet时会去调用Unit的equals方法和hashCode方法进行比较,对吧?这样数组对象就相同了。谢谢!!
    能否再请教一下,这个hashCode()方法是作什么用的?
      

  21.   

    非常抱歉!!说错了。又加固了一个知识点,任何对象都继承自Object,而且都覆盖了equals()和hashCode()方法,在方法内你可以定义你要比较的东西。
      

  22.   

    学习   believefym(feng) ( ) 信誉:100