Java常用类之比较器的使用详解

 更新时间:2022年11月22日 08:56:40   作者:馆主阿牛  
这篇文章主要为大家详细介绍了Java中比较器的相关资料,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下

前言

Java 中的对象,正常情况下,只能进行 = 或 != 比较。不能使用 > 或 < 的比较,但是在开发场景中,我们需要对多个对象进行排序,这就需要比较对象的大小。此时我们如何实现呢?java为我们提供了两个接口,使用两个接口中的任何一个: Comparable 或 Comparator 即可实现对象的比较大小!

java 比较器概述

在 Java 中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题。

Java 实现对象排序的方式有两种:

  • 自然排序: java. lang.Comparable
  • 定制排序: java.util.Comparator

自然排序 Comparable

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值反过来!

定制排序 Comparator

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 与 Comparator 的使用对比

Comparable 接口的方式一旦一定,保证 Comparable 接口实现类的对象在任何位置都可以比较大小 ,而 Comparator 接口属于临时性的比较。
再者一个很直观的是Comparable是在自定义类中将比较规则在类中写死了的,而Comparator则比较灵活,在比较时定义比较规则,看起来灵活一点!

到此这篇关于Java常用类之比较器的使用详解的文章就介绍到这了,更多相关Java比较器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 实现分布式WebSocket集群的方法

    实现分布式WebSocket集群的方法

    本文总结出了几个实现分布式WebSocket集群的办法,从zuul到spring cloud gateway的不同尝试,总结出了这篇文章,希望能帮助到某些人,并且能一起分享这方面的想法与研究
    2022-03-03
  • Java 多个异常共享同一个异常处理器的方法

    Java 多个异常共享同一个异常处理器的方法

    这篇文章主要介绍了Java 多个异常共享同一个异常处理器的方法,Java 的异常处理机制,在 Java 7 中有了非常大的改进。其中一个特性就是,支持多个异常共享同一个异常处理器。,需要的朋友可以参考下
    2019-06-06
  • Java多种方式实现生产者消费者模式

    Java多种方式实现生产者消费者模式

    这篇文章主要介绍了Java多种方式实现生产者消费者模式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • 如何使用IntelliJ IDEA中的Live Templates自定义代码模板

    如何使用IntelliJ IDEA中的Live Templates自定义代码模板

    在IntelliJ IDEA中,通过使用LiveTemplates功能,可以实现快速编码和自定义代码模板,例如,输入“main”可以自动补全主函数结构,“sout”可以补全输出语句,用户可以通过设置中的LiveTemplates选项查看和定义快捷模板,支持使用分组管理和参数化模板内容,适应复杂的编码需求
    2024-11-11
  • Java正则表达式之split()方法实例详解

    Java正则表达式之split()方法实例详解

    这篇文章主要介绍了Java正则表达式之split()方法,结合实例形式较为详细的分析了split方法的功能、使用方法及相关注意事项,需要的朋友可以参考下
    2017-03-03
  • Jersey Restful接口如何获取参数的问题

    Jersey Restful接口如何获取参数的问题

    这篇文章主要介绍了Jersey Restful接口如何获取参数的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • java springmvc 注册中央调度器代码解析

    java springmvc 注册中央调度器代码解析

    这篇文章主要介绍了java springmvc 注册中央调度器代码解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • 关于Lombok简化编码使用及说明

    关于Lombok简化编码使用及说明

    这篇文章主要介绍了关于Lombok简化编码使用及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • idea中如何过滤某些文件不提交的方法实现

    idea中如何过滤某些文件不提交的方法实现

    本文主要介绍了idea中如何过滤某些文件不提交,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • Java匿名类,匿名内部类实例分析

    Java匿名类,匿名内部类实例分析

    这篇文章主要介绍了Java匿名类,匿名内部类,结合实例形式分析了Java匿名类,匿名内部类相关原理、用法及操作注意事项,需要的朋友可以参考下
    2020-04-04

最新评论