使用java 8从map中使用比较器和crieria进行排序

让我们考虑一个具有20个属性的
java类Parent(attrib1,attrib2 .. attrib20)及其相应的getter和setter.

列表与LT;家长和GT; list包含n个Parent对象.

现在我想根据多个标准对此列表进行排序.我将使用比较器接口来构建排序标准.

排序arrtibute存储为映射.

Map< AttributeName, Ascending/Decending>

所以我想为每个键迭代map和bulid比较器接口.

我们如何迭代map并为每个键构建比较器接口,然后连接这些比较器接口.

我接受纯java 8代码来解决这个问题.

最佳答案 除非你使用反射,否则不可能实现这一点.此外,如果您不使用LinkedHashMap或者属性的名称没有按字典或其他定义的顺序链接,以确保您以正确的顺序链接它们,那么将无法检索您想要的那个链首先.

说实话,使用反射似乎更像是一个黑客.我认为你可以改进你的设计.

我建议创建一个LinkedHashMap< String,Comparator< Parent>> map = new HashMap<>();(如果你不需要一个LinkedHashSet就足够了),你可以从那里按照你想要链接它们的顺序插入比较器.

然后你正在寻找减少.迭代条目集的值,然后通过减少它们来链接比较器:

Comparator<Parent> cmp = map.entrySet()
                            .stream()
                            .map(Map.Entry::getValue)
                            .reduce(Comparator::thenComparing)
                            .get(); //check also orElse, orElseThrow, etc.

如果您的Map不是LinkedHashMap,但可以比较键以获得所需的链,则可以使用.sorted(Map.Entry.comparingByKey())对流进行排序.

您可以拥有Map< String,SimpleEntry< Comparator< Parent&gt ;, Boolean>>如果你想存储逻辑升序/降序,你只需要添加另一个映射操作:

...
.map(Map.Entry::getValue)
.map(e -> e.getValue() ? e.getKey().reversed() : e.getKey())
...

所以这样一个地图的例子可能是

Map<String, SimpleEntry<Comparator<Parent>, Boolean>> map = new HashMap<>();
map.put("id", new SimpleEntry<>(Comparator.comparingInt(Parent::getId), true));
map.put("name", new SimpleEntry<>(Comparator.comparing(Parent::getName), false));
点赞