我想对以下示例列表进行排序,该列表当前仅包含具有自己的自定义规则的字符串。
ArrayList<String> coll = new ArrayList<>();
coll.add("just");
coll.add("sdsd");
coll.add("asb");
coll.add("b as");
coll.add("just");
coll.add("dhfga");
coll.add("jusht");
coll.add("ktsa");
coll.add("just");
coll.add("just");
我知道我可以为此编写自己的比较器,但是我知道Java也有比较器可以解决这个问题,我想知道如何使用Java API 组合的那些强大的>有我自己的。
单词just
应该始终是列表中出现的第一个单词,后面是按字母顺序排列的所有其他单词。
Comparator.naturalOrder()
按字母顺序对列表进行排序,但是如何将这个comperator与自定义的comperator结合起来,以检查单词是just
还是其他。
答案 0 :(得分:6)
你可以这样做:
coll.sort(Comparator
.comparingInt((String s) -> s.equals("just") ? 0 : 1) // Words "just" first
.thenComparing(Comparator.naturalOrder())); // Then others
答案 1 :(得分:2)
您可以将标准集成到比较器中,如
coll.sort(Comparator.comparing((String s) -> !s.equals("just"))
.thenComparing(Comparator.naturalOrder()));
或者您将操作分开,首先将所有出现的"just"
移到前面,然后仅对其余元素进行排序:
int howManyJust = 0;
for(int ix = 0, num = coll.size(); ix < num; ix++)
if(coll.get(ix).equals("just") && ++howManyJust <= ix)
Collections.swap(coll, ix, howManyJust-1);
coll.subList(howManyJust, coll.size()).sort(Comparator.naturalOrder());
虽然这可能看起来更复杂,但它可能更有效,特别是对于较大的列表。
答案 2 :(得分:0)
第一步应该是定义自定义订单。我会通过使用Map来做到这一点。
Map<String, Integer> orderMap = new HashMap<>();
int order = 0;
for(String specialWord : yourListOfSpecialWords){
orderMap.put(specialWord, order++);
}
现在使用该地图和自然顺序构建比较器作为备份:
Comparator<String> comparator = ((Comparator<String>) (o1, o2) -> {
int leftScore = orderMap.getOrDefault(o1, Integer.MAX_VALUE);
int rightScore = orderMap.getOrDefault(o2, Integer.MAX_VALUE);
return Integer.compare(leftScore, rightScore);
}).thenComparing(String::compareTo);
使用此比较器对列表进行排序。注意:您可能只想将地图初始化一次,并将其保持在常量或至少在缓存中。
但是如果你的特殊情况只是一个单词,正如你的更新所暗示的那样,那么这当然是矫枉过正的,你应该在这里找到其中一个答案。