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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 傅宇 中级黑马   /  2013-3-23 22:22  /  2047 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 傅宇 于 2013-3-24 16:43 编辑
  1. import java.util.Iterator;
  2. import java.util.Set;
  3. import java.util.TreeSet;

  4. public class Demo1 {
  5.         public static void main(String[] args) {
  6.                 Set<Person> set = new TreeSet<Person>();
  7.                 set.add(new Person("zhangsan",29));
  8.                 set.add(new Person("lisi",30));
  9.                 set.add(new Person("wangwu",55));
  10.                 set.add(new Person("zhaoliu",33));
  11.                 set.add(new Person("lisi",34));
  12.                 set.add(new Person("chenqi",29));
  13.                 set.add(new Person("zhangsan",29));
  14.                
  15.                 Iterator<Person> it = set.iterator();
  16.                 while(it.hasNext()){
  17.                         Person p = (Person)it.next();
  18.                         System.out.println(p);
  19.                 }
  20.         }
  21. }

  22. class Person implements Comparable {
  23.         private String name;
  24.         private int age;

  25.         Person() {
  26.         }

  27.         Person(String name, int age) {
  28.                 this.name = name;
  29.                 this.age = age;
  30.         }

  31.         public void setName(String name) {
  32.                 this.name = name;
  33.         }

  34.         public void setAge(int age) {
  35.                 this.age = age;
  36.         }

  37.         public String getName() {
  38.                 return name;
  39.         }

  40.         public int getAge() {
  41.                 return age;
  42.         }

  43.         public int compareTo(Object obj) {
  44.                 if (!(obj instanceof Person)) {
  45.                         throw new RuntimeException("不是人");
  46.                 }
  47.                 Person p = (Person) obj;
  48.                 System.out.println(this.name+"...."+p.name);
  49.                 return this.age - p.age;
  50.         }

  51.         @Override
  52.         public String toString() {
  53.                 return "Person [name=" + name + ", age=" + age + "]";
  54.         }
  55. }
复制代码
求大神帮我分析下比较的过程。
lisi....zhangsan
wangwu....zhangsan
wangwu....lisi
zhaoliu....lisi
zhaoliu....wangwu
lisi....lisi
lisi....wangwu
lisi....zhaoliu
chenqi....lisi
chenqi....zhangsan
zhangsan....lisi
zhangsan....zhangsan

点评

记得及时处理帖子哦,继续追问,或将分类改成【已解决】,谢谢  发表于 2013-3-24 07:55

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

8 个回复

倒序浏览
从比较结果来看,你会发现Set采用的二分比较方式
回复 使用道具 举报
TreeSet集合底层数据结构是二叉树,通过自定义类实现Comparable接口或让集合本身具有比较性(通过匿名内部类,实现Comparator接口),重写compareTo(Object obj)或compare(Object obj1, Object obj2)方法,通过compareTo和compare方法来保障数据的唯一性,如果通过这两个方法返回0则表示同一个元素,如果返回值大于0存右边,如果小于0存左边,当向TreeSet集合添加元素时,添加的元素当然向集合中其他元素进行比较,只是我们不知道而已,你这里在compareTo()方法里写了调试语句,就可以看到它的比较过程。不能再分析了

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
  1. import java.util.Iterator;
  2. import java.util.Set;
  3. import java.util.TreeSet;

  4. public class Demo1 {
  5.         public static void main(String[] args) {
  6.                 Set<Person> set = new TreeSet<Person>();
  7.                 set.add(new Person("zhangsan",29));
  8.                 set.add(new Person("lisi",30));
  9.                 set.add(new Person("wangwu",55));
  10.                 set.add(new Person("zhaoliu",33));
  11.                 set.add(new Person("lisi",34));
  12.                 set.add(new Person("chenqi",29));
  13.                 set.add(new Person("zhangsan",29));
  14.                
  15.                 Iterator<Person> it = set.iterator();
  16.                 while(it.hasNext()){
  17.                         Person p = (Person)it.next();
  18.                         System.out.println(p);
  19.                 }
  20.         }
  21. }

  22. class Person implements Comparable {
  23.         private String name;
  24.         private int age;

  25.         Person() {
  26.         }

  27.         Person(String name, int age) {
  28.                 this.name = name;
  29.                 this.age = age;
  30.         }

  31.         public void setName(String name) {
  32.                 this.name = name;
  33.         }

  34.         public void setAge(int age) {
  35.                 this.age = age;
  36.         }

  37.         public String getName() {
  38.                 return name;
  39.         }

  40.         public int getAge() {
  41.                 return age;
  42.         }

  43.         public int compareTo(Object obj) {
  44.                 if (!(obj instanceof Person)) {
  45.                         throw new RuntimeException("不是人");
  46.                 }
  47.                 Person p = (Person) obj;
  48.                 System.out.println(this.name+"...."+p.name);  //其实你这里有个问题,这里输出的只是对象的名称,看出比较的顺序,并不是比较name属性
  49.                 return this.age - p.age;  //而这里只是通过比较age的大小来进行年龄从小到大排序,如果两个Person对象的age一样,而name不一样,
  50.         }                                    //这就不能算是同一个人吧?但是这里会把这两个Person当做同一个,后面的就存不到这个集合中了。

  51.         @Override
  52.         public String toString() {
  53.                 return "Person [name=" + name + ", age=" + age + "]";
  54.         }
  55. }
复制代码
以下这段代码可以进行一下修改:
  1. Person p = (Person) obj;
  2.                 System.out.println(this.name+"...."+p.name);
  3.                 return this.age - p.age;
复制代码
修改后代码如下:
  1.         Person p = (Person) obj;
  2.         System.out.println(this.name+"...."+p.name);
  3.         int num = this.age - p.age;
  4.         // // 当年龄相同的时候,你还得比较姓名是否相同
  5.         int num2 = (num == 0) ? this.name.compareTo(p.name) : num;
  6.         return num2;
复制代码

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
谢洋 发表于 2013-3-23 22:50
从比较结果来看,你会发现Set采用的二分比较方式

使用Set比的话,为什么到第3轮的时候比较的次数就少了一次,还有什么是二分比较啊?
回复 使用道具 举报
傅宇 发表于 2013-3-24 09:44
使用Set比的话,为什么到第3轮的时候比较的次数就少了一次,还有什么是二分比较啊? ...


问下度娘就行了
回复 使用道具 举报
本帖最后由 黑马朱超 于 2013-3-24 15:17 编辑
傅宇 发表于 2013-3-24 09:44
使用Set比的话,为什么到第3轮的时候比较的次数就少了一次,还有什么是二分比较啊? ...

第三个不是从第一个元素zhangsan的29开始比较而是从lisi的30开始比较。是因为系统在分析29,30和55之后取中间值30作为初始比较的元素,这就是二分比较。元素多的时候这样可以提高效率。见毕老师视频day15-03
08:00的视频.....

图示为添加的时候比较的示意图。

二分.png (23.7 KB, 下载次数: 9)

二分.png
回复 使用道具 举报
傅宇 中级黑马 2013-3-24 16:03:37
8#
黑马朱超 发表于 2013-3-24 15:09
第三个不是从第一个元素zhangsan的29开始比较而是从lisi的30开始比较。是因为系统在分析29,30和55之后取中 ...

谢谢哥们,明白了
回复 使用道具 举报
傅宇 发表于 2013-3-24 16:03
谢谢哥们,明白了

恩,不客气哈,....支持版主,把状态改改咯
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马