使用可变方法参考的Java 8 Lambda排序

时间:2016-08-18 22:09:53

标签: java lambda java-8 comparator

我有一个声明:

searchResults.sort(Comparator.comparing(WCCTableRowData::getD));

其中getD是WCCTableRowData类中的访问器,searchResults是WCCTableRowData的列表。 WCCTableRowData类具有getA到getZ的访问器。我需要能够从传入的变量中动态设置排序字段。有没有一种优雅的方法可以做到这一点,还是需要一系列if语句或类似的东西?

更新1 不幸的是,尽管我认为方向是正确的,但是接受的答案中的方法都不起作用。通过方法2我得到:

Intelli Sense

使用方法1,row.getField不会在WCCTableRowData类中获取getField方法,并且我得到类似的"不符合上限(#);错误。我认为错误是说WCCTableRowData类必须实现Comparable?

2 个答案:

答案 0 :(得分:3)

一种方法是使用键存储方法引用 - 变量的值。它类似于switch语句。你可以使用guava ImmutableMap.<WCCTableRowData, Comparable<?>>of()来使它更好一些。

<强>更新

您可以明确告诉Comparator.comparing(...)构建的比较器正在比较Comparable

Comparator.<WCCTableRowData, Comparable>comparing(getters.get(name));

此外,你可以存储你的对象的比较器(声音更合理,但添加了样板),而不是返回可比对象的函数:

Map<String, Comparator<WCCTableRowData>> comparators = new HashMap<>();
comparators.put("A", Comparator.comparing(WCCTableRowData::getX));
comparators.put("B", Comparator.comparing(WCCTableRowData::getY));

String name = "C";
searchResults.sort(comparators.get(name)); 

答案 1 :(得分:3)

一种方法是在WCCTableRowData中添加一个可以给出字段名称并返回该字段值的方法。

class WCCTableRowData {
    Comparable<?> getField(String name) { ... }
}

String name = "C";
searchResults.sort(Comparator.comparing(row -> row.getField(name)));

如果您不想修改课程,则可以设置外部地图。

Map<String, Function<WCCTableRowData, Comparable<?>>> getters = new HashMap<>();
getters.put("A", WCCTableRowData::getA);
getters.put("B", WCCTableRowData::getB);
getters.put("C", WCCTableRowData::getC);

String name = "C";
searchResults.sort(Comparator.comparing(getters.get(name)));