我正在尝试通过定义一些前缀,根据自定义排序顺序对字符串列表进行排序。结果应基于前缀的顺序进行排序,并且不匹配的条目应位于列表的末尾。当多个字符串以相同的前缀开头,或者在其余的多个条目中,则应按字母顺序排序。
已经尝试了基于来自另一个线程How to sort a java list against a custom order的解决方案的自定义比较器。但是我现在被困在要求的最后一部分,以便将列表末尾没有前缀的其余条目带入。
final Comparator<String> comparator = new PrefixComparator(Arrays.asList("java.", "javax.", "org."));
final ArrayList<String> imports = Lists.newArrayList("java.util.Arrays", "javax.annotation.Generated", "org.testng.annotations.Test", "org.testng.annotations.Optional", "de.bigmichi1.test.ClassB");
Collections.shuffle(imports);
imports.sort(comparator);
Assertions.assertThat(imports).containsExactly("java.util.Arrays", "javax.annotation.Generated", "org.testng.annotations.Optional","org.testng.annotations.Test", "de.bigmichi1.test.ClassB");
public class PrefixComparator implements Comparator<String>, Serializable {
private static final long serialVersionUID = -5748758614646881440L;
private final List<String> customOrder;
public PrefixComparator(@Nonnull final List<String> customOrder) {
this.customOrder = customOrder;
}
@Override
public int compare(final String o1,
final String o2) {
int order1 = -1;
int order2 = -1;
String remainder1 = "";
String remainder2 = "";
for (final String prefix : customOrder) {
if (o1.startsWith(prefix)) {
order1 = customOrder.indexOf(prefix);
remainder1 = o1.substring(prefix.length());
}
if (o2.startsWith(prefix)) {
order2 = customOrder.indexOf(prefix);
remainder2 = o2.substring(prefix.length());
}
}
if (order1 == order2) {
return remainder1.compareTo(remainder2);
} else {
return order1 - order2;
}
}
}
答案 0 :(得分:2)
这是我要怎么做:
import java.util.*;
public class Test
{
public static void main(String[] args) {
List<String> prefix = Arrays.asList("java.", "javax.", "org.");
List<String> imports = Arrays.asList("org.testng.annotations.Test", "java.util.Arrays", "javax.annotation.Generated", "org.testng.annotations.Optional", "de.bigmichi1.test.ClassB");
Collections.sort(imports, new Comparator<String>(){
int prefix1Index = Integer.MAX_VALUE, prefix2Index = Integer.MAX_VALUE;
@Override
public int compare(String o1, String o2) {
prefix1Index = Integer.MAX_VALUE;
prefix2Index = Integer.MAX_VALUE;
prefix.forEach((pre) -> {
if(o1.startsWith(pre)){
prefix1Index = prefix.indexOf(pre);
}
if(o2.startsWith(pre)){
prefix2Index = prefix.indexOf(pre);
}
});
if(prefix1Index == prefix2Index) return o1.compareTo(o2);
else return prefix1Index - prefix2Index;
}
});
imports.forEach((imported) -> {
System.out.println(imported);
});
}
}
以下是输出:
java.util.Arrays
javax.annotation.Generated
org.testng.annotations.Optional
org.testng.annotations.Test
de.bigmichi1.test.ClassB