Java——比较器

引入的背景

我们知道基本数据类型的数据(除boolean类型外)需要比较大小的话,直接使用比较运算符即可,但是引用数据类型是不能直接使用比较运算符来比较大小的。那么,如何解决这个问题呢?

在Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题。
Java实现对象排序的方式有两种:

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

自然排序:java.lang.Comparable

Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。

实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小。
如果当前对象this大于形参对象obj,则返回正整数。
如果当前对象this小于形参对象obj,则返回负整数。
如果当前对象this等于形参对象obj,则返回零。

package java.lang;

public interface Comparable{
    int compareTo(Object obj);
}

Comparable 的典型实现:(默认都是从小到大排列的)

  • String:按照字符串中字符的Unicode值进行比较
  • Character:按照字符的Unicode值来进行比较
  • 数值类型对应的包装类以及BigInteger、BigDecimal:按照它们对应的数值大小进行比较
  • Boolean:true 对应的包装类实例大于 false 对应的包装类实例
  • Date、Time等:后面的日期时间比前面的日期时间大

测试String

代码示例:

 @Test
    public void test1(){
        //测试String已经写好的
        String [] a = new String[]{"Jack", "Tom", "Lucy"};

        //排序之前
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+"\t");
        }

        System.out.println();
        //使用Arrays进行排序
        Arrays.sort(a);

        //排序之后进行展示
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i]+"\t");
        }
    }

运行效果:

在这里插入图片描述

测试自己实现comparable接口

Product类

package cn.edu.chd.exer1;

import java.util.Objects;


public class Product implements Comparable{
    private String name;
    private double prices;

    //无参构造
    public Product() {
    }

    //全参构造
    public Product(String name, double prices) {
        this.name = name;
        this.prices = prices;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrices() {
        return prices;
    }

    public void setPrices(double prices) {
        this.prices = prices;
    }

    @Override
    public String toString() {
        return "Product{" +
                "name='" + name + '\'' +
                ", prices=" + prices +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Product product = (Product) o;
        return Double.compare(product.prices, prices) == 0 && name.equals(product.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, prices);
    }

    @Override
    public int compareTo(Object o) {
        //如果是同一个对象,return 0
        if (this == o){
            return 0;
        }

        //两个对象比较的标准是:价格从小到大,价格一样的话,按照名字从小到大
        if (o instanceof Product){
            Product p = (Product)o;
            int v = Double.compare(this.prices, p.prices);
//            return v;
            if (v != 0){
                return v;
            }
            //价格如果相同,名字按照从小到大
            return this.name.compareTo(p.name);
        }
        //手动抛异常
        throw new RuntimeException("类型不匹配");

    }
}

测试

    //对不同对象的大小进行排序
    @Test
    public void test2(){

        //商品数组
        Product[] products = new Product[5];
        //全参构造器,在new对象时就对属性进行赋值
        products[0] = new Product("Huawei", 5999);
        products[1] = new Product("XiaoMi", 4999);
        products[2] = new Product("iPhone", 9999);
        products[3] = new Product("vivo", 3999);
        products[4] = new Product("Honer", 5999);


        System.out.println("排序之前");
        //排序之前的遍历
        for (int i = 0; i < products.length; i++) {
            System.out.println(products[i]);
        }

        System.out.println("----------------------------------------------");
        //使用arrays进行排序
        Arrays.sort(products);

        System.out.println("排序之后");
        //排序后的遍历
        for (int i = 0; i < products.length; i++) {
            System.out.println(products[i]);
        }
        
    }

运行效果

在这里插入图片描述

定制排序:java.util.Comparator

思考

  • 当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码(例如:一些第三方的类,你只有.class文件,没有源文件)
  • 如果一个类,实现了Comparable接口,也指定了两个对象的比较大小的规则,但是此时此刻我不想按照它预定义的方法比较大小,但是我又不能随意修改,因为会影响其他地方的使用,怎么办?(例如:我想要String按照字母从大到小的顺序排序,而不是默认的从小到大)

JDK在设计类库之初,也考虑到这种情况,所以又增加了一个java.util.Comparator接口。强行对多个对象进行整体排序的比较。

  • 重写compare(Object o1,Object o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。
  • 可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。

Product类

package cn.edu.chd.exer2;

import java.util.Objects;


public class Product implements Comparable{
    private String name;
    private double prices;

    //无参构造
    public Product() {
    }

    //全参构造
    public Product(String name, double prices) {
        this.name = name;
        this.prices = prices;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrices() {
        return prices;
    }

    public void setPrices(double prices) {
        this.prices = prices;
    }

    @Override
    public String toString() {
        return "Product{" +
                "name='" + name + '\'' +
                ", prices=" + prices +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Product product = (Product) o;
        return Double.compare(product.prices, prices) == 0 && name.equals(product.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, prices);
    }

    @Override
    public int compareTo(Object o) {
        //如果是同一个对象,return 0
        if (this == o){
            return 0;
        }

        //两个对象比较的标准是:价格从小到大,价格一样的话,按照名字从小到大
        if (o instanceof Product){
            Product p = (Product)o;
            int v = Double.compare(this.prices, p.prices);
//            return v;
            if (v != 0){
                return v;
            }
            //价格如果相同,名字按照从小到大
            return this.name.compareTo(p.name);
        }
        //手动抛异常
        throw new RuntimeException("类型不匹配");

    }
}

按照商品的价格从低到高排序的comparator

 @Test
    public void test1(){
        //new一个comparator接口的匿名实现类
        Comparator comparator = new Comparator() {
            //按照商品的价格从低到高排序
            @Override
            public int compare(Object o1, Object o2) {
                if (o1 == o2){
                    return 0;
                }
                if (o1 instanceof Product && o2 instanceof Product){
                    //强转
                    Product p1 = (Product) o1;
                    Product p2 = (Product) o2;
                    return Double.compare(p1.getPrices(), p2.getPrices());

                }
                throw new RuntimeException("类型不匹配");

            }
        };

        //商品数组
        Product[] products = new Product[5];
        //全参构造器,在new对象时就对属性进行赋值
        products[0] = new Product("Huawei", 5999);
        products[1] = new Product("XiaoMi", 4999);
        products[2] = new Product("iPhone", 9999);
        products[3] = new Product("vivo", 3999);
        products[4] = new Product("Honer", 5999);


        System.out.println("排序之前");
        //排序之前的遍历
        for (int i = 0; i < products.length; i++) {
            System.out.println(products[i]);
        }

        System.out.println("----------------------------------------------");
        //将comparator对象作为参数进行传入,排序
        Arrays.sort(products, comparator);

        System.out.println("排序之后");
        //排序后的遍历
        for (int i = 0; i < products.length; i++) {
            System.out.println(products[i]);
        }



        
    }

运行效果:

在这里插入图片描述

按照名称进行排序的comparator

   //按照名称进行排序
    @Test
    public void test2(){
        //new一个comparator接口的匿名实现类
        Comparator comparator = new Comparator() {
            //按照商品的名称进行排序
            @Override
            public int compare(Object o1, Object o2) {
                if (o1 == o2){
                    return 0;
                }
                if (o1 instanceof Product && o2 instanceof Product){
                    //强转
                    Product p1 = (Product) o1;
                    Product p2 = (Product) o2;
                    return p1.getName().compareTo(p2.getName());

                }
                throw new RuntimeException("类型不匹配");

            }
        };

        //商品数组
        Product[] products = new Product[5];
        //全参构造器,在new对象时就对属性进行赋值
        products[0] = new Product("Huawei", 5999);
        products[1] = new Product("XiaoMi", 4999);
        products[2] = new Product("iPhone", 9999);
        products[3] = new Product("vivo", 3999);
        products[4] = new Product("Honer", 5999);


        System.out.println("排序之前");
        //排序之前的遍历
        for (int i = 0; i < products.length; i++) {
            System.out.println(products[i]);
        }

        System.out.println("----------------------------------------------");
        //将comparator对象作为参数进行传入,排序
        Arrays.sort(products, comparator);

        System.out.println("排序之后");
        //排序后的遍历
        for (int i = 0; i < products.length; i++) {
            System.out.println(products[i]);
        }


    }

运行效果:

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Beyond Compare 是一款非常强大的文件比较工具,可以用于比较和合并各种类型的文件和文件夹。然而,Beyond Compare 默认情况下并不支持 Java 反编译,因为它主要是用于比较文本、二进制、图像等类型的文件,而不是代码文件。 不过,有一些第三方插件可以为 Beyond Compare 添加 Java 反编译功能。一种常用的插件是 Jadclipse,它是一个用于 Eclipse 的插件,可以在 Eclipse 中将编译后的 Java 类文件反编译为源代码。使用 Jadclipse 插件后,我们可以在 Beyond Compare 中选择将编译后的 Java 类文件与其对应的源代码文件进行比较,以查看源代码的差异。 要使用 Jadclipse 插件,我们首先需要在 Beyond Compare 中进行设置。在 Beyond Compare 的“工具”菜单中选择“自定义文件类型”选项,然后点击“新建”按钮。在弹出的窗口中,输入文件类型名称为“Java Class”,文件扩展名为“.class”,然后在后面的“转换”栏中填写 Jadclipse 的路径,以便 Beyond Compare 通过它来反编译 Java 类文件。 完成设置后,我们就可以使用 Beyond Compare 打开编译后的 Java 类文件与源代码文件进行比较了。在比较结果中,我们可以看到类方法的差异,反编译后的源代码可以作为比较结果的一部分显示。 需要注意的是,Jadclipse 插件只能对编译后的类文件进行反编译,而无法对已经压缩和混淆的类文件进行有效的反编译。对于混淆的代码,可能需要使用其他工具来还原源代码。 总而言之,通过添加 Jadclipse 插件,我们可以在 Beyond Compare 中对 Java 类文件进行反编译和比较,以便更好地理解和分析代码的差异。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值