文章目录
前言
- 包装类Collections的排序方法可以运用到各种集合框架,非常方便
- 分析看不懂请结合程序示例看
- 有问题欢迎评论或者私信!!!
接口分析
Comparable接口
-
Comparable接口在 java.lang.Comparable 包下
-
Comparable接口的实现方法:public int compareTo(T t);
-
Comparable接口是在集合的(类的)内部实现的排序方式,调用的实质 t1.compareTo(t2);
-
在排序对象本身支持相互比较所需要的接口(如Integer、String、Double、Float等)时,可以直接调用 Collections.sort() 方法的Comparable接口(参考程序示例)
-
当数值或ASCII码值从小到大的默认顺序或者排序的根据对象不满足程序需求时,可以重写compareTo方法(参考程序示例)
Comparator接口
-
Comparator接口在 java.util.Comparator 包下
-
Comparator接口的实现方法:public int compare(T t1, T t2);
-
Comparator接口是在集合的(类的)外部实现的排序方式,需要用到一个比较容器,调用的实质是 compare(t1 , t2);(参考程序示例)
-
在排序对象本身不支持相互比较所需要的接口,例如对整数采用绝对值大小排序,显然对象本身的Integer自然排序是不能实现的,同时如果Integer类也不容许你在它的内部重写compareTo()去改变它的排序行为,所以就可以用到Comparator接口(参考程序示例)
compareTo和compare方法
-
Comparable接口的实现方法:public int compareTo(T t),调用的实质 t1.compareTo(t2);
在方法内部返回一个运算结果,例如返回:t1.x - t2.x,则按从小到大的顺序排序
若返回:t2.x - t1.x,则按从大到小的顺序排序
-
Comparator接口的实现方法:public int compare(T t1, T t2),调用的实质是 compare(t1 , t2);
在方法内部返回一个运算结果,例如返回:t1.x - t2.x,则按从小到大的顺序排序
若返回:t2.x - t1.x,则按从大到小的顺序排序
-
compareTo默认的调用可以实现字符串的比较,比较方法:先比较第一个字符,不同则返回ASCII码的差值,若第一个字符相同,则比较第二个字符,若前面字符相同则比较长度。
例如:
String a = 'abc'; String b = 'cde'; String c = 'abcde'; int d = a.compareTo(b); int e = a.compareTo(c);
返回d = -2,由a的ASCII码值减去b的ASCII码值得来。e = -2,因为前字符相同,a.length() - c.length() = -2.
相关之处
-
对于一个对象的排序,既可以用Comparable接口实现,也能用Comparator接口实现,只是两种排序的实现方式不同,
-
在某些情况的排序下,可以用Comparator接口,在接口的compare方法中再次调用compareTo方法进行比较。例如如下情况:
输入学生的学号、姓名、班级、成绩,分别根据这四个数据进行排序。
对学号的排序,可以调用Comparable接口重写comparaTo方法按学号从小到大排序
对姓名的排序,可以实现一个比较容器,在容器中重写compare方法,在compare方法中调用compareTo方法实现对字符串的比较,然后返回对字符串的比较结果。
class NameUPComparator implements java.util.Comparator {
public int compare(Object o1, Object o2) {
Student s1 = (Student)o1;// 转化成当前类型的对象
Student s2 = (Student)o2;
return s1.getName().compareTo(s2.getName());
}
}
在调用sort方法时,则要通过:
Collections.sort(studentList,new NameUPComparator());
程序示例
调用默认的Comparable接口
import java.util.ArrayList;
import java.util.Collections;
public class CompObj {
public String toString() {
return "[x = " + x + "]";
}
public static void main(String[] args) {
ArrayList<Integer> al = new ArrayList<Integer>();// 单一Integer数据的ArrayList,有本身支持比较的接口Integer
al.add(3);
al.add(1);
al.add(2);
System.out.println("Before sort!");
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
Collections.sort(al); // 调用Collections的sort方法-静态方法
System.out.println("After sort!");
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
}
}
调用重写compareTo方法的Comparable接口
根据x值排序
import java.util.ArrayList;
import java.util.Collections;
public class CompObj implements java.lang.Comparable { // 定义要排序的类
int x;
int y;
public CompObj(int n1, int n2) {
x = n1;
y = n2;
}
public String toString() {
return "[x = " + x + ", y = " + y + "]";
}
public int compareTo(Object o) {
CompObj co = (CompObj) o;
if (this.x != co.x) {
return this.x - co.x;
} else {
return this.y - co.y;
}
}
public static void main(String[] args) {
ArrayList<CompObj> al = new ArrayList<CompObj>();
al.add(new CompObj(3, 1));
al.add(new CompObj(1, 3));
al.add(new CompObj(2, 2));
al.add(new CompObj(2, 1));
System.out.println("Before sort!");
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
Collections.sort(al); // 调用Collections的sort方法-静态方法
System.out.println("After sort!");
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
}
}
注意事项
-
compareTo()方法的形参为Object类的对象,在比较之前要进行类型转换成为CompObj类的对象
-
在重写的compareTo方法中,若俩对象的x值相同,则比较y值
-
若改为
if (this.x != co.x) { return co.x - this.x; } else { return co.y - this.y; }
则按照从大到小的顺序排序
调用重写compareTo方法的Comparator接口
根据y值排序
import java.util.ArrayList;
import java.util.Collections;
class ObjComparator implements java.util.Comparator {
public int compare(Object o1, Object o2) {
CompObj co1 = (CompObj) o1; // 转化成当前类型的对象
CompObj co2 = (CompObj) o2;
if (co1.y != co2.y) {
return co1.y - co2.y;// 先根据y值排序
} else {
return co1.x - co2.x;
}
}
}
public class CompObj { // 无需实现Comparable接口
int x;
int y;
public CompObj(int n1, int n2) {
x = n1;
y = n2;
}
public String toString() {
return "[x = " + x + ", y = " + y + "]";
}
public static void main(String[] args) {
ArrayList al = new ArrayList();
al.add(new CompObj(3, 2));
al.add(new CompObj(1, 3));
al.add(new CompObj(1, 2));
System.out.println("Before sort!");
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
Collections.sort(al, new ObjComparator());
System.out.println("After sort!");
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
}
}
调用重写compareTo方法的Comparator接口实现绝对值排序
根据x的绝对值排序
import java.util.ArrayList;
import java.util.Collections;
class AbsComparator implements java.util.Comparator {
public int compare(Object o1, Object o2) {
CompObj co1 = (CompObj) o1;// 转化成当前类型的对象
CompObj co2 = (CompObj) o2;
int v1 = Math.abs(co1.x);// 把对象co1的x成员转化成绝对值
int v2 = Math.abs(co2.x);
return v1 - v2;
}
}
public class CompObj { // 无需实现Comparable接口
int x;
int y;
public CompObj(int n1, int n2) {
x = n1;
y = n2;
}
public String toString() {
return "[x = " + x + ", y = " + y + "]";
}
public static void main(String[] args) {
ArrayList al = new ArrayList();
al.add(new CompObj(3, 2));
al.add(new CompObj(-2, 3));
al.add(new CompObj(1, 2));
System.out.println("Before sort!");
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
Collections.sort(al, new AbsComparator());
System.out.println("After sort!");
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
}
}
反思总结
- 起床整到现在,饿的一批
- 觉得有帮助到你就点个赞吧🙏🙏🙏
- 下期出数据结构的约瑟夫问题