Java 基础 --- Comparable 和 Comparator

Comparable 接口

  • comparable接口只有一个方法 — compareTo(T o)
    在这里插入图片描述
  • 一个类实现 Comparable 接口并重写 compareTo 方法就可以支持 Collections.sortArrays.sort 的排序
  • 返回值 — 从小到大排序:
  • 如果当前对象this大于形参对象obj,则返回正整数;
  • 如果当前对象this小于形参对象obj,则返回负整数;
  • 如果当前对象this等于参数对象obj,则返回零。
  • this - input (从小到大排序) , input - this (从大到小排序)
  • example:
  • 从大到小 p.getAge() - this.getAge()
  • 从小到大 this.getAge() - p.getAge()
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

class Person implements Comparable<Person> {
    
    
    private int id;
    private int age;
    private String name;
    public Person(int id, int age, String name) {
    
    
        this.id = id;
        this.age = age;
        this.name = name;
    }
    //重写compareTo, 使用 `Collections.sort` 和 `Arrays.sort` 的时候就可以根据年龄从大到小排序
    //如果从小到大排序, 则 this.getAge() - p.getAge();
    @Override
    public int compareTo(Person p) {
    
    
        return p.getAge() - this.getAge();
    }
}
public class ComparableExample {
    
    
    public static void main(String[] args) {
    
    
        Person p1 = new Person(1, 18, "Java");
        Person p2 = new Person(2, 22, "MySQL");
        Person p3 = new Person(3, 6, "Redis");
        List<Person> list = new ArrayList<>();
        list.add(p1);
        list.add(p2);
        list.add(p3);
        // 进行排序操作(根据 Person 类中 compareTo 中定义的排序规则)
        Collections.sort(list);
    }
}

Another example:

//指明商品比较大小的方法,按照价格从低到高,如果价格相同,按照产品名称从低到高
@Override
    public int compareTo(Object o) {
    
    
        if(o instanceof Goods){
    
    
            Goods goods=(Goods) o;
            if(this.price>goods.price){
    
    
                return 1;
            }else if(this.price<goods.price){
    
    
                return -1;
            }else{
    
    //价格相同,按照产品名称从低到高比较
                return this.name.compareTo(goods.name);
     }

Comparator 接口

  • comparatro接口包含很多方法, 其中排序的方法是 compare(T o1, T o2)
  • 默认为从小到大排序,用参数o1减参数o2。若需要从大到小排序,则用参数o2减参数o1
  • 重写Comparator接口有三种方法
  • 使用内部静态类
  • 使用内部匿名类
  • 使用lambda表达式
使用内部静态类

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class ComparatorExample {
    
    
	/**
	  * 用于 Person 类的比较器
	  */
	static class PersonComparator implements Comparator<Person> {
    
    
	    @Override
	    public int compare(Person p1, Person p2) {
    
    
	        return p2.getAge() - p1.getAge();
	    }
	}
	
    public static void main(String[] args) {
    
    
        // 创建对象
        Person p1 = new Person(1, 18, "Java");
        Person p2 = new Person(2, 22, "MySQL");
        Person p3 = new Person(3, 6, "Redis");
        // 添加对象到集合
        List<Person> list = new ArrayList<>();
        list.add(p1);
        list.add(p2);
        list.add(p3);
        // 进行排序操作(根据 PersonComparator 中定义的排序规则)
        Collections.sort(list, new PersonComparator());
    }
}

重写Comparator — Arrays.sort()

  • 重写comparator使Arrays.sort可以对二维数组从小到大排序
//内部匿名类
Arrays.sort(nums, new Comparator<int[]>() {
    
    
		public int compare(int[] a, int[] b){
    
    
			if(a[0]==b[0]){
    
    
				return a[1] - b[1];
			}else {
    
    
				return a[0] - b[0];
			}
		}
});
//lambda表达式
 Arrays.sort(intervals,(int [] o1, int [] o2)->{
    
    
            return  o1[0]-o2[0];
        });

重写Comparator — PriorityQueue()

class Node {
    
    
        public int num;
        public int freq;
        
        public Node(int num, int freq) {
    
    
            this.num = num;
            this.freq = freq;
        }
    }
    
 public int[] topKFrequent(int[] nums, int k) {
    
    
        //重写heap的comparator, heap将根据freq从大到小排序
        //内部匿名类
        PriorityQueue<Node> heap = new PriorityQueue<>(new Comparator<Node>() {
    
    
            @Override
            public int compare(Node o1, Node o2) {
    
    
                return o2.freq - o1.freq;
            }
        });
        
		//lambda表达式
		PriorityQueue<Integer> priorityQueue2 = new PriorityQueue<>((Integer o1, Integer o2) -> {
    
    
	            return o2 - o1;
	     });
 }

Comparable 和 Comparator的区别

  • 使用 Comparable 必须要修改原有的类,也就是你要排序那个类,就要在那个中实现 Comparable 接口并重写 compareTo 方法
  • 而 Comparator 的使用则不相同,Comparator 无需修改原有类。也就是在最极端情况下,即使 Person 类是第三方提供的,我们依然可以通过创建新的自定义比较器 Comparator,来实现对第三方类 Person 的排序功能。也就是说通过 Comparator 接口可以实现和原有类的解耦,在不修改原有类的情况下实现排序功能,

猜你喜欢

转载自blog.csdn.net/weixin_38803409/article/details/126032606