Java两个比较器

Java两个比较器

一、自然排序:Comparable接口

  • java.lang.Comparable

  • Comparable 接口强行对实现它的每个类的对象进行整体排序(被称为,类的排序)。

  • 重写 compareTo(Object obj) 方法的规则(两个对象通过该方法的返回值来比较大小):

    • 如果当前对象this大于形参对象obj,则返回正整数;
    • 如果当前对象this小于形参对象obj,则返回负整数;
    • 如果当前对象this等于参数对象obj,则返回零。
    //String类中对compareTo方法的重写
    public int compareTo(String anotherString) {
          
          
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;
    
        int k = 0;
        while (k < lim) {
          
          
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
          
          
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }
    
  • 如果自定义类需要排序,需让自定义类继承 Comparable 接口,重写 compareTo 方法,在其中指定排序方法。

  • 实现Comparable接口的对象列表或数组,可以通过 Collections.sort 或 Arrays.sort 进行自动排序。实现此接口的对象可以用作有序映射中的键有序集合中的元素,无需指定比较器。

  • 对于类 C 的每一个 e1 和 e2 来说,当且仅当 e1.compareTo(e2) == 0 与 e1.equals(e2) 具有相同的 boolean 值时,类 C 的自然排序才叫做与 equals 一致。建议(虽然不是必需的)最好使自然排序与 equals 一致。

  • 自定义类继承接口重写方法的代码举例:

    import org.junit.Test;
    import java.util.Arrays;
    
    public class ComparableTest {
          
          
        @Test
        public void test() {
          
          
            Goods[] arr = new Goods[5];
            arr[0] = new Goods("1", 4);
            arr[1] = new Goods("2", 3);
            arr[2] = new Goods("3", 2);
            arr[3] = new Goods("4", 1);
            arr[4] = new Goods("5", 3);
    
    
            Arrays.sort(arr);
            System.out.println(Arrays.toString(arr));
        }
    }
    
    class Goods implements Comparable{
          
          
        private String name;
        private double price;
    
        public Goods(String name, double price) {
          
          
            this.name = name;
            this.price = price;
        }
    
        @Override
        public String toString() {
          
          
            return "Goods{" +
                    "name='" + name + '\'' +
                    ", price=" + price +
                    '}';
        }
    
        @Override
        public int compareTo(Object o) {
          
          
            if (o instanceof Goods) {
          
          
                Goods goods = (Goods)o;
                if (this.price > goods.price)
                    return 1;
                else if (this.price < goods.price)
                    return -1;
                else
                    return -this.name.compareTo(goods.name);
            }
            throw new RuntimeException("货物数据输入错误!");
        }
    }
    

二、定制排序:Compatator

  • 当元素的类型没有实现 java.lang.Comparable 接口而又不方便修改代码,或者实现了 java.lang.Comparable 接口的排序顺序不适合当前的操作,那么可以考虑使用 Comparator 的对象来排序,强行对多个对象进行整体排序的比较。

  • 重写 compare(Object o1, Object o2) 方法(比较 o1 和 o2 的大小):

    • 返回正整数,表示 o1 大于 o2;
    • 返回 0,表示相等;
    • 返回负整数,表示 o1 小于 o2。
  • 例子

    • 使用String重写的compare方法

      import org.junit.Test;
      import java.util.Arrays;
      import java.util.Comparator;
      
      public class ComparableTest {
              
              
          @Test
          public void test() {
              
              
              String[] arr = new String[]{
              
              "AA","EE","CC","DD","BB"};
              Arrays.sort(arr, new Comparator() {
              
              
                  @Override
                  public int compare(Object o1, Object o2) {
              
              
                      if (o1 instanceof String && o2 instanceof String) {
              
              
                          String s1 = (String)o1;
                          String s2 = (String)o2;
                          return -s1.compareTo(s1);
                      }
                      throw new RuntimeException("输入数据类型不一致!");
                  }
              });
              System.out.println(Arrays.toString(arr));
          }
      }
      
    • 自定义重写compare方法

    package com.exer03;
    
    import org.junit.Test;
    import java.util.Arrays;
    import java.util.Comparator;
    
    public class ComparableTest {
          
          
        @Test
        public void test() {
          
          
            Goods[] arr = new Goods[5];
            arr[0] = new Goods("1", 4);
            arr[1] = new Goods("2", 3);
            arr[2] = new Goods("3", 2);
            arr[3] = new Goods("4", 1);
            arr[4] = new Goods("1", 3);
            Arrays.sort(arr, new Comparator() {
          
          
                @Override
                public int compare(Object o1, Object o2) {
          
          
                    if (o1 instanceof Goods && o2 instanceof Goods) {
          
          
                        Goods g1 = (Goods)o1;
                        Goods g2 = (Goods)o2;
                        if (g1.getName().equals(g2.getName())) {
          
          
                            return -Double.compare(g1.getPrice(), g2.getPrice());
                        }else{
          
          
                            return g1.getName().compareTo(g2.getName());
                        }
                    }
                    throw new RuntimeException("输入数据类型不一致!");
                }
            });
            System.out.println(Arrays.toString(arr));
        }
    }
    
    class Goods {
          
          
        private String name;
        private double price;
    
        public String getName() {
          
          
            return name;
        }
    
        public double getPrice() {
          
          
            return price;
        }
    
        public Goods(String name, double price) {
          
          
            this.name = name;
            this.price = price;
        }
    
        @Override
        public String toString() {
          
          
            return "Goods{" +
                    "name='" + name + '\'' +
                    ", price=" + price +
                    '}';
        }
    }
    

三、两者比较

  • Comparable 接口的方式一旦一定,保证接口实现类的对象安在任何位置都可以比较大小
  • Comparator 属于临时(挽救)性的比较。

猜你喜欢

转载自blog.csdn.net/qq_40463117/article/details/113547599
今日推荐