Java容器之Comparable接口的使用

Java容器之Comparable接口的使用

*<1>可以直接使用java.util.Arrays類進行數組的排序,但對象所在的類必須實現Comparable接口
*<2>public interface Comparable<T>此接口強行對實現它的每個類的對象進行整體排序。此排序
 被稱爲該類的自然排序,類的 compareTo 方法被稱爲它的自然比較方法。
*<3>實現此接口的對象列表(和數組)可以通過 Collections.sort(和 Arrays.sort)進行自動
  排序。實現此接口的對象可以用作有序映射表中的鍵或有序集合中的元素,無需指定比較器。


  方法摘要:
有且唯一的方法:int compareTo(T o)比較此對象與指定對象的順序。如果該對象小於、等於或大於指定對象,則分別
返回負整數、零或正整數。


要求:  定義一個學生類,含有姓名,年齡,分數三個屬性,要求成績按高到低排序,如果成績相等按年齡從小到大排序...
package comparable;

import java.util.Arrays;

class Student implements Comparable<Student>{
    private String name;
    private int age;
    private float score;
   
 Student(String name, int age, float score) {
  this.age = age;
  this.name = name;
  this.score = score;
 }
  
 @Override
 public String toString(){
  return name + "\t\t" + age + "\t\t" + score  + "\t\t";
 }

    //覆寫compareTo方法
 public int compareTo(Student stu) {
        if(this.score > stu.score){
         return -1;
        }
        if(this.score < stu.score){
         return 1;
        }else {
         if(this.age < stu.age){
          return -1;
         }if(this.age > stu.age){
          return 1;
         } else {
          return 0;
         }
        }
 }
}

public class ComparableDemo {
 public static void main(String[] args) {
  Student [] stus = {new Student("s1",20,99f),
     new Student("s2",21,99f),new Student("s3",20,89f),
     new Student("s4",23,94f),new Student("s5",23,100f),
     new Student("s6",19,78f)};
  
  Arrays.sort(stus);
  
  for(Student stu : stus){
   System.out.println(stu);
  }
  
 }
}
需要進行比較的類必須實現Comparable接口,否則將報Exception in thread "main" java.lang.ClassCastException: comparable.Student異常


2: 分析比較器的排序原理
<1>比較器的排序原理實際上是使用了二叉樹的排序方法,通過二叉樹進行排序,之後利用中序遍歷的方式把內容一次讀取出來.
<2>二叉樹排序的基本原理是,將第一個內容作爲根節點保存,之後如果後面的值比根節點小,則作爲左子樹,如果後面的值比根節點
   大,則作爲右子樹.
    如:給出如下數據.  6,2,4,7,3,8,12,1
    則二叉樹爲:
              
                 6
       2      7
     1   4       8
                     3           12
                解釋:  3是4的左子樹
 
手工實現一個二叉樹的排序方法:(使用Integer類完成public final class Integerextends Numberimplements Comparable<Integer>)


package comparable;

/**
 * 驗證只要實現了Comparable接口,就可以使用Comparable接口聲明對象
 * @author Administrator
 *
 */
public class ComparableDemo2 {
    public static void main(String[] args) {
        Comparable com =null;   //聲明一個Comparable接口對象
        com = 30;           //通過Integer爲Comparable接口對象賦值
        System.out.println(com);
 }
}

                   12
     1            23
        2                223
    5          124     235
                4    5         162
                 

       1 2 4 5 5 12 23 124 162 223 235


package comparable;

/**
 * 二叉樹<根據中序排序遍歷二叉樹>
 * @author Administrator
 *
 */
class BinaryTree {
 /*
  * 節點對象
  */
 class Node {
  private Comparable data;    //數據
  private Node lNode;      //左子樹
  private Node rNode;       //右子樹
  public Node(Comparable data){
   this.data = data;
  }
  //添加子節點,判斷是放在左子樹還是放在右子樹
  public void addNode(Node newNode) {
   //this表示的是跟節點<...>
   if(this.data.compareTo(newNode.data) > 0){   //節點內容小於根節點內容
    if(this.lNode != null){
     this.lNode.addNode(newNode);
    } else {
     this.lNode = newNode;
    }
   }
   if(this.data.compareTo(newNode.data) <= 0){    //節點內容大於根節點內容
    if(this.rNode != null){
     this.rNode.addNode(newNode);
    } else {
     this.rNode = newNode;
    }
   }
  }
  
  /**
   * 按照中序排序打印二叉樹的節點內容
   */
  public void printData(){
   if(this.lNode != null){   //如果左節點不等於空,先打印左節點的內容
    this.lNode.printData();
   }
   
//   else {
//    System.out.print(this.data + "\t");   
       //如果將165行內容改爲這樣,就會導致當某節點既沒有左節
       //點右沒有有節點時其父節點將跳過輸出
//   }
   
   System.out.print(this.data + "\t");    //否則打印根節點的內容,注意該句所方的位置
   
   if(this.rNode != null){
    this.rNode.printData();   //如果右節點不爲空,打印有節點的內容
   }
  }
 }
 
 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(){
  root.printData();   //根據根節點打印二叉樹
 }
 
}

/**
 * 手工實現二叉樹的排序
 * @author Administrator
 *
 */
public class ComparableDemo3 {
 public static void main(String[] args) {
        BinaryTree bt = new BinaryTree();
        bt.add(12);
        bt.add(23);
        bt.add(1);
        bt.add(2);
        bt.add(5);
        bt.add(223);
        bt.add(124);
        bt.add(5);
        bt.add(235);
        bt.add(162);
        bt.add(4);
       
        //按中序打印二叉樹的內容
        bt.print();
 }
}


package comparable;

/**
 *  二叉樹<根據先序排序遍歷二叉樹>
 */
class BinaryTree2{
 /*
  * 採用內部類,定義一個節點類
  */
 class Node{
  private Comparable<String> data;   //節點內容
  private Node left;   //左節點
  private Node right;  //右節點
  
  /**
   * 構造函數
   * @param data 節點內容
   */
  public Node(Comparable<String> data){
   this.data = data;
  }

  /**
   * 根據節點內容添加新的節點,將第一個節點作爲根節點,若後面的節點的小於根節點,則
      * 作爲左子樹,若後面的節點的內容大於等於根節點,則作爲右子樹
   * @param newNode  新節點
   */
  public void addNode(Node newNode) {
   if(this.data.compareTo((String) newNode.data) > 0){
    //'根節點'內容大於新節點內容,作爲左子樹保存
    if(this.left != null){
     this.left.addNode(newNode);
    } else {
     this.left = newNode;
    }
   }
   if(this.data.compareTo((String) newNode.data ) <= 0){
    //'根節點'內容小於等於新節點內容,作爲右子樹保存
    if(this.right != null){
     this.right.addNode(newNode);
    } else {
     this.right = newNode;
    }
   }
  }
  
  /**
   * 根據先序排序方法打印二叉樹節點內容
   */
  public void printNode(){
   System.out.print(this.data + "\t");
   if(this.left != null){
    this.left.printNode();
   }
   if(this.right != null){
    this.right.printNode();
   }
  }
 }
 
 public Node root;    //根節點
 
 /**
  * @param data   加入的新節點的內容,該節點類型實現了Comparable接口,且爲String類型 
  */
 public void add(Comparable<String> data){
  Node newNode = new Node(data);  //根據節點內容新建一個節點
  if(root == null){
   root = newNode;
  } else {
   root.addNode(newNode);    //調用Node的addNode方法
  }
 }
 
 /**
  * 根據先序排序打印二叉樹節點內容
  */
 public void print(){
  root.printNode();
 }
 
}


/**
 * 採用先序排序輸出二叉樹的內容
 * @author Administrator
 *
 */
public class ComparableDemo4 {
    public static void main(String[] args) {
  BinaryTree2 bt2 = new BinaryTree2();
  bt2.add("y");
  bt2.add("q");
  bt2.add("l");
  bt2.add("i");
  bt2.add("z");
  bt2.add("h");
  bt2.add("n");
  bt2.add("l");
  bt2.add("u");
  bt2.add("a");
  
  bt2.print();
 }
}

 

package comparable;

/**
 *  二叉樹<根據後序排序遍歷二叉樹>
 */
class BinaryTree2{
 /*
  * 採用內部類,定義一個節點類
  */
 class Node{
  private Comparable<String> data;   //節點內容
  private Node left;   //左節點
  private Node right;  //右節點
  
  /**
   * 構造函數
   * @param data 節點內容
   */
  public Node(Comparable<String> data){
   this.data = data;
  }

  /**
   * 根據節點內容添加新的節點,將第一個節點作爲根節點,若後面的節點的小於根節點,則
      * 作爲左子樹,若後面的節點的內容大於等於根節點,則作爲右子樹
   * @param newNode  新節點
   */
  public void addNode(Node newNode) {
   if(this.data.compareTo((String) newNode.data) > 0){
    //'根節點'內容大於新節點內容,作爲左子樹保存
    if(this.left != null){
     this.left.addNode(newNode);
    } else {
     this.left = newNode;
    }
   }
   if(this.data.compareTo((String) newNode.data ) <= 0){
    //'根節點'內容小於等於新節點內容,作爲右子樹保存
    if(this.right != null){
     this.right.addNode(newNode);
    } else {
     this.right = newNode;
    }
   }
  }
  
  /**
   * 根據後序排序方法打印二叉樹節點內容
   */
  public void printNode(){
   if(this.left != null){
    this.left.printNode();
   }
   if(this.right != null){
    this.right.printNode();
   }
   System.out.print(this.data + "\t");
  }
 }
 
 public Node root;    //根節點
 
 /**
  * @param data   加入的新節點的內容,該節點類型實現了Comparable接口,且爲String類型 
  */
 public void add(Comparable<String> data){
  Node newNode = new Node(data);  //根據節點內容新建一個節點
  if(root == null){
   root = newNode;
  } else {
   root.addNode(newNode);    //調用Node的addNode方法
  }
 }
 
 /**
  * 根據後序排序打印二叉樹節點內容
  */
 public void print(){
  root.printNode();
 }
 
}


/**
 * 採用後序排序輸出二叉樹的內容
 * @author Administrator
 *
 */
public class ComparableDemo4 {
    public static void main(String[] args) {
  BinaryTree2 bt2 = new BinaryTree2();
  bt2.add("y");
  bt2.add("q");
  bt2.add("l");
  bt2.add("i");
  bt2.add("z");
  bt2.add("h");
  bt2.add("n");
  bt2.add("l");
  bt2.add("u");
  bt2.add("a");
  
  bt2.print();
 }
}

 

 

 

 

 

 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章