为Arrays.compare定制比较器.泛型



下面的ArrayComparator的简化自定义比较器对象数组,运行代码时将看到它的工作方式。

现在我想在方法Arrays.compare(T[] a, T[] b, comparatorcmp),并为此修改了比较器ArrayComparator2. 下面给出的代码编译得很好,但是如果您删除注释斜杠的三行在main方法中,编译器发现没有适合比较的方法。如何解决这个问题?

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;
}
}
*/
}

Arrays.compare的方法签名可以看出,Comparator是用来比较数组元素的,而不是数组本身。换句话说,您应该提供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);

Arrays.compare()方法确实使用自定义比较器将数组作为输入,但是它将数组的值(不超过较小数组的长度)与您提供的比较器进行比较。看一下实现:

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;
}
}
所以,要么你应该将类签名更改为:

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<>();

只使用customComparator.compare()来检查你想要的数组元素和其他东西。

ArrayComparator2.compare(o1,o2);

别无他法。

最新更新