在 java 中,如何对发送给我的 Field 变量的通用 class T 进行排序

In java, how do I sort a generic class T on a Field variable sent to me

// this function can be called if the objects sent is Comparable (they have
// already chosen the field and how it compares)
public void mySort(Object [] obj) {
     Arrays.sort(obj, null);     // this sorts based on compareTo() 
                                 // method of comparable object
}

我的问题是需要如何更改以下函数才能按 Field 字段对数组进行排序。我已经尝试了许多不同的实现方式,只是将代码放在下面,代表我正在尝试做的事情。

// this function should be used to sort a generic array of T objects, to be
// compared on the Field field
public static <T> void mySort2(T [] obj, Field field) {
    Collections.sort(obj, new Comparator<T>(){
          public int compare(T obj1, T obj2)
          {
             return obj1.field.compareTo(obj2.field); // this does not work
                             //  since I need to the name of the field and
                             //  not a variable, however I do not know what
                             //  T will be when it is sent to me
          }
      });
}

您需要使用Field::get 来反射访问该字段。之后,您需要转换为 Comparable.

您真的需要传递一个 Field 实例并以反射方式查找该字段吗?作为一种可能的替代方案(可能性能更高,具体取决于您的 JVM 实现),您可以传递 lambda 或方法引用来访问该字段:

public static <T, U extends Comparable<? super U>> void mySort(
    T[] array,
    Function<T, U> func) {
  Arrays.sort(array, (a, b) -> func.apply(a).compareTo(func.apply(b));
}

你会这样称呼:

Foo[] foos = ...
mySort(foos, Foo::getMyField);    

如果你坚持 Java 7,你可以做同样的事情,但它有点冗长:

public interface Function<I, O> {
  O apply(I input);
}

public static <T, U extends Comparable<? super U>> void mySort(
    T[] array,
    final Function<T, U> func) {
  Arrays.sort(array,
      new Comparator<T>() {
        @Override public int compareTo(T a, T b) {
          return func.apply(a).compareTo(func.apply(b));
        }
      });
}

你会这样称呼:

Foo[] foos = ...
mySort(foos,
    new Function<Foo, Integer>() {
      @Override public Integer apply(Foo foo) {
        return foo.getMyField();
      }
    });

你问的是如何用Field做,已经给了答案。如果出于某种原因这是一个严格的要求,那么我的回答是没有意义的,但如果不是,这是一种更好的方法,无需反思。

首先,快速提及,而不是 T[] obj,它需要 List<T> obj

现在进行其余更改,

  1. 该方法的类型参数是 <T>,我已将其更改为 <T, F extends Comparable<F>>F 代表 "field"。 F 需要与自身相比较,这就是为什么它需要 Comparable<F>.
  2. 您需要一种从 T 获取 F 的方法。所以你给一个Function<T, F>,我将在下面举一个例子。
  3. 比较方法需要return getter.apply(obj1).compareTo(getter.apply(obj2)).

这是你的成品

public static <T, F extends Comparable<F>> void mySort2(List<T> obj, final Function<T, F> getter) {
    Collections.sort(obj, new Comparator<T>() {
        public int compare(T obj1, T obj2) {
            return getter.apply(obj1).compareTo(getter.apply(obj2));
        }
    });
}

下面是调用它来按长度对字符串进行排序的示例。

List<String> list = getSomeListOfStringsSomehow();
mySort2(list, (String s) -> g.length());