在Array 类中定义了以下的一个方法,可以直接为一个对象数组进行排序
public static void sort(Object[] a)
在sort()方法中强调,如果要想实现对象数组的排序,则所有的元素都必须实现Comparable接口
Comparable 接口
Comparable 接口实际上属于比较器的操作接口,此接口定义如下:
public interface Comparable<T> //接口上使用了泛型
int compareTo(T o){ //定义compareTo()方法,此方法完成排序的
//比较代码
}
}
关于compareTo()方法的返回值有三种类型:
小于:-1
等于:0
大于:1
package org.comparedemo;
import java.util.Arrays;
import org.thisdemo.thisdemo01;
class Student implements Comparable<Student>{ //实现比较器,并指定泛型
private String name;
private int stno;
private int age;
private double score;
public Student(String name,int stno,int age,double score){
this.name = name;
this.stno = stno;
this.age = age;
this.score = score;
}
public String toString(){ //覆写toString 方法
return "姓名:"+this.getName()+
"编号:"+this.getStno()+
"年龄:"+this.getAge()+
"分数:"+this.getScore();
}
public void setName(String name){
this.name = name;
}
public void setStno(int stno){
this.stno = stno;
}
public void setAge(int age){
this.age = age;
}
public void setScore(float score){
this.score = score;
}
public String getName(){
return this.name;
}
public int getStno(){
return this.stno;
}
public int getAge(){
return this.age;
}
public double getScore(){
return this.score;
}
public int compareTo(Student stu) {
// TODO Auto-generated method stub
if (this.getScore()<(stu.getScore())){
return -1;
}else if (this.getScore()>(stu.getScore())){
return 1;
}else{
if (this.getAge()<(stu.getAge())){
return -1;
}else if (this.getAge()>(stu.getAge())){
return 1;
}else {
return 0;
}
}
}
}
public class CompareDemo01 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Student stu[] = {new Student("吴二",1,20,90.1),
new Student("张三",2,20,90.1),
new Student("李四",3,19,75.1),
new Student("王五",4,18,90.1),
new Student("赵六",5,20,80.1)};
Arrays.sort(stu);
for (int i=0;i<stu.length;i++){
System.out.println(stu[i]);
}
}
}
Comparable 排序原理
在Comparable 发现compareTo()方法中可以返回三种类型:-1、0、1 ,实际上此种排序就类似于常见到的BT(Binary Tree)排序
现在假设有如下几个数字:7 4 6 1 11 0 9 5 3 ,那么如果使用二叉树排序,则首先应该将第一个元素做为根节点,之后每个元素,如果比第一个元素小,则放在左子树,如果比第一个元素大则放在右子树,依次类推
二叉树完成之后要使用中序遍历的方式完成:左-根-右
排序之后的数据:0134567911
那么此时,实际上就可以通过此种代码并结全Comparable 接口来实现一个二叉权的算法
需要注意,String 类型或 Integer 类型的数据都可以使用Comparable 进行接收
package org.comparedemo;
public class ComparableDemo03 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Comparable<String> date = "hello";
System.out.println(date);
}
}
package org.comparedemo;
class BinaryTree {
class Node{
private Comparable data; // 保存操作的数据内容
private Node left;
private Node right;
public Node(Comparable<?> date){
this.data = date;
}
public void addNode(Node newNode){
if (newNode.data.compareTo(this.data)<=0){ //放在左子树
if (this.left == null){ //还没有左子树,可以直接保存在此节点下的左子树
this.left = newNode; //保存左子树
}else{
this.left.addNode(newNode);//向下继续判断
}
}
if (newNode.data.compareTo(this.data)>0){ //放在右子树
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);// 找到根内容
if (this.right != null){ //存在右子树
this.right.printNode(); //继续找到下面的右子树
}
}
}
private Node root; // 根节点
public void add(Comparable date){ //接收数据
Node newNode = new Node(date);
if (this.root == null){ //没有根节点
this.root = newNode; //第一个节点作为根节点
}else{
this.root.addNode(newNode);
}
}
public void print(){ //输出
this.root.printNode();//输出全部的节点
}
}
public class ComparableDemo02 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
BinaryTree bt = new BinaryTree();
bt.add(3);
bt.add(5);
bt.add(1);
bt.add(0);
bt.add(1);
bt.add(9);
bt.print();
}
}
另一种比较器:Comparator
Comparable 接口在使用的时候直接在类中实现即可,那么如果现在一个类已经开发完成了,则肯定不能再去修改,所以,此时为了让此类也具备排序的功能,可以使用Comparator 接口中完成排序的操作
在Arrays类中提供了以下的ic 排序方法:
public stat<T> void sort(T[] a,Comparator<? super T>c)
Student 类:
package org.comparedemo;
class Student { //实现比较器,并指定泛型
private String name;
private int stno;
private int age;
private double score;
public Student(String name,int stno,int age,double score){
this.name = name;
this.stno = stno;
this.age = age;
this.score = score;
}
public boolean equals(Object obj){ //覆写equals 完成对象的比较
if (this == obj){
return true;
}
if (!(obj instanceof Student)){
return false;
}
Student stu = (Student) obj; //向下转型
if (this.stno == stu.stno && this.name.equals(stu.name)
&& this.age == stu.age && this.score == stu.score){
return true; //对象相等
}else{
return false; //对象不等
}
}
public String toString(){ //覆写toString 方法
return "姓名:"+this.getName()+
"编号:"+this.getStno()+
"年龄:"+this.getAge()+
"分数:"+this.getScore();
}
public void setName(String name){
this.name = name;
}
public void setStno(int stno){
this.stno = stno;
}
public void setAge(int age){
this.age = age;
}
public void setScore(float score){
this.score = score;
}
public String getName(){
return this.name;
}
public int getStno(){
return this.stno;
}
public int getAge(){
return this.age;
}
public double getScore(){
return this.score;
}
}
StudentComparator 类:
package org.comparedemo;
import java.util.Comparator;
public class StudentComparator implements Comparator<Student> {
@Override
public int compare(Student stu1, Student stu2) {
// TODO Auto-generated method stub
if (stu1.getScore()<(stu2.getScore())){
return -1;
}else if (stu1.getScore()>(stu2.getScore())){
return 1;
}else{
if (stu1.getAge()<(stu2.getAge())){
return -1;
}else if (stu1.getAge()>(stu2.getAge())){
return 1;
}else {
return 0;
}
}
}
public boolean equals (Object obj){
return this.equals(obj);
}
}
主方法:
package org.comparedemo;
import java.util.Arrays;
public class ComparatorDemo {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Student stu[] = {new Student("吴二",1,20,90.1),
new Student("张三",2,20,90.1),
new Student("李四",3,19,75.1),
new Student("王五",4,18,90.1),
new Student("赵六",5,20,80.1)};
Arrays.sort(stu,new StudentComparator());
for (int i=0;i<stu.length;i++){
System.out.println(stu[i]);
}
}
}