在 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
。
现在进行其余更改,
- 该方法的类型参数是
<T>
,我已将其更改为 <T, F extends Comparable<F>>
。 F
代表 "field"。 F
需要与自身相比较,这就是为什么它需要 Comparable<F>
.
- 您需要一种从
T
获取 F
的方法。所以你给一个Function<T, F>
,我将在下面举一个例子。
- 比较方法需要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());
// 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
。
现在进行其余更改,
- 该方法的类型参数是
<T>
,我已将其更改为<T, F extends Comparable<F>>
。F
代表 "field"。F
需要与自身相比较,这就是为什么它需要Comparable<F>
. - 您需要一种从
T
获取F
的方法。所以你给一个Function<T, F>
,我将在下面举一个例子。 - 比较方法需要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());