compareTo__Treeset的详细应用

package org.lulu.interview;
 
public class Parent implements Comparable {
private int age = 0 ;
public Parent(int age) {
this.age =age;
}
@Override
public int compareTo(Object o) {
System.out.println("method of parent");
Parent o1 = (Parent) o;
return age>o1.age?1:age
}
 
}
 
 
package org.lulu.interview;
 
public class Child extends Parent{
 
public Child() {
super(3);
}
 
public int compareTo(Object o){
System.out.println("method of child");
// Child o1 = (Child) o;
return 1;
 
}
 
 
 
 
 
}
package org.lulu.interview;
 
import java.util.TreeSet;
 
public class TreeSetTest {
 
 
public static void main(String[] args) {
TreeSet set = new TreeSet();
set.add(new Parent(3));
set.add(new Child());
set.add(new Parent(4));
System.out.println(set.size());
 
}
 
}
 
2012-03-08 20:55
这三个类其实考点有这几个,一个是java继承中的重载,一个是compareble这个接口,一个是treeset这个类。
先来讲Compareble这个接口吧,他是JDK提供的一个用于对象之间比较大小的接口。如果你希望你所写的对象是可以比较的,那么就需要提供一种比较的方式。比如:Person这个类,里面有age,name两个属性,你有可能想要按照age来比较,年龄小的排在年龄大的前面。或者你也可以根据名字的字典顺序来比较。这个就可以用Compareble来实现。
 
再回来看,Compareble接口中有一个compareTo方法,需要接受一个被比较的对象,返回的是一个int型。 返回值分为三类:
>0 表示该值大于所传参数的值
<0 表示该值小于所传参数的值
=0 表示该值等于所传参数的值
比如,一个实现了Compareble接口的对象A。
A a1 = new A();
A a2 = new A();
a1.compareTo(a2) > 0 说明a1大于a2
 
很自然的,第一个类就解释的通了。
在Parent类中实现了这个compareTo方法,其比较规则是:
age>o1.age?1:age
翻译一下, 这句代码先判断age是否大于o1.age 如果大于,就返回1.
如果不大于,就判断age是否小于o1.age,如果小于就返回-1,
否则就返回0
符合我之前说的 >0 <0 =0 的说法
 
再来看第二个类,Child 继承了Parent并且重写了compareTo方法,重写为,先输出一句,然后返回1. 意思是无论跟谁比,被比的都要比它小。并且他还有一个特点就是age=3
例如,Child c1 = new Child();
Child c2 = new Child();
c1.compareTo(c2) // 这个结果不管c1 c2是什么情况,都应该认为c1>c2(因为compareTo返回是1,大于0)
反过来c2.compareTo(c1) // c2>c1,因为调用的是c2的方法。
 
第三个类,考你的是treeSet。 这个数据结构是一个有序的数据结构,你所插入的数据,会自动的排序。 比如你先后插入 2,3,1,6,5,0 最终会有序的排位0,1,2,3,5,6。
而且,他不允许重复值,比如你先插入3,再插入3,那么里面只有一个3,第二个3是插不进去的。
其原理就是调用一个对象的compareTo方法(否则他怎么知道谁大谁小呢)
 
所以,我们先来比较一下3个被加入treeset的对象的大小情况。
1) set.add(new Parent(3));
2) set.add(new Child());
3) set.add(new Parent(4));
1)号放入的age是3,没任何问题
接着放2)号,将会调用2)号的compareTo方法。而2号之前解释过了,无论怎样他都要比被比较的大,结论是2)号比1)号大。所以2)号放在1)号的后面。
接着放3)号,这里调用的又是parent的compareTo方法,这里比较的就是age的值了,结论是4比3大。那么3)号大于2)号,接着3)号放在2)号的前面。也没问题。
所以最后会有3个对象放入,顺序就是插入的顺序。
 
(如果都是调用parent中的compareTo,将会出现1号和2号相同,因此2好差不进去,最终set里面只有两个对象。这就是这题的最终考点)
 
有任何疑问,欢迎提问,乐意解答,为了熊猫。 
 
-------------------------20.55追加--------
以上解释了最后size=3. 也就是最后输出的那个3.
 
而那四句字符串的输出来源是pearent中的compareTo,和child的compareTo方法。
 
set.add(new Parent(3)); // 因为之前没有值,所以调用父类的compareTo和null比较,输出method of parent。但是优化后的treeset,在第一个插入的时候不会调用compareTo方法,因为不用比较他也是最小的。所以有可能不会输出第一句。我的机子就不会输出第一句
 
set.add(new Child()); //这个child对象放入set的时候,里面已经有一个对象,会调用child的compareTo方法,因此会多加一句method of child
 
set.add(new Parent(4));//调用父类的compareTo方法与第二个插入的比较,输出method of parent,接着调用了compareTo与第一个插入的比较,所以插入第三个的时候比较了两次。输出了两次
 
答案由此得来。
追问
您好,那假如我第一个改为set.add(new Parent(1)); 结果该怎么解释呢?
还有,// Child o1 = (Child) o;这句话是被注释掉的,为什么不能够写这句话呢?
麻烦您了
回答
第一个改成new Parent(1),结果应该是跟Parent(3)一样的。 因为是第一个放,跟null比较,输出一句method of parent(或者不输出,之前解释过了) 
有了Child o1 = (Child)o这句,将传入的比较对象转换成Child类。第二个放的是Child,在这之前已经有一个Parent存在,比较的时候调用Child的compareTo将Parent强行转成Child做比较,会报类型转换错误 
顺便说下,你的jdk是什么版本的,我试了好多台机子,然后看了源码,觉得第一个插入 都应该是不会调用compareTo才对
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值