Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用comparator和crieria从使用Java8的map进行排序 让我们考虑一个java类父< /C> > 20个属性(ATTRB1、ATTRB2.. ATTRB20)及其相应的吸气剂和设置器。_Java_Java 8_Comparator - Fatal编程技术网

使用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()
(如果您不需要键a
LinkedHashSet
可能就足够了),从那里您可以按照您想要链接的顺序插入比较器

那么你是在寻求降价。您遍历条目集的值,然后通过减少它们来链接比较器:

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));