Comparable接口
可以直接使用java,util.Arrays类进行数组的排序操作,但是对象对所有的类必须实现Comparable接口。用于指定排序接口。
Comparable接口定义如下:
Public intterface Comparable<T>{
Public int compareTo(T o);
}
此时,返回一个int类型的数据,但是int的数值只有以下三种:
1 : 表示大于
-1 : 表示小于
0 : 表示等于
要求;
定义一个学生类,里面有姓名、年龄、成绩三个属性,要求按成绩由高到地排序,如果成绩相等,就按照年龄有低到高排序。
/*================================================================
* 比较器的使用
*
*===============================================================*/
package Demo006;
class Student implements Comparable<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 name+"\t\t"+this.age+"\t\t"+this.score;
}
@Override
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 class Demo002Compable {
public static void main(String[] args){
Student stu[]={
new Student("张三", 21, 100.0f),
new Student("李四",20,90.0f),
new Student("王五",22,60.0f),
new Student("赵六",22,90.0f),
new Student("孙七",25,80.0f)
};
java.util.Arrays.sort(stu);
for(int i=0;i<stu.length;i++){
System.out.println(stu[i]);
}
}
}
/*================================================================
* 比较器的使用
*
*===============================================================*/
class Student implements Comparable<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 name+"\t\t"+this.age+"\t\t"+this.score;
}
@Override
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 class Demo002Compable {
public static void main(String[] args){
Student stu[]={
new Student("张三", 21, 100.0f),
new Student("李四",20,90.0f),
new Student("王五",22,60.0f),
new Student("赵六",22,90.0f),
new Student("孙七",25,80.0f)
};
java.util.Arrays.sort(stu);
for(int i=0;i<stu.length;i++){
System.out.println(stu[i]);
}
}
}
这样的排序我们在DTO 经常用到;
比较器的排序原理:
实际上比较器的操作,就是二叉树的排序算法。
排序的基本原理,使用第一个元素做为根节点, 之后如果后面的内容比根节点要小的就放到左子树,如果内比更节点大,就放在右子树中。
例如;8 3 10 9 1 5
8
3 10
1 5 9
然后,中序遍历拿到左子树的1 3 5 8 9 10
/*===============================
* 二叉树的排序
*
*==============================*/
class BirnaryTree{
private Node root;//树根节点
//树节点
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){
//newNode节点比本节点小 ,再和左子树比较,如果为空就放在左子树
if(this.left==null){
this.left=newNode;
}else{
this.left.addNode(newNode);//递归判断
}
}else if(newNode.data.compareTo(this.data)>0){
//newNode 比本节点大或等于 就放在 右子节点上
if(this.right==null){
this.right=newNode;
}else{
this.right.addNode(newNode);
}
}
}
//中序遍历
public void printNode(){
if(this.left!=null){
this.left.printNode();//输出左子树
}
System.out.println("输出子树: "+this.data + "\t");
if(this.right!=null){
this.right.printNode();
}
}
};
//对树操作,添加数据
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 class Demo003 {
public static void main(String[] args){
BirnaryTree bt=new BirnaryTree();
bt.add(8);
bt.add(3);
bt.add(10);
bt.add(9);
bt.add(1);
bt.add(2);
bt.add(23);
bt.add(6);
bt.print();
}
}
输出子树: 1
输出子树: 2
输出子树: 3
输出子树: 6
输出子树: 8
输出子树: 9
输出子树: 10
输出子树: 23
另一种比较器: Comparator
如果一个类已经开发完成,但我们在此类建立的初期,并没有实现Comparable 接口,此时肯定无法进行对象的排序操作的,所以为了解决这样的问题,java又定义了另一个比较器的操作接口--------------Comparator.
java.util
Interface Comparator<T>
|
/*==================================================
* 下面定义一个自己的类,此类没有实现Comparator接口
* 要复写Object 的toString() equals() hashCode()
*
*==================================================*/
import java.util.Comparator;
class Student1{
private String name;
private int age;
public Student1(String name,int age){
this.name=name;
this.age=age;
}
public boolean equals(Object obj){
boolean result=false;
if(this==obj){
result=true;
}
if(!(obj instanceof Student1)){
result=false;
}
Student1 stu = (Student1)obj;
if(stu.name.equals(this.name)&&stu.age==this.age){
result=true;
}
return result;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "Student1 [name=" + name + ", age=" + age + "]";
}
};
//实现比较器,第三方比较器
class StudentComparator implements Comparator<Student1>{
//Object 本身已经有equals()方法
@Override
public int compare(Student1 o1, Student1 o2) {
if(o1.equals(o2)){
return 0;
}else if(o1.getAge()< o2.getAge()){
return 1;
}else{
return -1;
}
}
};
public class Demo004 {
public static void main(String[] args){
Student1 stu[]={
new Student1("张三", 21),
new Student1("李四",20),
new Student1("王五",22),
new Student1("赵六",27),
new Student1("孙七",25)
};
java.util.Arrays.sort(stu , new StudentComparator());
for(int i=0;i<stu.length;i++){
System.out.println(stu[i]);
}
}
}
Student1 [name=赵六, age=27]
Student1 [name=孙七, age=25]
Student1 [name=王五, age=22]
Student1 [name=张三, age=21]
Student1 [name=李四, age=20]
采用第三方实现比较器;在开发中尽可能使用comparable 接口实现对象排序;