尝试在给定字段上为给定类创建比较器时出错



我正试图制作一个函数,在类的字段上重新返回比较器,但当我试图在Comparable v2 = (Comparable) field.get(o2);行获取o2的值时,我遇到了一个错误,说lambda参数无法转换为对象。有人能帮忙吗?

public Comparator comp(String className, String fieldName) throws Exception {
Comparator comparator = Comparator.comparing((o1, o2) -> {
Class aClass = null;
try {
aClass = Class.forName(className);
Field field = aClass.getDeclaredField(fieldName);
field.setAccessible(true);
Comparable v1 = (Comparable) field.get(o1);
Comparable v2 = (Comparable) field.get(o2);
return v1.compareTo(v2);
} catch (Exception e) {
e.printStackTrace();
}
return 0;
});
return comparator;
}

您使用的是Comparator.comparing方法,但您传递的实际上是一个比较器的实现。你可以去掉那个方法调用并使用:

Comparator comparator = (o1, o2) -> {
Class aClass = null;
try {
aClass = Class.forName(className);
Field field = aClass.getDeclaredField(fieldName);
field.setAccessible(true);
Comparable v1 = (Comparable) field.get(o1);
Comparable v2 = (Comparable) field.get(o2);
return v1.compareTo(v2);
} catch (Exception e) {
e.printStackTrace();
}
return 0;
};
return comparator;

或者,您可以继续使用Comparator.comparing方法,但请记住,您应该传入一个提取字段值的函数

public Comparator comp(String className, String fieldName) throws Exception {
Class aClass = Class.forName(className);
Field field = aClass.getDeclaredField(fieldName);
field.setAccessible(true);
Comparator comparator = Comparator.comparing(o1 -> {
try {
Comparable v1 = (Comparable) field.get(o1);
return v1;
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
});
return comparator;
}
Joni的回答正确地指出了代码中的错误。

此外,您不希望在每个compare()调用上执行该方法的反射查找,所以在创建Comparator之前执行该查找。

此外,您的comp()方法应该是static

public static Comparator comp(String className, String fieldName) throws Exception {
Field field = Class.forName(className).getDeclaredField(fieldName);
field.setAccessible(true);
return (o1, o2) -> {
try {
Comparable v1 = (Comparable) field.get(o1);
Comparable v2 = (Comparable) field.get(o2);
return v1.compareTo(v2);
} catch (IllegalAccessException e) {
// Should not happen because of setAccessible(true)
throw new AssertionError("Unexpected error: " + e, e);
}
};
}

如果你想使用Comparator.comparing(...),那么就这样做:

public static Comparator comp(String className, String fieldName) throws Exception {
Field field = Class.forName(className).getDeclaredField(fieldName);
field.setAccessible(true);
return Comparator.comparing(o -> {
try {
return (Comparable) field.get(o);
} catch (IllegalAccessException e) {
// Should not happen because of setAccessible(true)
throw new AssertionError("Unexpected error: " + e, e);
}
});
}

最新更新