JAVA比较器
实现对象的排序,可以考虑两种方法:
自然排序(comparable)、定制排序(comparator)
一、方式一:实现comparable接口(自然排序)
1、定义与注意点
- Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。
- 实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小。如果当前对象this大于形参对象obj,则返回正整数,如果当前对象this小于形参对象obj,则返回负整数,如果当前对象this等于形参对象obj,则返回零。
- 对于类 C 的每一个 e1 和 e2 来说,当且仅当 e1.compareTo(e2) == 0 与e1.equals(e2) 具有相同的 boolean 值时,类 C 的自然排序才叫做与 equals一致。建议(虽然不是必需的)最好使自然排序与 equals 一致。
2、步骤
- 具体的类A实现
Comparable
类接口 - 重新
Comparable
接口中的compareTo(Object o)
方法 - 在compareTo方法中指明比较的大小。
返回值为正代表大,为负代表小。
一般来说this在前Object O在后是升序,this在后Object O在前是降序
package Day8;
/*
*项目名: OneDayLearn1
*文件名: ComparableTest
*创建者: SWY
*创建时间:2023/6/7 下午9:58
*描述: 测试Comparable的compareTo方法
*/
import org.junit.Test;
import java.util.Arrays;
import java.util.Objects;
public class ComparableTest {
@Test
public void test() {
People[] arr = new People[5];
arr[0] = new People("Time",22);
arr[1] = new People("Tom",13);
arr[2] = new People("Jerry",13);
arr[3] = new People("Lucy",19);
arr[4] = new People("Rose",44);
Arrays.sort(arr);
for(People o:arr){
System.out.println(o);
}
/*
People{name='Jerry', age=13}
People{name='Tom', age=13}
People{name='Lucy', age=19}
People{name='Time', age=22}
People{name='Rose', age=44}
*/
}
}
class People implements Comparable {
public String name;
public int age;
public People(String name, int age) {
this.name = name;
this.age = age;
}
public People() {
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Object o) {
if (o == this) {
return 0;
}
if (o instanceof People) {
People p = (People) o;
//判断年纪、升序
int value = Integer.compare(this.age, p.age);
if(0 != value){
return value;
}
//年龄相同的情况,按姓名排序
return this.name.compareTo(p.name);
}
//抛出异常
throw new RuntimeException("类型不一致");
}
}
3、排序顺序(默认都是从小到大排列的)
- String:按照字符串中字符的Unicode值进行比较
- Character:按照字符的Unicode值来进行比较
- 数值类型对应的包装类以及BigInteger、BigDecimal:按照它们对应的数值大小进行比较
- Boolean:true 对应的包装类实例大于 false 对应的包装类实例
- Date、Time等:后面的日期时间比前面的日期时间大
二、方式二:实现Comparator接口(定制排序)
1、定义与注意点
- 当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象来排序,强行对多个对象进行整体排序的比较
- 重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2
- 可以将 Comparator 传递给 sort 方法 (如 Collections.sort 或rrrays.sort),从而允许在排序顺序上实现精确控制。
- 还可以使用 Comparator 来控制某些数据结构(如有序 set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。
2、步骤
- 创建Comparator的一个实例(可以采取匿名的创建方式)。
- 实现Comoarator接口的
compare(类A o1, 类A o2)
方法。
注意此时
o1
相当于comparato(Object o)
中的this
,o2
相当于Object o
- 传入sort方法中。
Arrays.sort(arr, new Comparator<People>() {
@Override
public int compare(People o1, People o2) {
if (o1 instanceof People && o2 instanceof People) {
int value = o1.name.compareTo(o2.name);
if (value != 0) {
return value;
} else {
return Integer.compare(o1.age,o2.age);
}
}
throw new RuntimeException("类型不匹配");
}
});