使用 Java 8 流进行动态排序?

tom*_*ato 5 java java-stream

长话短说,我正在使用 JDBI DAO 来访问数据。很难进行具有动态顺序的查询。因此,我计划使用 Java 8 流来执行此操作,作为获取查询结果后的后处理步骤。

问题在于比较器的工作方式是必须静态声明对象的方法。

shepherds = shepherds.stream()
    .sorted(Comparator.comparing(Shepherd::getId).reversed())
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

我怎样才能用这样的变量动态地做到这一点

orderBy = id
orderDirection = ASC
Run Code Online (Sandbox Code Playgroud)

这样我就可以参数化这个方法调用?

例如

if(orderDirection.equals("ASC"))
    shepherds.stream().sorted(Comparator.comparing(orderBy));
else
    shepherds.stream().sorted(Comparator.comparing(orderBy).reversed());
Run Code Online (Sandbox Code Playgroud)

Eug*_*ene 3

最简单的方法可能是构建一个Map(除非你真的不能在数据库端这样做,这应该是你的主要关注点),其中Key看起来像:

class Key {
    String field;
    Direction direction; // enum
    // getters/setters/hashcode/equals
}
Run Code Online (Sandbox Code Playgroud)

并简单地Map预先创建这个:

Map<Key, Comparator<Shepherd>> map = new HashMap<>();
map.put(new Key("id", Direction.ASC), Comparator.comparing(Shepard::getId))
map.put(new Key("id", Direction.DESC), Comparator.comparing(Shepard::getId).reversed())
Run Code Online (Sandbox Code Playgroud)

另一方面,我认为可以通过真正LambdaMetafactory动态地创建它,但它相当复杂。

  • 您可以简单地使用 Array.asList("id", Direction.ASC) 等,而不是 `Key` 类,甚至更好,当您使用Java 9。 (2认同)