java-在未知值之前对具有已知值的列表进行排序

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

>已知值应在未知值之前排序.
>已知值应通过单独定义的键排序.
>未知值应按其自然顺序进行排序.

我有(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);

产生:

[red, green, blue, orange, yellow, indigo, violet]

但是最后四个按其原始顺序排列,而我希望它们按其自然顺序排序:

[red, green, blue, indigo, orange, violet, yellow]

我唯一想到的就是编写自己的自定义函数,该函数会在地图中查找内容,并将地图结果添加到原始值,如果找不到地图,则使用地图大小-例如它会返回:

"1-red", "4-orange", "4-yellow", "2-green", "3-blue", "4-indigo", "4-violet"

但这仅在映射值是整数且要求数字格式在“ 10”等之前将“ 02”排序的情况下有效.

任何人都有更好的方法来实现这一目标?

解决方法:

这是Guava版本(当您使用Java 7或更低版​​本时):

Ordering<String> ordering = Ordering.natural().nullsLast()
        .onResultOf(Functions.forMap(map, null))
        .compound(Ordering.natural());

这是使用纯Comparator的非Guava版本(在JDK 8上):

Comparator<String> comparator = Comparator
        .<String, Integer>comparing(map::get, Comparator.nullsLast(Comparator.naturalOrder()))
        .thenComparing(Comparator.naturalOrder());

PS.如您所见,使用Guava API的类型推断更好(不需要指定显式类型参数).

上一篇:java-使用Collections.sort()对ArrayList进行复杂排序?


下一篇:Java排序如何工作?