简体   繁体   English

Arrays.compare 的自定义比较器。 Generics

[英]Custom comparator for Arrays.compare. Generics

below you find with the inner class ArrayComparator a simplified custom comparator for Object arrays, which works as you will see when running the code.在下面,您会发现内部 class ArrayComparator是 Object arrays 的简化自定义比较器,运行代码时您将看到它的工作原理。

Now I would like to use this comparator in method Arrays.compare(T[] a, T[] b, Comparator<? super T> cmp) , and modified the comparator for this purpose in ArrayComparator2 .现在我想在方法Arrays.compare(T[] a, T[] b, Comparator<? super T> cmp)中使用这个比较器,并为此目的在ArrayComparator2中修改比较器。 The code as given below compiles nicely, but if you remove the comment slashes of the three lines in the main method, the compiler finds no suitable method for compare .下面给出的代码可以很好地编译,但是如果您删除 main 方法中三行的注释斜线,编译器将找不到合适的方法进行 compare How to fix this?如何解决这个问题?

import java.awt.*;
import java.util.*;

public class CompareTest {

  static Object[] o1= {new Point(1,2), new Point(3,4), new Point(5,6)};
  static Object[] o2= {new Point(1,2), new Point(3,4), new Point(5,6)};

  public static void main(String args[]) {
    if (args.length>0) {
      if (args[0].equals("1"))
        ((Point)o2[2]).y= 7;
      else
        ((Point)o1[2]).y= 7;
    }
    for (int i=0; i<o1.length; i++) {
      System.out.println(o1[i]+", "+o2[i]);
    }
    ArrayComparator comparator= new ArrayComparator();
    int result= comparator.compare(o1, o2);
    System.out.println("Result: "+result);

//    ArrayComparator2<Object[]> comparator2= new ArrayComparator2<>();
//    result= Arrays.compare(o1, o2, comparator2);
//    System.out.println("Result: "+result);

    System.exit(0);
  }


  static class ArrayComparator implements Comparator<Object[]> {
    public int compare(Object[] o1, Object[] o2) {
      int l= o1.length;
      if (l!=o2.length) {
        return l>o2.length ? 1 : -1;
      }
      for (int i=0; i<l; i++) {
        int j= (o1[i].toString()).compareTo(o2[i].toString());
        if (j!=0) return j;
      }
      return 0;
    }
  }


  static class ArrayComparator2<T> implements Comparator<T[]> {
    public int compare(T[] o1, T[] o2) {
      int l= o1.length;
      if (l!=o2.length) {
        return l>o2.length ? 1 : -1;
      }
      for (int i=0; i<l; i++) {
        int j= (o1[i].toString()).compareTo(o2[i].toString());
        if (j!=0) return j;
      }
      return 0;
    }
  }


/* No solution either:
  static class ArrayComparator2<Object> implements Comparator<Object[]> {
    public int compare(Object[] o1, Object[] o2) {
      int l= o1.length;
      if (l!=o2.length) {
        return l>o2.length ? 1 : -1;
      }
      for (int i=0; i<l; i++) {
        int j= (o1[i].toString()).compareTo(o2[i].toString());
        if (j!=0) return j;
      }
      return 0;
    }
  }
*/

}

From the method signature of Arrays.compare , it can be seen that the Comparator is used for comparing the array elements, not the arrays themselves.Arrays.compare的方法签名可以看出Comparator用于比较数组元素,而不是 arrays 本身。 In other words, you should provide a Comparator<T> , not a Comparator<T[]> .换句话说,您应该提供Comparator<T> ,而不是Comparator<T[]>

static class ArrayComparator2<T> implements Comparator<T> {
    public int compare(T o1, T o2) {
        return o1.toString().compareTo(o2.toString());
    }
}
// ...
ArrayComparator2<Object> comparator2= new ArrayComparator2<>();
result= Arrays.compare(o1, o2, comparator2);
System.out.println("Result: "+result);

The Arrays.compare() method does take the arrays as input with a custom comparator, but it compares the values of the arrays (upto the length of the smaller array) with the comparator you've provided. Arrays.compare()方法确实将 arrays 作为自定义比较器的输入,但它将 arrays 的值(直到较小数组的长度)与您提供的比较器进行比较。 Just look at the implementation:只看实现:

public static <T> int compare(T[] a, T[] b, Comparator<? super T> cmp) {
    Objects.requireNonNull(cmp);
    if (a == b) {
        return 0;
    } else if (a != null && b != null) {
        int length = Math.min(a.length, b.length);

        for(int i = 0; i < length; ++i) {
            T oa = a[i];
            T ob = b[i];
            if (oa != ob) {
                int v = cmp.compare(oa, ob);
                if (v != 0) {
                    return v;
                }
            }
        }

        return a.length - b.length;
    } else {
        return a == null ? -1 : 1;
    }
}

So, either you should change the class signature to:因此,您应该将 class 签名更改为:

static class ArrayComparator2<T> implements Comparator<T> {
    public int compare(T o1, T o2) {
        return o1.toString().compareTo(o2.toString());
    }
}

And instantiate the comparator class as:并将比较器 class 实例化为:

ArrayComparator2<Object> comparator2= new ArrayComparator2<>();

OR或者

JUST USE THE customComparator.compare() for your desired array element check and other stuffs.只需使用 customComparator.compare() 进行所需的数组元素检查和其他操作。

ArrayComparator2.compare(o1,o2);

There's no way around.没有办法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM