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

 

 

 

 

 

 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值