Comparable接口与Comparator接口

一.Comparable接口的使用

Comparable接口是定义在java.lang包中的,如下:

public interface Comparable<T>{
	public int comparaTo(T o);
}

此接口强行对实现它的每个类的对象进行整体排序。此排序被称为该类的自然排序 ,类的 compareTo 方法被称为它的自然比较方法 。实现此接口的对象列表(和数组)可以通过 Collections.sort (和 Arrays.sort )进行自动排序。

可以看到在Comparable接口中也使用了Java泛型技术,接口中只定义了comparaTo方法,返回一个int类型的数据:

1:表示大于

-1:表示小于

0:表示相等

下面看一个实例如何使用comparable接口实现对象排序:设计一个学生类,此类包含姓名、年龄、成绩,产生一个对象数组,要求按成绩由高到低排序,如果成绩相等,则按照年龄由低到高排序。

步骤:

1.创建学生类实现Comparable接口覆写compareTo()方法

2.调用java.util.Arrays.sort()方法排序

class Student implements Comparable<Student>{
	private String name;
	private int age;
	private float score;
	public Student(String name,int age,float score){
		this.name = name;
		this.age = age;
		this.score = score;
	}
	public String toString(){
		return name +"\t\t"+age+"\t\t"+score;
	}
	public int compareTo(Student stu){
		if(this.score > stu.score){
			return 1;
		}else if(this.score < stu.score){
			return -1;
		}else{
			if(this.age > stu.age){
				return 1;
			}else if(this.age < stu.age){
				return -1;
			}else{
				return 0;
			}
		}
	}
}
public class ComparableDemo01{
	public static void main(String[] args){
		Student stu[] = {new Student("张三",20,90.0f),new Student("李四",22,90.0f),new Student("王五",20,99.0f),
				 new Student("赵六",20,70.0f),new Student("孙七",22,100.0f)};
		java.util.Arrays.sort(stu);
		for(int i=0;i<stu.length;i++){
			System.out.println(stu[i]);
		}
	}
}

可以看到,要实现对象的排序,则该类必须实现Comparable接口,并且覆写里面的comparaTo()方法,指出排序规则,如果Student类没有实现Comparable接口,则会出现ClassCastException

二.Comparable接口比较的原理

之前我们学习Arrays时可以直接比较String类型的数据是因为String类本身就实现了Comparable接口,所以可以直接比较了,使用Comparable接口排序的原理实际上是数据结构中的二叉树排序方法,二叉树排序的基本原理:将第一个内容作为根节点保存,如果后面的值比根节点的值小,则放在根节点的左子树,如果后面的值比根节点的值大,则放在根节点的右子树,要注意一点,实现了Comparabe接口的对象可以用Comparable接口接收,下面以Integer作为范例,Integer类已经实现了Comparable接口

public class ComparableDemo02{
	public static void main(String[] args){
		Comparable com = null;
		com = 30;
		System.out.println("内容为:"+com);
	}
}

基于Comparable接口实现的二叉树操作:

class BinaryTree{
	class Node{
		private Comparable data;
		private Node left;
		private Node right;
		public void addNode(Node newNode){
			if(newNode.data.compareTo(this.data) < 0){
				if(this.left == null){
					this.left = newNode;
				}else{
					this.left.addNode(newNode);
				}
			}
			if(newNode.data.compareTo(this.data) >= 0){
				if(this.right == null){
					this.right = newNode;
				}else{
					this.right.addNode(newNode);
				}
			}
		}
		public void printNode(){	//输出时采用中序遍历
			if(this.left!= null){
				this.left.printNode();
			}
			System.out.print(this.data+"\t");
			if(this.right != null){
				this.right.printNode();
			}
		}
	}
	private Node root;
	public void add(Comparable data){
		Node newNode = new Node();
		newNode.data = data;
		if(root == null){
			root = newNode;
		}else{
			root.addNode(newNode);	//确定节点是放在左子树还是右子树
		}
	}
	public void print(){
		this.root.printNode();
	}
}
public class ComparableDemo03{
	public static void main(String[] args){
		BinaryTree bt = new BinaryTree();
		bt.add(8);
		bt.add(3);
		bt.add(4);
		bt.add(3);
		bt.add(4);
		bt.add(5);
		bt.add(6);
		bt.add(1);
		bt.add(2);
		System.out.println("排序之后的结果:");
		bt.print();
	}
}

三.Comparator接口的使用

如果一个类已经开发完成,但是此类建立的初期并没有实现Comparable接口,此时肯定是无法进行对象排序操作的。所以Java在java.util包中定义了Comparator接口

public interface Comparator<T>{
	public int compare(T o1,T o2);
	boolean equals(Object obj);
}

强行对某个对象 collection 进行整体排序 的比较函数。可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。

此类与Comparable接口不同的是需要单独指定好一个比较器的比较规则类才可以完成数组排序。下面定义一个学生类,其中有年龄和姓名属性,并按照年龄排序

步骤:

1.创建学生类,覆写equals(),toString()方法

2.创建StudentComparator类实现Comprator接口覆写compare()方法定义比较规则

3.调用java.util.Arrays.sort()方法

import java.util.*;
class Student{
	private String name;
	private int age;
	public Student(String name,int age){
		this.name = name;
		this.age = age;
	}
	public boolean equals(Object obj){
		if(this == obj){
			return true;
		}
		if(!(obj instanceof Student)){
			return false;
		}
		Student stu = (Student) obj;
		if(stu.name.equals(this.name) && stu.age == this.age){
			return true;
		}else{
			return false;
		}
	}
	public String toString(){
		return name +"\t" + age;
	}
	public String getName(){
		return name;
	}
	public void setName(String name){
		this.name = name;
	}
	public int getAge(){
		return age;
	}
	public void setAge(int age){
		this.age = age;
	}
}
//定义比较规则:
class StudentComparator implements Comparator<Student>{
	public int compare(Student s1,Student s2){
		if(s1.equals(s2)){
			return 0;
		}else if(s1.getAge() < s2.getAge()){
			return 1;
		}else{
			return -1;
		}
				
	}
}
//为对象数组进行排序
public class ComparatorDemo{
	public static void main(String[] args){
		Student stu[] = {new Student("张三",20),new Student("李四",22),new Student("王五",20),
				new Student("赵六",20),new Student("孙七",22)};
		Arrays.sort(stu,new StudentComparator());	//排序,制定排序规则
		for(int i = 0;i < stu.length;i++){
			System.out.println(stu[i]);
		}
	}
}

参考资料:李兴华老师java讲解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值