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();
}
}