Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/397.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 在未知值之前使用已知值对列表进行排序_Java_Guava_Java 7_Comparator - Fatal编程技术网

Java 在未知值之前使用已知值对列表进行排序

Java 在未知值之前使用已知值对列表进行排序,java,guava,java-7,comparator,Java,Guava,Java 7,Comparator,我尝试使用以下规则对列表进行排序: 已知值应在未知值之前排序 已知值应按单独定义的键排序 未知值应按其自然顺序排序 我有(1)和(2),只是在混音中加入(3)很困难 到目前为止,我有: List<String> values = Arrays.asList( "red", "orange", "yellow", "green", "blue", "indigo", "violet"); ImmutableMap<String, Integer> map = Im

我尝试使用以下规则对列表进行排序:

  • 已知值应在未知值之前排序
  • 已知值应按单独定义的键排序
  • 未知值应按其自然顺序排序
  • 我有(1)和(2),只是在混音中加入(3)很困难

    到目前为止,我有:

    List<String> values = Arrays.asList(
        "red", "orange", "yellow", "green", "blue", "indigo", "violet");
    
    ImmutableMap<String, Integer> map = ImmutableMap.of("red", 1, "green", 2, "blue", 3);
    
    Ordering<String> order = Ordering.natural()
        .nullsLast()
        .onResultOf(Functions.forMap(map, null));
    
    Collections.sort(values, order);
    
    System.out.println(values);
    
    但最后4个是按原始顺序排列的,而我希望它们按自然顺序排列:

    [red, green, blue, indigo, orange, violet, yellow]
    
    我能想到的唯一一件事就是编写自己的自定义函数,该函数在地图中查找并将地图结果预先设置为原始值,如果未找到,则使用地图大小-例如,它将返回:

    "1-red", "4-orange", "4-yellow", "2-green", "3-blue", "4-indigo", "4-violet"
    
    但这仅适用于映射值为整数的情况,并且要求数字格式将“02”排在“10”之前,以此类推

    有谁有更好的方法来实现这一点吗?

    这是番石榴的版本(当您使用Java 7或更低版本时):


    如您所见,GuavaAPI的类型推断更好(无需指定显式类型参数)。

    我认为这个解决方案应该可以解决您的问题。很抱歉我使用了
    ArrayList
    s-我在Java8API中找不到任何与
    ImmutableMap
    对应的文档。我还假设自然顺序意味着ASCII顺序。希望这有帮助:)

    //要排序的值
    ArrayList值=新的ArrayList();
    添加(“红色”);
    添加(“橙色”);
    添加(“橙色”);
    添加(“黄色”);
    添加(“绿色”);
    添加(“蓝色”);
    添加(“靛蓝”);
    添加(“紫色”);
    增加(1)//我添加了1来验证输出
    //包含已知值顺序的列表
    ArrayList knownOrder=新的ArrayList();
    knownOrder.添加(“红色”);
    增加(1);
    添加(“绿色”);
    knownOrder.添加(“蓝色”);
    增加(3);
    ArrayList knownValues=新的ArrayList();
    ArrayList unknownValues=新的ArrayList();
    用于(对象值:值){
    if(knownOrder.contains(value)){
    增加(价值);
    }否则{
    未知值。添加(值);
    }
    }
    //按所需顺序对已知值进行排序
    Collections.sort(knownvalue,(m1,m2)->knownOrder.indexOf(m1)-knownOrder.indexOf(m2));
    //按自然顺序对未知值排序
    Collections.sort(未知值,(m1,m2)->m1.toString().charAt(0)-m2.toString().charAt(0));
    //将已知值和未知值合并到一个ArrayList中
    已知值。addAll(未知值);
    System.out.println(已知值);
    //印刷品[红色、1、绿色、蓝色、靛蓝、橙色、橙色、紫色、黄色]
    

    我还应该提到:此解决方案不适用于字符串和基本包装之外的对象。

    我建议您将示例值更改为“红色”、“绿色”和“蓝色”未排序的顺序(例如,
    “红色”、“橙色”、“黄色”、“蓝色”、“绿色”、“靛蓝”、“紫色”
    )。否则,很难验证解决方案是否满足条件2.或
    Comparator.comparingInt((字符串s)->map.getOrDefault(s,Integer.MAX_值))。然后进行比较(Comparator.naturalOrder())
    ,假设
    Integer.MAX_值
    从未作为映射值出现。
    "1-red", "4-orange", "4-yellow", "2-green", "3-blue", "4-indigo", "4-violet"
    
    Ordering<String> ordering = Ordering.natural().nullsLast()
            .onResultOf(Functions.forMap(map, null))
            .compound(Ordering.natural());
    
    Comparator<String> comparator = Comparator
            .<String, Integer>comparing(map::get, Comparator.nullsLast(Comparator.naturalOrder()))
            .thenComparing(Comparator.naturalOrder());
    
        //Values to be sorted
        ArrayList<Object> values = new ArrayList<>();
    
        values.add("red");
        values.add("orange");
        values.add("orange");
        values.add("yellow");
        values.add("green");
        values.add("blue");
        values.add("indigo");
        values.add("violet");
        values.add(1);    //I added 1 to verify output
    
        //List containing order of known values
        ArrayList<Object> knownOrder = new ArrayList<>();
    
        knownOrder.add("red");
        knownOrder.add(1);
        knownOrder.add("green");
        knownOrder.add("blue");
        knownOrder.add(3);
    
        ArrayList<Object> knownValues = new ArrayList<>();
        ArrayList<Object> unknownValues = new ArrayList<>();
    
        for (Object value: values) {
            if (knownOrder.contains(value)) {
                knownValues.add(value);
            }else {
                unknownValues.add(value);
            }
        }
    
        //Sort known values in required order
        Collections.sort(knownValues, (m1, m2)->knownOrder.indexOf(m1)-knownOrder.indexOf(m2));
    
        //Sort unknown values in natural order
        Collections.sort(unknownValues, (m1, m2)->m1.toString().charAt(0)-m2.toString().charAt(0));
    
        //Combine the known and unknown values into one ArrayList
        knownValues.addAll(unknownValues);
    
        System.out.println(knownValues);
        //Prints [red, 1, green, blue, indigo, orange, orange, violet, yellow]