Comparable 接口和 Comparator 接口的区别及 sort()方法的使用

一、概述

Java 提供的 Comparable 和 Comparator 接口都是为我们解决比较两个对象的问题,都能实现数组和集合的排序。

两者也有所区别:

  • Comparable 接口位于包 java.lang 下;Comparator 接口位于包 java.util 下。
  • Comparable 接口——Java类库中的 Byte、Short、String 以及 BigDecimal 等都实现了 Comparable 接口,可以直接调用,用于比较两个对象大小,十分方便,称为自然排序;Comparator 接口——主要用集合的排序,根据不同需求的排序方式直接接口实现,易于功能扩展,不影响原代码,称为比较器排序
  • 实现 Comparable 接口需要重写 compareTo()方法,而实现 Comparator 接口需要重写 compare()方法,两个方法返回值都是 int 类型,根据返回值来判断比较对象的大小,从而实现排序。

二、Comparable接口——自然排序

1、默认的 compareTo()方法

Comparable 接口中的 compareTo()方法判断这个对象相对于比较对象的顺序,小于返回负整数,等于返回 0,大于返回正整数。

(1) 单个字符的比较——返回参与比较的前后两个字符的 asc 码的差值。

String a1 = "a";
String a2 = "c";        
System.out.println(a1.compareTo(a2));//结果为-2

(2)字符串的比较——参与比较的两个字符串如果首字符相同,则比较下一个字符,直到有不同的为止,返回该不同的字符的asc码差值;

String a1 = "aa";
String a2 = "ad";        
System.out.println(a1.compareTo(a2));//结果为-3

(3)字符串的比较——如果两个字符串长度不同,可以参与比较的字符又完全一样,则返回两个字符串的长度差值;

String a1 = "aa";
String a2 = "aa12345678";        
System.out.println(a1.compareTo(a2));//结果为-8

(4)返回为正数表示 a1>a2,返回为负数表示 a1<a2,,返回为 0 表示 a1==a2;

(5)数字类型不能用 compareTo,int 跟 int 的比较不能用compareTo方法。直接用大于(>) 、小于(<) 、等于(==) 或者不等于(!=)来比较即可。(也可以先把 int 转换成 String 再进行比较)

int num1 = 4;
int num2 = 5;        
num1.compareTo(num2);//Cannot invoke compareTo(int) on the primitive type int 

2、实现Comparable接口,重写compareTo()

public class Rectangle implements Comparable{
	int length;
	int width;
	
	public Rectangle(int length, int width) {
		this.length = length;
		this.width = width;
	}
	
	public int getArea(){
		return length * width;
	}

	@Override
	public int compareTo(Rectangle o) {// 重写比较方法
		if(getArea() > o.getArea()){// 面积比较
			return 1;
		}else if(getArea() < o.getArea()){
			return -1;
		}else{
			return 0;
		}
	}
	
	public static void main(String[] args) {
		Rectangle rect = new Rectangle(2, 2);
		System.out.println(rect.compareTo(new Rectangle(3, 3)));
		System.out.println(rect.compareTo(new Rectangle(1, 3)));
		System.out.println(rect.compareTo(new Rectangle(2, 2)));
	}
}

测试结果:

-1
1
0

3、sort()方法——Arrays.sort()、Collections.sort()

由于 Comparable 对象都有 compareTo 方法,sort 方法就可以使用 compareTo 方法的结果来对数组或者 list 的对象进行比较和排序。测试代码如下:

// 数组,int型
int[] num = {2, 5, 1, 4};
Arrays.sort(num);
for (int i = 0; i < num.length; i++) {
	System.out.print(num[i] + " ");
}
System.out.println();
		
// 数组,String
String[] animal = {"cat", "dog", "chicken", "pig"};
Arrays.sort(animal);//数组排序的类
for (String s : animal) {
	System.out.print(s + " ");
}
System.out.println();
        
// 集合,String
ArrayList strings = new ArrayList<>();
strings.add("chicken");
strings.add("cat");
strings.add("dog");
strings.add("pig");
Collections.sort(strings);//list排序的类
for (String s : strings) {
        System.out.print(s + " ");
}

测试结果:

1 2 4 5 
cat chicken dog pig 
cat chicken dog pig 

三、Comparator 接口——比较器排序

Comparator 接口的使用:在外部定义比较器实现 Comparator 接口,重写 compare(T o1,T o2) 方法,该方法返回一个 int 型的结果。若方法中定义(o1 - o2),则返回负数表示 o1 小于 o2,返回 0 表示 o1 和等于o2,返回正数表示 o1 大于 o2。

重写好 compare 方法之后,可调用Collections.sort(list, c)对集合进行排序,其中参数 list 为要要排序的集合,参数 c 为实现了 Comparator 接口的对象(它决定了排序的方式)。

测试代码如下:

// 明星类
class Star{
	private String name;
	private int age;
	
	public Star(){
		super();
	}

	public Star(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}

	public String toString(){
		return "[name: " + name + ", age: " + age + "]";
	}
}

public class Star_Comparator extends Star implements Comparator{
	public Star_Comparator(){
		super();
	}
	
	public Star_Comparator(String name, int age){
		super(name, age);
	}
	
	@Override
	public int compare(Star_Comparator o1, Star_Comparator o2) {
		// 排序时先看姓名,再看年龄;比较年龄时,用o1 - o2,则排序结果为正序(从小到大)
		if(o1.getName() == o2.getName()){
			return o1.getAge() - o2.getAge();
		}else{
			return o1.getName().compareTo(o2.getName());
		}
	}
	
	public static void main(String[] args) {
		Star_Comparator s1 = new Star_Comparator("pual", 31);
		Star_Comparator s2 = new Star_Comparator("kobe", 24);
		Star_Comparator s3 = new Star_Comparator("wade", 34);
		Star_Comparator s4 = new Star_Comparator("kobe", 34);
		List<Star_Comparator> list = new ArrayList<>();
		list.add(s1);
		list.add(s2);
		list.add(s3);
		list.add(s4);
		System.out.println(list);
		Collections.sort(list, new Star_Comparator());
		System.out.println(list);
	}
}

测试结果:

[[name: pual, age: 31], [name: kobe, age: 24], [name: wade, age: 34], [name: kobe, age: 34]]
[[name: kobe, age: 24], [name: kobe, age: 34], [name: pual, age: 31], [name: wade, age: 34]]
发布了56 篇原创文章 · 获赞 0 · 访问量 953

猜你喜欢

转载自blog.csdn.net/weixin_45594025/article/details/104405473