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比较器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot创建多模块项目的全过程记录

    SpringBoot创建多模块项目的全过程记录

    这篇文章主要给大家介绍了关于SpringBoot创建多模块项目的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • Java属性文件操作之Properties与ResourceBundle详解

    Java属性文件操作之Properties与ResourceBundle详解

    这篇文章主要介绍了Java属性文件操作之Properties与ResourceBundle详解,两个类都可以读取属性文件中以key/value形式存储的键值对,ResourceBundle读取属性文件时操作相对简单,需要的朋友可以参考下
    2023-11-11
  • Java从控制台读入数据的几种方法总结

    Java从控制台读入数据的几种方法总结

    下面小编就为大家带来一篇Java从控制台读入数据的几种方法总结。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-10-10
  • Mybatis主配置文件的properties标签详解

    Mybatis主配置文件的properties标签详解

    这篇文章主要介绍了Mybatis主配置文件的properties标签,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-08-08
  • 解读maven项目的打包方式

    解读maven项目的打包方式

    这篇文章主要介绍了关于maven项目的打包方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • Java编程实现向文本文件中读取数据之Scanner用法示例

    Java编程实现向文本文件中读取数据之Scanner用法示例

    这篇文章主要介绍了Java编程实现向文本文件中读取数据之Scanner用法,结合实例形式分析了java使用Scanner类读取文本文件相关操作技巧与注意事项,需要的朋友可以参考下
    2018-03-03
  • spring security国际化及UserCache的配置和使用

    spring security国际化及UserCache的配置和使用

    这篇文章主要介绍下国际化的配置及UserCache的配置及使用教程,感兴趣的朋友参考下实现代码吧
    2017-09-09
  • 解决java.lang.ClassCastException的java类型转换异常的问题

    解决java.lang.ClassCastException的java类型转换异常的问题

    这篇文章主要介绍了解决java.lang.ClassCastException的java类型转换异常的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • SpringMVC JSON数据交互实现过程解析

    SpringMVC JSON数据交互实现过程解析

    这篇文章主要介绍了SpringMVC JSON数据交互实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • Java中InetAddress类的使用

    Java中InetAddress类的使用

    InetAddress类是Java中用于表示IP地址的类,本文就来介绍一下Java中InetAddress类的使用,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09

最新评论