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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 司懿卓 于 2013-1-27 19:13 编辑

先上代码:
  1. public class Student implements Comparable        //comparable接口
  2. {
  3.         private String name;
  4.         private int age;
  5.         Student(String name, int age)
  6.         {
  7.                 this.name = name;
  8.                 this.age = age;
  9.         }
  10.         public String getName()
  11.         {
  12.                 return this.name;
  13.         }
  14.         public int getAge()
  15.         {
  16.                 return this.age;
  17.         }
  18.         public int hashCode()                //hashCode重写
  19.         {
  20.                 return this.name.hashCode() + this.age * 9;
  21.         }
  22.         public boolean equals(Object obj)        //equals重写
  23.         {
  24.                 if (!(obj instanceof Student))
  25.                         throw new ClassCastException("非法类型");        //RuntimeException
  26.                 Student stu = (Student)obj;
  27.                 return this.name.equals(stu.name)&& this.age == stu.age;
  28.         }
  29.         public int compareTo(Object obj)                //compareTo重写
  30.         {
  31.                 if (!(obj instanceof Student))
  32.                         throw new ClassCastException("非法类型");
  33.                 Student stu = (Student)obj;
  34.                 int num = new Integer(this.age).compareTo(new Integer(stu.age)); //比较
  35.                 if (num == 0)
  36.                         return this.name.compareTo(stu.name);        
  37.                 return num;
  38.         }
  39.         public String toString()
  40.         {
  41.                 return "name:" + name + ",age:" + age;
  42.         }
  43. }
复制代码
代码2:
  1. import java.util.*;
  2. public class TreeSetTest
  3. {
  4.         public static void sop(Object obj)
  5.         {
  6.                 System.out.println(obj);
  7.         }
  8.         public static void main(String[] args)
  9.         {
  10.                 TreeMap<Student, String> tm = new TreeMap<>(new Comparator<Student>()                //匿名内部比较器
  11.                 {
  12.                         public int compare(Student s1, Student s2)
  13.                         {
  14.                                 return 1;                //按照存入状态排序
  15.                         }
  16.                 });
  17.                 tm.put(new Student("张三", 19), "北京");
  18.                 tm.put(new Student("李四", 25), "上海");
  19.                 tm.put(new Student("王五", 18), "广东");
  20.                 tm.put(new Student("冯六", 19), "杭州");
  21.                 //第一种
  22.                 Set<Student> keySet = tm.keySet();                        //keySet获取key
  23.                 for (Iterator<Student> it = keySet.iterator(); it.hasNext(); )
  24.                 {
  25.                         Student stu = it.next();
  26.                         sop("name:" + stu.getName() + ", age:" + stu.getAge() +
  27.                                         ", addr:" + tm.get(stu));                //输出内容
  28.                 }
  29.                 //第二种
  30.                 Set<Map.Entry<Student, String>> entrySet = tm.entrySet();        //entrySet获取映射关系
  31.                 Iterator<Map.Entry<Student, String>> iter = entrySet.iterator();
  32.                 while (iter.hasNext())
  33.                 {
  34.                         Map.Entry<Student, String> me = iter.next();// Map.Entry是entrySet集合的元素类型.
  35.                         Student stu1 = me.getKey();
  36.                         String addre = me.getValue();
  37.                         sop("key=" + stu1 + ",addre:" + addre);
  38.                 }
  39.         }
  40. }
复制代码
上面的需求是对Student对象进行自定排序.
并且使用了两种Map集合输出方式.
但是,再加入匿名内部比较器后,第一种方法的addr无法正常输出.
第二种却可以.
取消比较器. 输出正常.
这是不使用比较器的输出结果:



这是使用比较器的输出结果:





---------------------------------------------------------------------------
谢谢帮忙解决问题的朋友..  还是自己的问题,在做其他练习,就想着等这个解决.  这是我的错.

public V get(Object key)返回指定键所映射的值,如果对于该键而言,此映射不包含任何映射关系,则返回 null。 更确切地讲,如果此映射包含从键 k 到值 v 的映射关系,根据该映射的排序 key 比较起来等于 k,那么此方法将返回 v;否则返回 null。(最多只能有一个这样的映射关系。)
上面的是API对get方法的解释..   如果重写了元素的比较器,也要注意其他情况..  这就是错误的例子.

感谢zyx67786110   以及所有回帖的朋友.

使用.jpg (53.86 KB, 下载次数: 206)

使用比较器

使用比较器

评分

参与人数 1技术分 +1 收起 理由
Rancho_Gump + 1

查看全部评分

7 个回复

倒序浏览
自定义的比较器和人和对象比较返回1,通过get方法获取value是获取不到的,因为比较key都是返回的1
回复 使用道具 举报
本帖最后由 司懿卓 于 2013-1-27 13:42 编辑
黑马刘向阳 发表于 2013-1-27 12:55
自定义的比较器和人和对象比较返回1,通过get方法获取value是获取不到的,因为比较key都是返回的1 ...

比较器是用于内部排序的..  通过排序后的key来获取value的..  这貌似和key本身排序应该没有关系的吧
回复 使用道具 举报
如果是比较器破坏了TreeSet集合的数据结构的映射关系.那么 用entrySet方法获取的也应该是被破坏的,
为什么entrySet方法可以,而keySet方法不行..  
郁闷~~
回复 使用道具 举报
我猜的啊,可能是这样(不一定对啊),我把你的代码改了一下,表示地址的String放在了泛型的前面,自定义了一个构造器尖括号里是String,采用第一种打印方式,结果打印的地址是出现了
但是学生的信息全为null,但是采用Map.Entry第二种迭代方式却全部都打印了出来,由此可见表示value的Student对象确实是添加进来TreeMap集合,但是因为在创建TreeMap
对象时指定了构造器(构造器的泛型只有一个),以至于该集合虽然能添加key和value但是当从该集合取出数据时只能取出key,value虽然存在但你无权取得,我觉得你现在得去翻一下源码了
回复 使用道具 举报
vmvm555 发表于 2013-1-27 16:05
我猜的啊,可能是这样(不一定对啊),我把你的代码改了一下,表示地址的String放在了泛型的前面,自定义了一 ...

谢谢啦..  但是entrySet和keySet都是在通过构造器排序后使用的.
如果数据结构遭到破坏,那entrySet也应该无法获取的啊.
如果在put元素后 再次直接打印集合(就是数组的自身的toString)
会发现,key对应的value依然健在的.

输出结果:  这个是在两种输出方式之前直接toString的..
  1. {name:张三,age:19=北京, name:李四,age:25=上海, name:王五,age:18=广东, name:冯六,
  2. age:19=杭州}
复制代码
回复 使用道具 举报
本帖最后由 zyx67786110 于 2013-1-27 18:54 编辑

因为你的comparator写的有问题,你每次都返回-1,虽然实现了按输入顺序排序,但也带来了很多问题。比如,可以输入重复元素,因为每次比较都不等;还有一个就是你现在程序出现的问题,每次当你从新建的Set集合取出一个key(stu)去找它对应的值时,它要先将这个key跟tm的每个key比较,由于比较器返回的都是1,没有==0,即相等的情况,所以每次返回的都是null了。
回复 使用道具 举报
zyx67786110 发表于 2013-1-27 18:27
因为你的comparator写的有问题,你每次都返回-1,虽然实现了按输入顺序排序,但也带来了很多问题。比如,可 ...

受教了..   
谢谢帮忙找出问题点..  
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马