【详细清晰】Java中比较器:Comparable和Comparator接口

1、前言

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

   Java中的对象,正常情况下,只能进行比较:==   !=。不能用 >  < 号比较对象,使用以下方式比较对象的大小。

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

        ①自然排序:java.lang.Comparable

        ②定制排序:java.util.Comparator

 

2、方式一:自然排序,自定义类实现Comparable接口

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

   实现Comparable的类必须实现的Comparable中的compareTo(Object obj)方法,两个对象通过compareTo(Object obj)方法的返回值来比较大小。 

   如果当this对象大于形参的obj,则返回正整数;

   如果当前this对象小于形参obj,则返回负整数;

   如果当前对象的this等于形参obj,则返回0;

   返回的是如果前面添加 负号,

 // 返回的是自然排序从小到大,要从大到小的话,在前面添加负号
                    return -s1.compareTo(s2);

  有的类已经实现了Comparable接口,比如String,重写了接口中的compareTo()方法,给出比较两个对象的大小。对于自定义的类来说,如果需要排序,我们可以自定义类实现Comparable接口,重写compareTo()方法进行排序。

  注意:A instanceOf(B):意思是判断A是否是B的对象

  具体自定义类的比较,需要实现Comparable接口,然后实现compareTo()方法。

public class Goods implements Comparable{
    private String name;
    private Double price;

    public Goods(String name, Double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

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

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

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

    public int compareTo(Object o) {
         // 判断参数对象是否属于Goods
        if (o instanceof Goods) {
            // 将参数o强转Goods对象
            Goods good = (Goods)o;

            if (this.price > good.price) {
                return 1;
            } else if (this.price < good.price) {
                return -1;
            } else {
//                return 0;
                // 当商品价格相同的时候,就从商品的名称开始排序
                return this.name.compareTo(good.name);
            }

           // return Double.compare(this.price, good.price);
        }
        // 如果不是一个商品就抛出异常
        throw new RuntimeException("运行时候异常");
    }
}

   

public void test3(){
        String[] arr = new String[]{"ZZ","KK","QQ","WW"};
        Arrays.sort(arr, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                // 两个对象都应该是String类似,满足才比较
                if (o1 instanceof String && o2 instanceof String) {
                    // 进行强转
                    String s1 = (String) o1;
                    String s2 = (String) o2;

                    // 返回的是自然排序从小到大,要从大到小的话,在前面添加负号
                    return -s1.compareTo(s2);
                }
                throw new RuntimeException("运行时候异常");
            }
        });
        System.out.println(Arrays.toString(arr));

    }

2、方式一:定制排序,排序的时候new Compartor(){}

      当元素的类型没有实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则而不适合的操作,那么可以使用Comparator的对象来排序。

      在sort()方法中的第二个参数实现Comparator(){},判断对象的大小。

      compare(Object obj,Object obj),比较o1和o2的大小:如果方法放回正整数,则o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2;

      注意:int compare(T o1,T o2):意思是判断A是否是B的对象

     代码如下:实现的是如果name相同,就比较price。否则就按照姓名排序。

   @Test
    public void test4(){
        Goods[] goods = new Goods[5];
        goods[0] = new Goods("qwq", 12.0);
        goods[1] = new Goods("dwe", 13.0);
        goods[2] = new Goods("awqeq", 54.0);
        goods[3] = new Goods("yh", 1000.0);
        goods[4] = new Goods("yh", 123.0);
        Arrays.sort(goods, new Comparator<Goods>() {
            @Override
            public int compare(Goods o1, Goods o2) {
                if (o1.getName().equals(o2.getName())) {
                    return o1.getPrice().compareTo(o2.getPrice());
                } else {
                    return o1.getName().compareTo(o2.getName());
                }
            }
        });
        System.out.println(Arrays.toString(goods));
    }

4、总结

      本文是主要讲的是Java中的比较器,现在来做个总结。

        ①自然比较:java.lang.Comparable,接口中的方法public  int compareTo(T o);

        ②定制比较:java.util.Comparator  , 接口中的方法  int compare(T o1,T o2)

      比较:

       Comparable接口的方式一旦确定,保证Comparable接口实现实现类的对象在任何位置比较大小。

       Comparator接口属于临时性比较,相当于一次性的,程序自己写。

 

上一篇:CSS3移动端vw+rem不依赖JS实现响应式布局


下一篇:R语言简单自编码器AE