我有TreeMap
需要根据键进行排序。这是TreeMap
的默认属性。但就我而言,我无法找出比较器。以下是我的代码。
public class Test {
public static void main(String[] args) {
Map<String, String> aMap = new TreeMap<String, String>(new MyComp());
aMap.put("02_file.cql", "test");
aMap.put("01.cql", "test");
aMap.put("04.cql", "test");
aMap.put("3_file.cql", "test");
aMap.put("11_file.cql", "test");
aMap.put("10_file.cql", "test");
aMap.put("0_file.cql", "test");
aMap.put("100_file.cql", "test");
Set<Map.Entry<String,String>> set = aMap.entrySet();
for(Map.Entry<String,String> e : set){
System.out.println(e.getKey() + ":" + e.getValue());
}
}
}
class MyComp implements Comparator<String> {
@Override
public int compare(String str1, String str2) {
return str1.compareTo(str2);
}
}
输出结果如下:
01.cql:test
02_file.cql:test
04.cql:test
0_file.cql:test
100_file.cql:test
10_file.cql:test
11_file.cql:test
3_file.cql:test
这不是我预期的结果。我期待结果如:
0_file.cql:test
01.cql:test
02_file.cql:test
3_file.cql:test
04.cql:test
10_file.cql:test
11_file.cql:test
100_file.cql:test
与NameFileComparator.NAME_COMPARATOR
org.apache.commons.io.comparator.NameFileComparator;
有什么建议吗?
答案 0 :(得分:3)
传递给Comparator
构造函数的TreeMap
以某种方式使compareTo()
字符串做:字典比较。
但你不想进行词典编纂比较
在您的预期中,您只需要进行数字比较
要实现此目的,请移除String
的无数字部分,从中创建两个int
并将int
与Integer.compare(int, int)
进行比较。
class MyComp implements Comparator<String> {
@Override
public int compare(String str1, String str2) {
String notDigit = "[^\\d]";
int int1 = Integer.parseInt(str1.replaceAll(notDigit, ""));
int int2 = Integer.parseInt(str2.replaceAll(notDigit, ""));
return Integer.compare(int1, int2);
}
}
使用此比较器输出:
0_file.cql:测试
01.cql:测试
02_file.cql:测试
3_file.cql:测试
04.cql:测试
10_file.cql:测试
11_file.cql:测试
100_file.cql:测试
答案 1 :(得分:0)
这是因为您将密钥作为字符串进行比较,因此它会比较第一个字符,然后是第二个字符,依此类推。
看起来你想要的是比较每个键开头的整数。
答案 2 :(得分:0)
比较操作似乎没问题。它只是比较字符串值,显然是&#34; _&#34;字符的优先级低于数字。如果您希望代码以数字方式对文件进行排序,则必须将文件名的数字部分存储为单独的int类型密钥。
答案 3 :(得分:0)
如果你想完全与apache commons-io NameFileComparator进行比较,你不是在谈论大量的文件名或对这个方法的并发调用......只需创建一个委托给apache的比较器。
public clas MyComp implements Comparator<String> {
private final Comparator<File> delegate = <init NameFileComparator as needed>;
@Override
public int compare(String str1, String str2) {
return delegate.compare(new File(str1), new File(str2));
}
}
然后在TreeSet构造函数上使用MyComp。
考虑到File只是一个抽象,除非你决定创建一个文件,否则它不是真正的系统文件。这样安全使用。
添加关于大量文件名的免责声明,因为这种方法将为每个文件名生成一个新的File实例,这意味着少量的内存开销。在大多数情景中都没有考虑到这一点。