Java 中的对象,正常情况下,只能进行 = 或 != 比较。不能使用 > 或 < 的比较,但是在开发场景中,我们需要对多个对象进行排序,这就需要比较对象的大小。此时我们如何实现呢?java为我们提供了两个接口,使用两个接口中的任何一个: Comparable 或 Comparator 即可实现对象的比较大小!
在 Java 中经常会涉及到对象数组的排序问题,那么就涉及到对象之间
的比较问题。
Java 实现对象排序的方式有两种:
1.Comparable 接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。
2.实现 Comparable 的类必须实现 compareTo (Object obj)方法,两个对象即通过 compareTo (Object obj)方法的返回值来比较大小。如果当前对象 this 大于形参对象 obj ,则返回正整数,如果当前对象 this 小于形参对象 obj ,则返回负整数,如果当前对象 this 等于形参对象 obj ,则返回零。
3.实现 Comparable 接口的对象数组可以通过 Collections.sort 或Arrays.sort 进行自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
注:像 String 、包装类等实现了 Comparable 接口,重写了 compareTo(obj) 方法,进行了从小到大的排列!
import java.util.Arrays;
public class ComparableTest {
public static void main(String[] args) {
String[] arr = new String[]{"aniu","tom","tony","lisa"};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}
}
这是因为我们的String实现了Comparable接口,并对compareTo方法进行了重写!
此时我们要将这个对象实现Comparable接口,然后重写compareTo方法。
package 比较器;
import java.util.Arrays;
public class ComparableDemo {
public static void main(String[] args) {
Books[] book = new Books[4];
book[0] = new Books("The Beautiful and the Damned",68);
book[1] = new Books("Where Angels Fear to Tread",45);
book[2] = new Books("These Lovers Fled Away",35);
book[3] = new Books("The Left Hand of Darkness",58);
Arrays.sort(book);
for(Books item:book){
System.out.println(item.toString());
}
//System.out.println(Arrays.toString(book));
}
}
class Books implements Comparable{
String name;
double price;
public Books(String name, double price) {
this.name = name;
this.price = price;
}
//重写compareTo
@Override
public int compareTo(Object o) {
//按照图书价格从小到大排序
if (o instanceof Books){
Books b = (Books) o;
if(this.price>b.price){
return 1;
}else if(this.price<b.price) {
return -1;
}else{
return 0;
}
}
throw new RuntimeException("传入的数据类型不一致!");
}
//重写 toString
@Override
public String toString() {
return "Books{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
这样写是从小到大排,如果要从大到小排,则需要将return值反过来!
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 或有序映射)的顺序,或者为那些没有自然顺序的对象 colection 提供排序。
package 比较器;
import java.util.Arrays;
import java.util.Comparator;
public class ComparatorDemo {
public static void main(String[] args) {
Book[] book = new Book[4];
book[0] = new Book("The Beautiful and the Damned",68);
book[1] = new Book("Where Angels Fear to Tread",45);
book[2] = new Book("These Lovers Fled Away",35);
book[3] = new Book("The Left Hand of Darkness",58);
Arrays.sort(book, new Comparator(){
//按照价格从大到小排
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof Book && o2 instanceof Book){
Book b1 = (Book)o1;
Book b2 = (Book)o2;
return -Double.compare(b1.price,b2.price); //这里我们直接调用Double的compare方法
}
throw new RuntimeException("传入的数据类型不一致!");
}
});
for(Book item:book){
System.out.println(item.toString());
}
//System.out.println(Arrays.toString(book));
}
}
class Book{
String name;
double price;
public Book(String name, double price) {
this.name = name;
this.price = price;
}
//重写 toString
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
可以从代码看到,这里这里我们直接调用Double的compare方法进行了比较,不用像上面的案例一样手写了,当然我们也可以用comparTo方法,因为上面提到了,包装类也实现了Comparable接口,但Double重写的comparTo方法底层依旧是compare方法!因为是从大到小排,所以在Double前加个负号!
Comparable 接口的方式一旦一定,保证 Comparable 接口实现类的对象在任何位置都可以比较大小 ,而 Comparator 接口属于临时性的比较。
再者一个很直观的是Comparable是在自定义类中将比较规则在类中写死了的,而Comparator则比较灵活,在比较时定义比较规则,看起来灵活一点!
如果你觉得博主写的还不错的话,可以关注一下当前专栏,博主会更完这个系列的哦!也欢迎订阅博主的其他好的专栏。
🏰系列专栏
👉软磨 css
👉硬泡 javascript
👉flask框架快速入门