一、Comparable接口
可以直接使用java.util.Arrays類進行數組的排序操作,但對象所在的類必須實現Comparable接口,用於指定排序接口。
Comparable接口定義如下:
public interface Comparable<T>{
public int compareTo(T o);
}
此方法返回一個int類型的數據,但是此int的值只能是一下三種:
1:表示大於
-1:表示小於
0:表示相等
樣例:
public 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 this.name + "\t\t" + this.age + "\t\t" + this.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 static void main(String[] args){
Student[] stu = {new Student("張三", 20, 90.0f), new Student("李四", 27, 99.0f),
new Student("王五", 22, 70.0f), new Student("趙六", 30, 100.0f)};
java.util.Arrays.sort(stu); //進行排序操作
for(int i = 0; i < stu.length; i++){ //循環輸出數組中的內容
System.out.println(stu[i]);
}
}
}
注意:如果在Student類中沒有實現Comparable接口,則在執行時會出現一下的異常Exception in thread "main" java.lang.ClassCastException;
二、比較器的排序原理
二叉樹的排序方法,通過二叉樹進行排序,之後利用中序遍歷的方式把內容一次讀取出來。
二叉樹排序的基本原理就是,將第一個內容作爲根節點保存,之後如果後面的值比根節點的值小,則放在根節點的左子樹上,如果後面的值比根節點的值大,則放在根節點的右子樹。
public class BinaryTree{
class Node{ //聲明一個節點類
private Comparable data; //保存具體的內容
private Node left; //保存左子樹
private Node right; //保存右子樹
public Node(Comparable data){
this.data = data;
}
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(data);
if(root == null){ //沒有根節點
root = newNode; //第一個元素作爲根節點
}else{
root.addNode(newNode); //確定是放在左子樹還是放在右子樹
}
}
public void print(){
this.root.printNode(); //通過根節點輸出
}
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();
}
}
三、Comparator接口
如果一個類已經開發完成,但是在此類建立的初期並沒有實現Comparable接口,此時肯定是無法進行對象排序操作的,所以爲了解決這樣的問題,java中定義了另一個比較器的操作接口----Comparator。此接口定義在java.util包中,接口定義如下:
public interface Comparator<T>{
public int compare(T o1, T o2);
boolean equals(Object obj);
}
import java.util.* ;
class Student{ // 指定類型爲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 ;
}
};
class StudentComparator implements Comparator<Student>{ // 實現比較器
// 因爲Object類中本身已經有了equals()方法
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)} ;
java.util.Arrays.sort(stu,new StudentComparator()) ; // 進行排序操作
for(int i=0;i<stu.length;i++){ // 循環輸出數組中的內容
System.out.println(stu[i]) ;
}
}
};
總結:
Comparator和Comparable的區別如下:
1.Comparable用在對象本身,說明這個對象是可以被比較的,也就是說可以被排序的。(String和Integer之所以可以比較大小,是因爲它們都實現了Comparable接口,並實現了compareTo()方法)。
2.Comparator用在對象外面,相當於定義了一套排序算法來排序。