Comparable接口的实现

Comepareto

public static void main(String[] args) {
Set set=new TreeSet();
stu s1=new stu(12,"张三");
stu s2=new stu(10,"李四");
stu s3=new stu(14,"王武");
stu s4=new stu(10,"李四");
stu s5=new stu(13,"赵六");
set.add(s1);
set.add(s2);
set.add(s3);
set.add(s4);
set.add(s5); Iterator i=set.iterator();
for(;i.hasNext();){
//每个迭代器的.next才能得到一个对象
/**
 * 从打印结果我们可以看出,set容器默认的对于对象的比较,并不是单纯的从对象的值来比较
 名字李四的年龄是10
名字张三的年龄是12
名字李四的年龄是10
名字王武的年龄是14
 */
System.out.println(i.next().toString());
}
}

基础类:
public class stu {
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public stu(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "名字"+this.getName()+"的年龄是"+this.getAge();
}
}


上面的两个代码都很容易理解,但是当我们将我们的hashset转换为treeset的时候,代码就出问题了,这是为什么了?

看代码我们就可以发现,原来在treeset中,它对会使用元素的自然顺序(自然顺序:实现了comparable接口,并在里面定义了类的比较规则的方式)对元素进行排序。因此,如果我们添加的类如果没有实现comparable接口,那么在插入treeset的时候就会报错。

Exception in thread "main" java.lang.ClassCastException: stu cannot be cast to java.lang.Comparable

大家可能会觉得很奇怪,为什么我们添加string的时候它不会报错了。其实理由很简单,你查看comparable接口,看一下它的实现类你就知道答案了。

在这里为了书写的方便,我们使用了泛型,如果不会的可以先将<>和里面的内容删除,然后在代码中强转就行。
public class stu implements Comparable<stu>{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
public stu(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "名字"+this.getName()+"的年龄是"+this.getAge();
}
@Override
public int compareTo(stu o) {
if(this.getAge()<o.getAge()) return -1;
else if(this.getAge()>o.getAge()) return 1;
return 0;
}
   //有人比较搞笑的在这里直接返回1或者0,很明显如果是1的话,则全部插入,如果是0的话那肯定只有第一条。
}



虽然这段代码只修改了很小的一部分,但是很多人还是很不理解
compare里面的比较,实际上它的底层实现是一颗二叉树,我们可以在compareto方法中添加一句代码打印结果,System.out.println(this.getName()+"与"+o.getName()+"比较");

打印结果:

李四与张三比较

王武与张三比较

李四与张三比较

李四与李四比较

赵六与张三比较

赵六与王武比较

首先往数据中插入张三,然后插入李四的时候与张三做比较,李四比张三要下,那么就放在张三的左边

然后再插入王武,王武比张三要大,那么就放在张三的右边

然后现在插入另外一个李四,它一进来就的先跟张三比较,它比张三要小,那么它就在张三的左边,因此它跟李四比较,它跟李四一样大,因此就放不保存,hashset中,虽然我们没有设置equals方法,但是当我们有两个对象相等,不能区分那个对象该放在一个结点的左边还是右边的时候,我们是不会保存这个对象的。这个需要注意。

然后我们添加我们的赵六,同理,他会先去跟张三比较,他比张三要大,因此放在张三的右边,然后它会去跟王武比较,他比王武要小,因此他放在王武的左边。也许看到这你会有些奇怪,this.get方法指的是谁?

假实现:这就是java的一种机制,实际上这个this就是指跟这个二叉树的每个结点对象进行比较,你利用上述的system打印你就知道了。

特别要注意,hashset的底层实现是一个二叉树,它是不能够保存conpare函数返回0的值的(因为相等他们就应该处于统一位置,而二叉树每个结点的左右节点都有意义,因此不能够存放)。特别注意,插入第一个的时候是无需调用compare方法的。

当然这只是在类中实现的一种方法,你也可以在使用treeset的类中使用Comparator这个接口,比较的简单,只要实现这个比较器,然后将它作为参数传递到treeset中即可。下面便是一个简单的例子。

首先我们先定义一个comparator比较器,以便在new treeset中进行使用

public class compared02 implements Comparator {

	public int compare(Object o1, Object o2) {
		stu s1=(stu) o1;
		stu s2=(stu) o2;
		if(s1.getName().compareTo(s2.getName())>0)
		return 1; 
		else if(s1.getName().compareTo(s2.getName())<0)
			return -1;
		return 0;
	}

}


在创建中使用

                TreeSet set=new TreeSet(new compared02());
		stu s1=new stu(12,"aa");
		stu s2=new stu(10,"cc");
		stu s3=new stu(14,"bb");
		stu s4=new stu(10,"ed");
		stu s5=new stu(13,"dd");
		set.add(s1);
		set.add(s2);
		set.add(s3);
		set.add(s4);
		set.add(s5);
		Iterator i=set.iterator();
		for(;i.hasNext();){
			System.out.println(i.next().toString());
		}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值