如何根据键为字母数字的键对 TreeMap 进行排序,但我们只需要根据可用数字进行排序?
How to sort TreeMap based on keys where keys are alpha numeric , but we need to sort based on available numbers only?
我有一个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;
有什么建议吗?
传递给 TreeMap
构造函数的 Comparator
以某种方式实现了 String 的 compareTo()
所做的:字典顺序比较。
但您不需要字典序比较。
在您的预期中,您只需要一个数字比较。
要实现它,删除 String
s 的无数字部分,从中创建两个 int
s 并将 int
s 与 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: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
这是因为您将键作为字符串进行比较,所以它比较第一个字符,然后是第二个字符,依此类推。
看来你想要的是比较每个键开头的整数。
比较操作好像没问题。它只是比较字符串值,显然“_”字符的优先级低于数字。如果您希望代码按数字对文件进行排序,则必须将文件名的数字部分存储为单独的 int 类型键。
如果您希望比较与 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 实例,这意味着少量的内存开销。在大多数情况下无需考虑。
我有一个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;
有什么建议吗?
传递给 TreeMap
构造函数的 Comparator
以某种方式实现了 String 的 compareTo()
所做的:字典顺序比较。
但您不需要字典序比较。
在您的预期中,您只需要一个数字比较。
要实现它,删除 String
s 的无数字部分,从中创建两个 int
s 并将 int
s 与 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: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
这是因为您将键作为字符串进行比较,所以它比较第一个字符,然后是第二个字符,依此类推。
看来你想要的是比较每个键开头的整数。
比较操作好像没问题。它只是比较字符串值,显然“_”字符的优先级低于数字。如果您希望代码按数字对文件进行排序,则必须将文件名的数字部分存储为单独的 int 类型键。
如果您希望比较与 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 实例,这意味着少量的内存开销。在大多数情况下无需考虑。