java - 根据给定的前缀对字符串列表进行排序
问题描述
我正在尝试通过定义一些前缀根据自定义排序顺序对字符串列表进行排序。结果应根据前缀的顺序进行排序,并且不匹配的条目应位于列表的末尾。当多个字符串以相同的前缀开头或其余部分有多个条目时,应按字母顺序排序。
已经尝试了基于来自另一个线程的解决方案的自定义比较器如何根据自定义顺序对 java 列表进行排序。但是我现在被困在我要求的最后一部分,即把没有前缀的剩余条目放在列表的末尾。
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;
}
}
}
解决方案
这是我的做法:
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
推荐阅读
- java - 在 @PostConstruct 之后调用 Mockito @Before 方法
- c# - API 控制器查询中间表的存储库模式问题
- database - 使用 Amazon RDS 只读副本时是否可能获得不一致的数据?
- javascript - click 回调根据 var 或 let 丢失上下文
- c++ - 使用 cv::dnn::Layer cv::dnn::LayerFactory 和 cv::dnn::Net 的问题
- java - 由一对多关系引起的休眠堆栈溢出
- visual-studio-code - 片段中的智能感知 (VSCode)
- excel - 如何更正一个公式 tat 有多个返回“#VALUE!”的 IF 语句 当某些单元格未填充时?
- php - PHP - 使用 strpos() 查找包含分号的字符串失败
- php - 如何在 PHP 中验证我的联系表格?我的代码的解决方案