使用comparator和crieria从使用Java8的map进行排序 让我们考虑一个java类父< /C> > 20个属性(ATTRB1、ATTRB2.. ATTRB20)及其相应的吸气剂和设置器。
使用comparator和crieria从使用Java8的map进行排序 让我们考虑一个java类父< /C> > 20个属性(ATTRB1、ATTRB2.. ATTRB20)及其相应的吸气剂和设置器。,java,java-8,comparator,Java,Java 8,Comparator,列表列表包含n个父对象对象 现在我想根据多个条件对这个列表进行排序。我将使用comparator接口来构建排序标准 排序排列被存储为映射 Map< AttributeName, Ascending/Decending> Map 所以我想迭代每个键的map和bulid比较器接口 我们如何迭代映射并为每个键构建比较器接口,然后连接这些比较器接口 我接受纯java 8代码来解决这个问题。首先,我假设您的父类具有get方法,该方法可以通过名称提供属性。它可以使用反射来实现: public
列表
列表包含n个父对象
对象
现在我想根据多个条件对这个列表进行排序。我将使用comparator接口来构建排序标准
排序排列被存储为映射
Map< AttributeName, Ascending/Decending>
Map
所以我想迭代每个键的map和bulid比较器接口
我们如何迭代映射并为每个键构建比较器接口,然后连接这些比较器接口
我接受纯java 8代码来解决这个问题。首先,我假设您的
父类具有get
方法,该方法可以通过名称提供属性。它可以使用反射来实现:
public class Parent {
public Object get(String fieldName) {
try {
return getClass()
.getMethod(
"get"+Character.toTitleCase(fieldName.charAt(0))+fieldName.substring(1))
.invoke(this);
} catch(IllegalAccessException | InvocationTargetException |
NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
}
或者可能使用EJB内省或其他适合您的机制
因此,我们可以定义以下方法:
@SuppressWarnings({ "unchecked", "rawtypes" })
static Comparator<Parent> getComparator(Map<String, Boolean> sortOrder) {
return sortOrder.entrySet().stream()
.map(entry -> entry.getValue() ?
Comparator.comparing(
(Parent parent) -> (Comparable)parent.get(entry.getKey())) :
Comparator.comparing(
(Parent parent) -> (Comparable)parent.get(entry.getKey())).reversed())
.reduce((a, b) -> a.thenComparing(b))
.orElse((a, b) -> 0);
}
除非使用反射,否则不可能实现这一点。此外,如果您不使用LinkedHashMap
,或者属性的名称没有按照字典或其他定义的顺序进行链接,以确保您按照正确的顺序进行链接,则无法检索要首先链接的属性
老实说,使用反射进行此操作更像是一种黑客行为。我认为你可以改进你的设计
我建议创建一个LinkedHashMap=newHashMap()
(如果您不需要键aLinkedHashSet
可能就足够了),从那里您可以按照您想要链接的顺序插入比较器
那么你是在寻求降价。您遍历条目集的值,然后通过减少它们来链接比较器:
Comparator<Parent> cmp = map.entrySet()
.stream()
.map(Map.Entry::getValue)
.reduce(Comparator::thenComparing)
.get(); //check also orElse, orElseThrow, etc.
因此,这种映射的一个例子可能是
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));
Map Map=newhashmap();
put(“id”,新的SimpleEntry(Comparator.comparingInt(Parent::getId),true));
put(“name”,新的SimpleEntry(Comparator.comparing(Parent::getName),false));
也许可以向我们展示您迄今为止所做的尝试?comparatorbyfirst=(e1,e2)->e2.getAttrib2().compareTo(e1.getAttrib2());比较器秒=(e1,e2)->e2.getAttrib12().compareTo(e1.getAttrib12());比较器结果=byFirst.然后比较(bySecond);Collections.sort(参数列表、结果)代码>试着把这个放在你的问题中,并解释什么不起作用
...
.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));