簡體   English   中英

Arrays.compare 的自定義比較器。 Generics

[英]Custom comparator for Arrays.compare. Generics

在下面,您會發現內部 class ArrayComparator是 Object arrays 的簡化自定義比較器,運行代碼時您將看到它的工作原理。

現在我想在方法Arrays.compare(T[] a, T[] b, Comparator<? super T> cmp)中使用這個比較器,並為此目的在ArrayComparator2中修改比較器。 下面給出的代碼可以很好地編譯,但是如果您刪除 main 方法中三行的注釋斜線,編譯器將找不到合適的方法進行 compare 如何解決這個問題?

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用於比較數組元素,而不是 arrays 本身。 換句話說,您應該提供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()方法確實將 arrays 作為自定義比較器的輸入,但它將 arrays 的值(直到較小數組的長度)與您提供的比較器進行比較。 只看實現:

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

因此,您應該將 class 簽名更改為:

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

並將比較器 class 實例化為:

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

或者

只需使用 customComparator.compare() 進行所需的數組元素檢查和其他操作。

ArrayComparator2.compare(o1,o2);

沒有辦法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM