光阴似箭,我好像跟不上
—— 24.5.6
一、java.lang.Comparable
我们知道基本数据类型的数据(除boolean类型外)需要比较大小的话,直接使用比较运算符即可,但是引用数据类型是不能直接使用比较运算符来比较大小的。那么,如何解决这个问题呢?
java给所有引用数据类型的大小比较,指定了一个标准接口,就是java.lang.Comparable接口:package java.lang; public interface Comparable{ int compareTo(Object obj); }
那么我们想要使得我们某个类的对象可以比较大小,怎么做呢?
步骤:
第一步:哪个类的对象要比较大小,哪个类就实现java.lang.Comparable接口,并重写方法。方法体就是你要如何比较当前对象和指定的另一个对象的大小
第二步:对象比较大小时,通过对象调用compareTo方法,根据方法的返回值决定谁大谁小。
this对象(调用compareTo方法的对象)减指定对象(传入compareTo()的参数对象)大于0,返回正整数。this对象(调用compareTo方法的对象)减指定对象(传入compareTo()的参数对象)小于0返回负整数
this对象(调用compareTo方法的对象)减指定对象(传入compareTo()的参数对象)等于0返回零
CompareTo函数:
public class Student implements Comparable { private String name; private int Score; public Student(String name, int score) { this.name = name; Score = score; } public Student() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getScore() { return Score; } public void setScore(int score) { Score = score; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", Score=" + Score + '}'; } // this代表students[i] // o代表students[i+1] // 如果students[i].getscore()-students[i+1].getstore()>0 // 证明数组中的钱一个对象比后一个对象分数高 @Override public int compareTo(Object o) { // 向下转型 Student s = (Student) o; return this.getScore()-s.getScore(); } }
Test:
public static void main(String[] args) { // 创建一个数组 Student[] students = new Student[3]; Student s1 = new Student("张三",100); Student s2 = new Student("李四",60); Student s3 = new Student("王五",90); students[0]=s1; students[1]=s2; students[2]=s3; for (int j = 0; j < students.length-1; j++) { for (int i = 0; i < students.length-1-j; i++) { // 如果students[i]>students[i+1],就换位置 if (students[i].compareTo(students[i+1])>0){ Student tmp = students[i]; students[i] = students[i+1]; students[i+1] = tmp; } } } // 遍历一下 for (int i = 0; i < students.length; i++) { System.out.println(students[i]); } }
二、java.util.Comparator
思考:
(1)如果一个类,没有实现Comparabe接口,而这个类你又不方便修改(例如:一些第三方的类,你只有.class文件,没有源文件),那么这样类的对象也要比较大小怎么办?
(2)如果一个类,实现了Comparable接口,也指定了两个对象的比较大小的规则,但是此时此刻我不想按照它预定义的方法比较大小,但是我又不能随意修改,因为会影响其他地方的使用,怎么办?JDK在设计类库之初,也考虑到这种情况了,所以又增加了一个java.util.Comparator接口。
package java.util; public interface Comparator{ int compare(Object o1,Object o2); }
步骤:
第一步:编写一个类,我们称之为比较器类型,实现java.ulil.Comparator接口,并重写方法。
方法体就是你要如何指定的两个对象的大小
第二步:比较大小时,通过比较器类型的对象调用compare()方法,将要比较大小的两个对象作为compare方法的实参传入,根据方法的返回值决定谁大谁小。
o1对象减o2大于0返回正整数
o1对象减o2小于0返回负整数
o1对象减o2等于0返回零Comparator函数
import java.util.Comparator; public class Student2 implements Comparator { private String name; private int Score; public Student2(String name, int score) { this.name = name; Score = score; } public Student2() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getScore() { return Score; } public void setScore(int score) { Score = score; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", Score=" + Score + '}'; } // o1代表students[i] // o2代表students[i+1] // 如果o1的分数>o2的分数,compare方法返回正整数 // 如果o1的分数<o2的分数,compare方法返回负整数 // 如果o1的分数=o2的分数,compare方法返回0 @Override public int compare(Object o1, Object o2) { Student2 s1 = (Student2) o1; Student2 s2 = (Student2) o2; return s1.getScore()-s2.getScore(); } }
Test函数
public class Demo160ClassicObject2 { public static void main(String[] args) { // 创建一个数组 Student2[] students = new Student2[3]; Student2 s1 = new Student2("张三",100); Student2 s2 = new Student2("李四",60); Student2 s3 = new Student2("王五",90); students[0]=s1; students[1]=s2; students[2]=s3; Student2 student = new Student2(); for (int j = 0; j < students.length-1; j++) { for (int i = 0; i < students.length-1-j; i++) { // 如果students[i]>students[i+1],就换位置 if (student.compare(students[i],students[i+1])>0){ Student2 tmp = students[i]; students[i] = students[i+1]; students[i+1] = tmp; } } } // 遍历一下 for (int i = 0; i < students.length; i++) { System.out.println(students[i]); } } }