在java中经常涉及到对象数组的比较的情况,常见的有两种方法来处理:
Comparable 是排序接口。(自然排序)
若一个类实现了Comparable接口,就意味着“该类支持排序”。 即然实现Comparable接口的类支持排序,假设现在存在“实现Comparable接口的类的对象的List列表(或数组)”,则该List列表(或数组)可以通过 Collections.sort(或 Arrays.sort)进行排序。
此外,“实现Comparable接口的类的对象”可以用作“有序映射(如TreeMap)”中的键或“有序集合(TreeSet)”中的元素,而不需要指定比较器。
1)String:按照字符串中字符的Unicode值进行比较
2)Character:按照字符的Unicode值来进行比较
3)数值类型对应的包装类以及BigInteger、BigDecimal:按照它们对应的数值大小进行比较
4)Boolean:true 对应的包装类实例大于 false 对应的包装类实例
5)Date、Time等:后面的日期时间比前面的日期时间大
Comparable 接口仅仅只包括一个函数,它的定义如下:
package java.lang;
import java.util.*;
public interface Comparable {
public int compareTo(T o);
}
解释: 假设我们通过 x.compareTo(y) 来“比较x和y的大小”。若返回“负数”,意味着“x比y小”;返回“零”,意味着“x等于y”;返回“正数”,意味着“x大于y”。
这里为了大家更好的理解Compareable这个接口, 我自己手写了一个Compareable接口.
Comparable接口
package com.company.strategy2;
/**
* Created by 苍狼
* Time on 2022-08-06
*/
public interface Comparable {
public int compareTo(T object);
}
Cat实体类
package com.company.strategy2;
/**
* Created by 苍狼
* Time on 2022-08-06
*/
public class Cat implements Comparable {
private int height;
private int weight;
public Cat(int height, int weight){
this.height = height;
this.weight = weight;
}
public int compareTo(Cat cat){
if(this.height>cat.height){
return 1;
} else if(this.heightpackage com.company.strategy2;
/**
* Created by 苍狼
* Time on 2022-08-06
*/
public class Sorter {
public static void sort(Comparable[] arr) {
if (arr == null || arr.length < 2) {
return;
}
for (int e = arr.length - 1; e > 0; e--) {
for (int i = 0; i < e; i++) {
if (arr[i].compareTo(arr[i + 1]) == 1) {
swap(arr, i, i + 1);
}
}
}
}
public static void swap(Comparable[] arr, int i, int j) {
Comparable temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
测试类
package com.company.strategy2;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Cat[] cats = {new Cat(111,111), new Cat(555,555), new Cat(222,222), new Cat(444,444)};
Sorter sorter = new Sorter();
sorter.sort(cats);
System.out.println(Arrays.toString(cats));
}
}
实际使用中则不需要自己手写Comparable接口和sort排序算法.
Pig实体类
package com.company.strategy2;
/**
* Created by 苍狼
* Time on 2022-08-07
*/
public class Pig implements java.lang.Comparable {
private Double weight;
public Pig(Double weight){
this.weight = weight;
}
@Override
public int compareTo(Pig pig) {
if (this.weight>pig.weight) {
return 1;
} else if (this.weight
测试类
package com.company.strategy2;
import java.util.Arrays;
/**
* Created by 苍狼
* Time on 2022-08-07
*/
public class Test {
public static void main(String[] args) {
Pig[] pigs = new Pig[]{new Pig(123.5), new Pig(145.6), new Pig(111.6)};
System.out.println(Arrays.toString(pigs));
Arrays.sort(pigs);
System.out.println(Arrays.toString(pigs));
}
}
运行结果
1) 当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象来排序,强行对多个对象进行整体排序的比较。
2) 重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。
3) 可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。
4) 还可以使用 Comparator 来控制某些数据结构(如有序 set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。
Comparator 接口仅仅只包括两个个函数,它的定义如下:
package java.util;
public interface Comparator {
int compare(T o1, T o2);
boolean equals(Object obj);
}
解释: 若一个类要实现Comparator接口:它一定要实现compareTo(T o1, T o2) 函数,但可以不实现 equals(Object obj) 函数。
问题: 为什么可以不实现 equals(Object obj) 函数呢?
因为任何类,默认都是已经实现了equals(Object obj)的。 Java中的一切类都是继承于java.lang.Object,在Object.java中实现了equals(Object obj)函数;所以,其它所有的类也相当于都实现了该函数。
int compare(T o1, T o2) 是“比较o1和o2的大小”。返回“负数”,意味着“o1比o2小”;返回“零”,意味着“o1等于o2”;返回“正数”,意味着“o1大于o2”
同样的, 为了大家更加直观的理解, 我这里也同样写两个案例, 一个手写Comparator接口, 一个使用java提供的Comparator接口
package com.company.strategy3;
/**
* Created by 苍狼
* Time on 2022-08-06
*/
@FunctionalInterface //如果这里只有一个方法, 则这个也可以不写
public interface Comparator {
public int compare(T t1, T t2);
default void show(){
System.out.println("世界, 你好....");
}
}
Cat实体类
package com.company.strategy3;
/**
* Created by 苍狼
* Time on 2022-08-06
*/
public class Cat{
private int height;
private int weight;
public Cat(int height, int weight){
this.height = height;
this.weight = weight;
}
@Override
public String toString() {
return "Cat{" +
"height=" + height +
", weight=" + weight +
'}';
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
cat的比较器类
package com.company.strategy3;
/**
* Created by 苍狼
* Time on 2022-08-06
*/
public class CatComparator implements Comparator{
@Override
public int compare(Cat t1, Cat t2) {
if(t1.getHeight()*t1.getWeight()>t2.getHeight()*t2.getWeight()){
return 1;
} else if (t1.getHeight()*t1.getWeight()
排序类Sorter中的sort排序方法
package com.company.strategy3;
/**
* Created by 苍狼
* Time on 2022-08-06
*/
public class Sorter {
public void sort(T[] arr, Comparator comparator) {
if (arr == null || arr.length < 2) {
return;
}
for (int e = arr.length - 1; e > 0; e--) {
for (int i = 0; i < e; i++) {
if (comparator.compare(arr[i], arr[i+1])==1){
swap(arr, i, i+1);
}
}
}
}
public void swap(T[] arr, int i, int j) {
T temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
测试类
package com.company.strategy3;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Cat[] cats = {new Cat(111,111), new Cat(555,555), new Cat(222,222), new Cat(444,444)};
Sorter sorter1 = new Sorter<>();
sorter1.sort(cats, new CatComparator());
System.out.println(Arrays.toString(cats));
}
}
这里也可以用测试类Lambda表达式来写
package com.company.strategy3;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
Sorter sorter = new Sorter();
Cat[] cats= new Cat[]{new Cat(1111,1111), new Cat(8888,8888), new Cat(3333,3333), new Cat(6666,6666)};
sorter.sort(cats, (o1,o2)->{
if (o1.getHeight()>o2.getHeight()){
return 1;
} else if (o1.getHeight()
Dog实体类
package com.company.strategy3;
/**
* Created by 苍狼
* Time on 2022-08-06
*/
public class Dog implements Comparable {
private int food;
public Dog(int food){
this.food = food;
}
@Override
public int compareTo(Dog dog) {
if(this.food > dog.food){
return 1;
} else if (this.food < dog.food){
return -1;
} else{
return 0;
}
}
@Override
public String toString() {
return "Dog{" +
"food=" + food +
'}';
}
public void setFood(int food){
this.food = food;
}
public int getFood(){
return this.food;
}
}
Dog的比较器类
package com.company.strategy3;
/**
* Created by 苍狼
* Time on 2022-08-06
*/
public class DogComparator implements Comparator{
@Override
public int compare(Dog t1, Dog t2) {
if (t1.getFood()>t2.getFood()){
return 1;
} else if (t1.getFood()
测试类
package com.company.strategy3;
import java.util.Arrays;
/**
* Created by 苍狼
* Time on 2022-08-07
*/
public class Test {
public static void main(String[] args) {
Dog[] dogs = new Dog[]{new Dog(111), new Dog(777), new Dog(555), new Dog(333)};
System.out.println(Arrays.toString(dogs));
System.out.println("=====================");
Arrays.sort(dogs, new DogComparator());
System.out.println(Arrays.toString(dogs));
}
}
运行结果
Comparable是排序接口: 若一个类实现了Comparable接口,就意味着“该类支持排序”。
而Comparator是比较器: 我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。
我们不难发现:Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。