本章目标
掌握Comparable比较接口的使用
了解比较器的基本排序原理
掌握Comparator比较接口的使用
Comparable接口
可以直接使用java.util.Arrays类进行数组的排序操作,但对象所在的类必须实现Comparable接口,用于指定排序接口,
Comparable接口定义如下:
——public interface Comparable<T>{
public int compareTo(T o) ;
}
——此方法返回一个int类型的数据,但是此int的值只能是以下三种:
————1:表示大于
————-1:表示小于
————0:表示相等
定义比较规则,使用Arrays类进行排序
class Student implements Comparable<Student>{//指定泛型类型为 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){//覆写 compareTo() 方法,实现顺序规则的应用
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("赵三", 22, 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]);
}
}
/* 结果:
* 孙七 22 100.0
* 王五 20 99.0
* 张三 20 90.0
* 李四 22 90.0
* 赵三 22 70.0
* */
}
注意
如果在此时Student类中没有实现Comparable接口,则在执行时会出现以下的异常:
Exception in thread "main" java.lang.ClassCastException:
分析比较器的排序原理
实际上之前所讲解的排序过程,也就是经常听到数据结构中的二叉树的排序方法,通过二叉树进行排序,之后利用中序遍历的方式把内容依次读取出来。
二叉树排序的基本原理就是,将第一个内容作为根节点保存,之后如果后面的值比根节点的值小,则放在根节点的左子树,如果后面的值比根节点的值大,则放在根节点的右子树。
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;//如果是第 1 个元素,设置成根元素
}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(3);/*加入重复元素*/
bt.add(10);
bt.add(9);
bt.add(1);
bt.add(5);
bt.add(5); /*加入重复元素*/
System.out.println("排序之后的结果:");
bt.print();
}
/* 结果:
* 排序之后的结果:
* 1 3 3 5 5 8 9 10
* */
}
Integer为Comparable接口实例化
public class ComparableDemo02 {
public static void main(String[] args) {
Comparable com = null;//声明一个 Comparable 接口对象
com = 30;//通过 Integer 类为 Comparable 实例化
System.out.println("内容为:"+com);//实际上调用的是 toString() 方法
}
/* 结果:
* 内容为:30
* */
}
另一种比较器:Comparator
如果一个类已经开发完成,但是在此类建立的初期并没有实现Comparable接口,此时肯定是无法进行对象排序操作的,所以为了解决这样的问题,java又定义了另一个比较器的操作接口 —— Comparator。此接口定义在java.util包中,接口定义如下:
public interface Comparator<T> {
public int compare(T o1,T o2) ;
boolean equals(Object obj) ;
}
定义学生类
public 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){ // 覆写equals方法
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 void setName(String name){
this.name = name ;
}
public void setAge(int age){
this.age = age ;
}
public String getName(){
return this.name ;
}
public int getAge(){
return this.age ;
}
public String toString(){
return name + "\t\t" + this.age ;
}
}
定义比较规则
import java.util.Comparator;
//实现比较器接口
public class StudentComparator implements Comparator<Student> {
// 为学生类定义比较规则
public int compare(Student s1,Student s2){
if(s1.equals(s2)){//如果相等,则返回0
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)} ;
java.util.Arrays.sort(stu,new StudentComparator()) ; // 进行排序操作
for(int i=0;i<stu.length;i++){ // 循环输出数组中的内容
System.out.println(stu[i]) ;
}
}
/* 结果:
* 李四 22
* 孙七 22
* 张三 20
* 王五 20
* 赵六 20
* */
}