说明
java.util.Comparator 类似 Comparable ,可以实现 排序 功能
应用场景
某个类 不实现
Comparable接口,又要进行比较某个类 实现了
Comparable接口,但是开发者认为其比较方式并不是自己想要,需要 临时 改用自己的排序规则。
如:List,其元素是Integer型,默认 从小到大排序,但要改成 从大到小排序
方法
Comparator接口里面有一个 compare 方法,如下:
int compare(T o1, T o2);
形参: 方法有两个参数 T o1 和 T o2,是 泛型 的表示方式,分别表示待比较的两个对象。
注意:在集合中(如:数组、List),o1 表示 后一个元素,o2 表示 前一个元素,如下图:
返回值:方法返回值是int,有三种情况:
- 正整数,不会改变 这2个元素的位置
- 负整数,交换 这2个元素的位置
- 0,表示 o1等于o2,不会改变 这2个元素的位置
返回值表示 排序规则
排序规则-正序(从小到大)
- o1(后一个元素)大于 o2(前一个元素),返回 正整数
- o1(后一个元素)小于 o2(前一个元素),返回 负整数,会交换这2个元素的位置
排序规则-倒序(从大到小)
- o2(前一个元素)大于 o1(后一个元素),返回 正整数
- o2(前一个元素)小于 o1(后一个元素),返回 负整数,会交换这2个元素的位置
例子-int 数组
从小到大排序,即:正序
这里只是为了演示,其实对于 int 型数组,不需要实现 Comparator,因为数字型本身就可以排序
package test;
import java.util.*;
public class Std_Comparator_array {
public static void main(String[] args) {
Integer[] array=new Integer[]{1,3,2};
Arrays.sort(array,new MyComparator());
System.out.println(Arrays.toString(array));
}
static class MyComparator implements Comparator<Integer> {
/**
*
* @param o1 后一个元素
* @param o2 前一个元素
* @return
*/
@Override
public int compare(Integer o1, Integer o2) {
int ret=0;
if(o2 > o1){
ret=-1;
}else if(o2 < o1){
ret=1;
}else{//等于
ret=0;
}
return ret;
}
}
}
返回元素相减,简化操作
从小到大排序,即:正序,返回 后一个元素(第一个形参) - 前一个元素(第二个形参)
package test;
import java.util.*;
public class Std_Comparator_array {
public static void main(String[] args) {
Integer[] array=new Integer[]{1,3,2};
Arrays.sort(array,new MyComparator());
System.out.println(Arrays.toString(array));
}
static class MyComparator implements Comparator<Integer> {
/**
*
* @param o1 后一个元素
* @param o2 前一个元素
* @return
*/
@Override
public int compare(Integer o1, Integer o2) {
int ret = o1 - o2;
return ret;
}
}
}
例子-int List
对于 int 型List,已经实现了 从小到大排序,但我们要改成 从大到小排序,即:倒序
package test;
import org.apache.flink.api.java.tuple.Tuple2;
import java.util.*;
public class Std_Comparator_list_daoxu {
public static void main(String[] args) {
List<Integer> list=new ArrayList();
list.add(1);
list.add(3);
list.add(2);
list.sort(new MyComparator()); // list本身排序
// Collections.sort(list,new MyComparator()); //Collections.sort()排序
System.out.println(Arrays.toString(list.toArray()));
}
static class MyComparator implements Comparator<Integer> {
/**
*
* @param o1 后一个元素
* @param o2 前一个元素
* @return o1大于o2,返回正整数;o1小于o2,返回负整数;返回0,表示等于
*/
@Override
public int compare(Integer o1, Integer o2) {
int ret=0;
if(o2 < o1){
ret=-1;
}else if(o2 > o1){
ret=1;
}else{//等于
ret=0;
}
return ret;
}
}
}
例子:对象类型
假设某类没有实现 Comparable 接口,但是又想进行比较
或者 实现了 Comparable 接口,但是开发者认为其比较方式并不是自己想要,需要 临时 改用自己的排序规则
根据年龄比较
有 Student 类,没有实现 Comparable 接口,但又想根据 年龄 进行比较
Student类:
package test;
public class Student {
private String name;
private int age;
private int length;
public Student(String name, int age,int length) {
this.name = name;
this.age = age;
this.length = length;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return name+","+age+","+length;
}
}
主类
package test;
import java.util.*;
public class Std_Comparator_list_Student {
public static void main(String[] args) {
Student std=new Student("李雷",20,182);
Student std2=new Student("lucy",16,168);
Student std3=new Student("lucy",16,167);
Student std4=new Student("韩梅梅",25,165);
Student std5=new Student("张三",16,185);
List<Student> list=new ArrayList();
list.add(std);
list.add(std2);
list.add(std3);
list.add(std4);
list.add(std5);
// list.sort(new MyComparator()); // list本身排序
Collections.sort(list,new MyComparator()); //Collections.sort()排序
System.out.println(Arrays.toString(list.toArray()));
}
static class MyComparator implements Comparator<Student> {
/**
*
* @param o1 后一个元素
* @param o2 前一个元素
* @return
*/
@Override
public int compare(Student o1,Student o2) {
int res=0;
if( o1.getAge() < o2.getAge()){
res=-1;
}else if(o1.getAge() > o2.getAge()){
res=1;
}else{//相等
res=0;
}
return res;
}
}
}
二次排序
对于上面的例子,当 年龄 相同时,身高从大到小排序
修改测试类,进行二次排序
package test;
import java.util.*;
public class Std_Comparator_list_Student2 {
public static void main(String[] args) {
Student std=new Student("李雷",20,182);
Student std2=new Student("lucy",16,168);
Student std3=new Student("lucy",16,167);
Student std4=new Student("韩梅梅",25,165);
Student std5=new Student("张三",16,185);
List<Student> list=new ArrayList();
list.add(std);
list.add(std2);
list.add(std3);
list.add(std4);
list.add(std5);
// list.sort(new MyComparator()); // list本身排序
Collections.sort(list,new MyComparator()); //Collections.sort()排序
System.out.println(Arrays.toString(list.toArray()));
}
static class MyComparator implements Comparator<Student> {
/**
*
* @param o1 后一个元素
* @param o2 前一个元素
* @return
*/
@Override
public int compare(Student o1,Student o2) {
int res=0;
if( o1.getAge() < o2.getAge()){
res=-1;
}else if(o1.getAge() > o2.getAge()){
res=1;
}else{//相等
// res=0;
//二次排序
if(o1.getLength()>o2.getLength()){
res=-1;
}else if(o1.getLength() < o2.getLength()){
res=1;
}else{
res=0;
}
}
return res;
}
}
}

