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