A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 乔九 中级黑马   /  2013-2-23 09:49  /  1589 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

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());
                }

        }

}

评分

参与人数 1黑马币 +9 收起 理由
李培根 + 9 赞一个!

查看全部评分

4 个回复

正序浏览
我记得保证唯一性是要重写 equals 和 hash 方法 ,compator方法是用来排序的
回复 使用道具 举报
本帖最后由 王钊 于 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。

评分

参与人数 1技术分 +1 收起 理由
李培根 + 1 赞一个!

查看全部评分

回复 使用道具 举报
呵呵,你没有覆写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. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
李培根 + 1 赞一个!

查看全部评分

回复 使用道具 举报
TreeSet中的元素具有唯一性,你这是要重复插入“shjkghas”吗?
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马