Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.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
Java 按可为空字段排序,表示项目';s位置_Java_Spring_Java Stream_Comparator_Comparable - Fatal编程技术网

Java 按可为空字段排序,表示项目';s位置

Java 按可为空字段排序,表示项目';s位置,java,spring,java-stream,comparator,comparable,Java,Spring,Java Stream,Comparator,Comparable,我需要以自定义方式对对象数组进行排序。 假设我的对象中有两个字段-priority(可空)和createdAt(不可空)。 优先级字段表示项目应位于哪个位置。但是,它可以为null。在这种情况下,我们应该考虑createdAt字段(降序)进行排序 让我举例说明。 例如,我的对象是: Object0: priority: null, createdAt: 2018-12-01 Object1: priority: 1, createdAt: 2018-12-02 Object2: prior

我需要以自定义方式对对象数组进行排序。 假设我的对象中有两个字段-
priority
(可空)和
createdAt
(不可空)。 优先级字段表示项目应位于哪个位置。但是,它可以为null。在这种情况下,我们应该考虑createdAt字段(降序)进行排序

让我举例说明。 例如,我的对象是:

Object0: priority: null, createdAt: 2018-12-01
Object1: priority: 1,    createdAt: 2018-12-02
Object2: priority: 5,    createdAt: 2018-12-03
Object3: priority: null, createdAt: 2018-12-04
Object4: priority: null, createdAt: 2018-12-05
Object5: priority: 2,    createdAt: 2018-12-06
Object6: priority: null, createdAt: 2018-12-07
最终订单应为:

  • Object1(按其优先级)
  • 对象5(按其优先级)
  • Object6(通过createdAt desc填充左侧位置)
  • Object4(通过createdAt desc填充左侧位置)
  • Object2(按其优先级)
  • Object3(通过createdAt desc填充左侧位置)
  • Object0(通过createdAt desc填充左侧位置)
  • 我怎样才能实现我的目标?有现成的比较仪吗

    编辑: 我认为我们可以使用该类:

    public class MyObject {
       Integer priority;
       LocalDateTime createdAt;
    }
    

    不,不要使用比较器进行此操作,或者更准确地说,不要对整个作业使用比较器。比较器的工作是比较两个对象并告诉它们之间的顺序。它不适合检测优先级序列中的间隙

    相反,假设优先级是整数且唯一的,我建议您对具有已定义优先级的对象使用数组和基数排序。优先级1进入数组索引1、优先级2索引2等。优先级为
    null
    的对象在创建日期降序时使用比较器进行排序,然后填充到仍然为
    null
    的数组索引中(我想索引0除外)

    “假设优先级是完整的和唯一的”,我的意思是,你不会冒两个优先级为3的对象或优先级为2.44的对象的风险

    我可以使用流和
    收集器.partitioning by
    来分离具有优先级的对象和没有优先级的对象,当然还有其他方法

    我会手工编码的。我从来没有听说过任何现成的解决办法。搜索永远不会有什么害处,但我会惊讶地发现一个。另一方面,不需要太多的代码行


    顺便说一句,对日期使用
    LocalDate
    ,因为它们没有时间(而不是
    LocalDateTime
    )。

    给定所有对象的列表:数组可以根据优先级设置位置:

    List<MyObject> list = new ArrayList<>(Arrays.asList(...));
    MyObject[] res = new MyObject[list.size()];
    
  • 将它们插入阵列的空框中

    int indicList = 0;
    for (int i = 0; i < res.length; i++) {
        if (res[i] == null) {
            res[i] = list.get(indicList++);
        }
    }
    
    int indicilist=0;
    for(int i=0;i

      • 一种可能的方法(对效率不是很确定)是:

        List<CustomObject> customObjectList = new ArrayList<>(); // your initialisation;
        
        // list of only those objects whose priority is null sorted descending by createdAt
        List<CustomObject> nullValues = customObjectList.stream()
                .filter(a -> a.getPriority() == null)
                .sorted(Comparator.comparing(CustomObject::getCreatedAt).reversed())
                .collect(Collectors.toList());
        
        // remaining non null priority objects sorted by priority ascending
        List<CustomObject> remainingValues = customObjectList.stream()
                .filter(a -> a.getPriority() != null)
                .sorted(Comparator.comparing(CustomObject::getPriority))
                .collect(Collectors.toList());
        
        // final list of same size as initial
        List<CustomObject> finalList = new ArrayList<>(customObjectList.size());
        
        // set the priority based indexes first
        remainingValues.forEach(a -> finalList.add(a.getPriority(), a));
        
        // iterate through the final list and fill in the empty slots 
        // while popping(`remove(0)`) the element from list sorted descending by createdAt
        IntStream.range(0, finalList.size())
                .filter(i -> finalList.get(i) == null)
                .forEach(i -> finalList.add(i, nullValues.remove(0)));
        
        List customObjectList=new ArrayList();//你的初始化;
        //仅按createdAt降序排序优先级为空的对象的列表
        List nullValues=customObjectList.stream()
        .filter(a->a.getPriority()==null)
        .sorted(Comparator.comparing(CustomObject::getCreatedAt).reversed())
        .collect(Collectors.toList());
        //按优先级升序排序的剩余非空优先级对象
        List remainingValues=customObjectList.stream()
        .filter(a->a.getPriority()!=null)
        .sorted(Comparator.comparing(CustomObject::getPriority))
        .collect(Collectors.toList());
        //与初始列表大小相同的最终列表
        List finalList=newarraylist(customObjectList.size());
        //首先设置基于优先级的索引
        remainingValues.forEach(a->finalList.add(a.getPriority(),a));
        //遍历最终列表并填充空槽
        //在弹出(`remove(0)`)按createdAt降序排序的列表中的元素时
        IntStream.range(0,finalList.size())
        .filter(i->finalList.get(i)==null)
        .forEach(i->finalList.add(i,nullValues.remove(0));
        
        注意:这里很少有假设 -列表中设置了基于
        0
        的优先级。
        -非空优先级值是
        finalList

        中的精确索引。您能给出与之相关的类吗?老实说,我没有该类。我的情况更复杂,在这里我把它减少到最低限度。我将编辑我的文章,但是提供最小类。为什么object6和object4介于object5和object2之间?您可以轻松地使用自己的比较器lambda进行排序,但我不清楚您的算法。Object5的优先级为2,因此它将进入位置2。Object2的优先级为5,因此它将转到位置5。当所有对象都位于它们的位置时,我们使用按createdAt排序的对象填充数组中的左空格。我希望它现在会更清楚。你不能这样排序,因为你说你需要优先权作为索引,而这不是它的工作方式,你只能比较它们之间的元素,before/after/equalsOk。所以我知道没有比较标准。有道理:)你知道有什么现成的解决办法吗?是的,这就是我的意思。:-)您可能需要考虑到最大优先级可能大于对象数,我不知道,询问者应该知道。正如我所想的那样,
        finalList.set(a.getPriority(),a)
        抛出一个
        java.lang.IndexOutOfBoundsException:Index:1,Size:0
        ,通过
        添加
        更改
        设置
        是否会更改problem@azro好的,没有测试这个,更新为使用
        add
        .f***我的头脑总是忘记“不”。。。大脑太快,手拿不动,“改加不改问题”不知道如何解决it@azro好的,让我用一个更好的测试代码回到这里,如果是这样的话,通常需要对列表进行初始化。
        int indicList = 0;
        for (int i = 0; i < res.length; i++) {
            if (res[i] == null) {
                res[i] = list.get(indicList++);
            }
        }
        
        List<CustomObject> customObjectList = new ArrayList<>(); // your initialisation;
        
        // list of only those objects whose priority is null sorted descending by createdAt
        List<CustomObject> nullValues = customObjectList.stream()
                .filter(a -> a.getPriority() == null)
                .sorted(Comparator.comparing(CustomObject::getCreatedAt).reversed())
                .collect(Collectors.toList());
        
        // remaining non null priority objects sorted by priority ascending
        List<CustomObject> remainingValues = customObjectList.stream()
                .filter(a -> a.getPriority() != null)
                .sorted(Comparator.comparing(CustomObject::getPriority))
                .collect(Collectors.toList());
        
        // final list of same size as initial
        List<CustomObject> finalList = new ArrayList<>(customObjectList.size());
        
        // set the priority based indexes first
        remainingValues.forEach(a -> finalList.add(a.getPriority(), a));
        
        // iterate through the final list and fill in the empty slots 
        // while popping(`remove(0)`) the element from list sorted descending by createdAt
        IntStream.range(0, finalList.size())
                .filter(i -> finalList.get(i) == null)
                .forEach(i -> finalList.add(i, nullValues.remove(0)));