黑马程序员技术交流社区

标题: 视频程序中的一个小bug [打印本页]

作者: 乔九    时间: 2013-2-23 09:49
标题: 视频程序中的一个小bug
package com.itheima;
import java.util.*;
class strLengthcompare implements Comparator
{
        public int compare(Object o1,Object o2)
        {
                        String s1=(String)o1;
                String s2=(String)o2;
/*                if(s1.length()>s2.length())
                        return 1;
                if(s1.length()==s2.length())
                       
                return -1;*/
                int num=new Integer(s1.length()).compareTo(new Integer(s2.length()));
                if(num==0)
                        return s1.compareTo(s2);
                return num;
               
        }

}
public class Stringex {

        /**
         * @param args
         */
        public static void main(String[] args) {
                // TODO Auto-generated method stub
                TreeSet ts=new TreeSet(new strLengthcompare());
                ts.add("hsa");
                ts.add("hsuajkh");
                ts.add("shjkghas");
                ts.add("sejkghas");如果此处字符串为“shjkghas”还是没办法插入比较该如何重写Comparator??????
                Iterator it=ts.iterator();
                while(it.hasNext())
                {
                        System.out.println(it.next());
                }

        }

}
作者: 黑马刘杰    时间: 2013-2-23 10:09
TreeSet中的元素具有唯一性,你这是要重复插入“shjkghas”吗?
作者: 杨玲    时间: 2013-2-23 10:30
呵呵,你没有覆写Comparator方法吧?

这样是正常的,因为String类型的数据有这样一个特征,
  1. String str1 = "abc";
  2. String str2 = "abc";

  3. //那么str1和str2指向的是同一个地址,也就是说hashCode值相同
复制代码
而没有覆写Comparator方法,那么在往TreeSet中加入数据时,调用的其实是String类的Comparator方法。

所以,如果想要让向这样的两个字符串都加入到这个集合,可以通过String的子类来覆写Comparator,然后加入子类,

或者就是传入一个指定的比较器,至于如何覆写Comparator方法呢,嘿嘿,最简单的就是让没一个都返回不等了,

不然还真没办法办到,毕竟要从一个对象的两个引用上找到不同之处我办不到,所以只能不做判断,直接认为它们是不等的。
如:
  1. //我就只写下内部的代码哈,

  2. int compare(T o1, T o2)
  3. {
  4.    return -1;//或者1也行,别的没了
  5. }
复制代码

作者: 王钊    时间: 2013-2-23 10:59
本帖最后由 王钊 于 2013-2-23 11:01 编辑

int num=new Integer(s1.length()).compareTo(new Integer(s2.length()));
                 if(num==0)
                         return s1.compareTo(s2);
                 return num;
你写的比较器的规则是,如果长度不等比较长度,如果长度相等再用String的默认字母顺序比较。
你想插入“shjkghas”这个,这个和上一个长度也相同,字符转也相等,当然插不进去了。
如果你非想插入相同元素,我倒有一招,请看分解:
  1. int num=new Integer(s1.length()).compareTo(new Integer(s2.length()));
  2.                  if(num==0){
  3.                          //return s1.compareTo(s2);
  4.                                                 int result= s1.compareTo(s2);
  5.                                                 if (result!=0)//如果字符串值不相同,则正常比较。
  6.                                                 {
  7.                                                         return result;
  8.                                                 }
  9.                                                 else
  10.                                                 {
  11.                                                         //关键在这里,如果字符转值相同,则比较地址,如果是同一个对象,则不能插入,如果不是同一个对象,则后来的默认排在后面。
  12.                                                         return s1==s2?0:1;
  13.                                                 }
  14.                                  }        
  15.                  return num;
复制代码
如果你这样写ts.add("shjkghas");
                   ts.add("shikghas");
是不可能成功的,因为这两个是字符串池中的同一个对象,无论你怎么改写comparator,同一个对象都不能插入,因为地址相同。
但是如果你这样写ts.add("shjkghas");
                 ts.add(new String("shjkghas"))
能成功,因为虽然用String的默认自然排序,这两个是相同的,但是第一个是字符串池中的对象,第二个是堆中的对象,地址不同,不是同一个对象,
所以我的比较原则是后来的放在后面,能同时加入TreeSet。
作者: 张晨    时间: 2013-2-23 13:48
我记得保证唯一性是要重写 equals 和 hash 方法 ,compator方法是用来排序的




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2