版权声明:本文为博主原创文章,转载请注明出处:https://twocups.cn/index.php/2020/02/05/18/

有时我们需要对同一类型的对象进行多种不同方式的排序,而自然排序 Comparable 并不能实现。这里我们就需要重写比较器,可以让对象数组或集合以自定义的排序规则进行排序。

示例

给定一组非负整数,重新排列它们的顺序使之组成一个最大的整数。例如 [10, 2] 的输出为210,[3, 30, 34, 5, 9] 的输出为9534330。

这道题解法的关键就是排序,具体的规则为:数组中的非负整数(例如 xy)两两进行比较,若x + y > y + x,则判定 x 的优先级比 y 高,且 x 在最终的整数里排在 y 的前面。

代码

import java.util.Arrays;
import java.util.Comparator;

class Test{
    public String largestNumber(int[] nums) {
        Integer[] arr = new Integer[nums.length];
        for(int i = 0; i < nums.length; i++) arr[i] = nums[i];
        Arrays.sort(arr, new Comparator<Integer>(){
            @Override
            public int compare(Integer o1, Integer o2){
                String s1 = o1 + "" + o2;
                String s2 = o2 + "" + o1;
                return s2.compareTo(s1);
            }
        });
        StringBuffer sb = new StringBuffer();
        for(int x: arr) sb.append(x);
        String res = sb.toString();
        return res.charAt(0) == '0' ? "0" : res;
    }
}

代码中我们使用了数组的排序方法 sort(),并且重写了一个比较器 Comparator 来定义数组中元素在排序时两两之间的比较规则。如果是集合,同样也可以使用 Collections 的排序方法 sort()。有些人在使用这个方法的时候会遇到如下问题:

英文版:
Error: java: no suitable method found for sort(char[],<anonymous java.util.Comparator<java.lang.Character>>)
    method java.util.Arrays.<T>sort(T[],java.util.Comparator<? super T>) is not applicable
      (inference variable T has incompatible bounds
        equality constraints: char
        upper bounds: java.lang.Character,java.lang.Object)
    method java.util.Arrays.<T>sort(T[],int,int,java.util.Comparator<? super T>) is not applicable
      (cannot infer type-variable(s) T
        (actual and formal argument lists differ in length))
中文版:
Error: java: 对于sort(char[],<匿名java.util.Comparator<java.lang.Character>>), 找不到合适的方法
    方法 java.util.Arrays.<T>sort(T[],java.util.Comparator<? super T>)不适用
      (推论变量 T 具有不兼容的限制范围
        等式约束条件: char
        上限: java.lang.Character,java.lang.Object)
    方法 java.util.Arrays.<T>sort(T[],int,int,java.util.Comparator<? super T>)不适用
      (无法推断类型变量 T
        (实际参数列表和形式参数列表长度不同))

原因是 public static void sort (T [] a,Comparator c) 是根据指定比较器引发的顺序对指定的对象数组进行排序,所以 sort() 方法的第一个参数 T [] a 中只能存放对象,而不能存放基本数据类的数据。如果将 char 类型的数组传入该方法,则会报出以上错误;如果传入的是 Character 类型的数组,则正常。

这里可能有人要问了,char 类型的数据和 Character 类型的数据不是会自动装箱和封箱吗,那为什么这里两者的数组不能通用呢?

通用不代表混用。char 在 Java 中属于八大基本数据类型,不需要实例化就能直接使用;而 Character 是 char 的封装类,需要实例化后才能用。一般来说,char 类型的数据和 Character 类型的数据会动态地进行自动封箱和装箱,来满足不同的需求,但是 char 类型的数组和 Character 类型的数组并不会自动转换啊,它们的本质是数组,只是存放了两种类型的数据而已。

所以如果之前得到的是 char 类型的数组,需要我们自己新建其封装类数组,并将 char 数组的元素全部装入其封装类数组中(这里将元素装入时才会自动封箱)。

其实,在特殊情况下还有更加方便的写法,我举两个例子。

// 将排序的参照要素从数组中的元素变成该元素的某个部分
int[] nums = new int[]{{2, 5}, {3, 7}, {1, 5}, {9, 1}};
Arrays.sort(nums , Comparator.comparingInt(a -> a[0]));
// 改变排序所依照的两个元素的比较方式
String[] strs = new String[]{"aaa", "bbb"};
Arrays.sort(strs , (x, y) -> y.compareTo(x));

// 优先队列:由原来的升序排序,到现在的根据元素的time属性降序排序
PriorityQueue<Integer> priorityQueue = new PriorityQueue<>((a, b) -> (b.time - a.time));

林皓伟

《【Java】重写比较器java.util.Comparator的注意事项》有 9 条评论
  1. Hi there! Do you know if they make any plugins to help with SEO?
    I’m trying to get my blog to rank for some targeted
    keywords but I’m not seeing very good gains. If you
    know of any please share. Kudos! You can read similar art here:
    Najlepszy sklep

  2. Good day! Do you know if they make any plugins to assist with Search Engine Optimization? I’m trying to get my blog to rank for some targeted keywords but I’m not seeing very good success.
    If you know of any please share. Appreciate it! You can read similar text here:
    Sklep online

  3. Hey there! Do you know if they make any plugins to help with SEO?
    I’m trying to get my blog to rank for some targeted keywords but I’m not seeing very good results.
    If you know of any please share. Appreciate it!
    You can read similar blog here: Sklep online

  4. Howdy! Do you know if they make any plugins to help with Search Engine Optimization? I’m trying to get my blog to rank for some targeted keywords but I’m not seeing very good gains.

    If you know of any please share. Kudos! You can read similar text here: Sklep internetowy

发表回复

您的电子邮箱地址不会被公开。