如何根据键是字母数字的键对TreeMap进行排序,但是我们只需要根据可用的数字进行排序?

时间:2017-08-10 17:20:04

标签: java treemap

我有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;

有什么建议吗?

4 个答案:

答案 0 :(得分:3)

传递给Comparator构造函数的TreeMap以某种方式使compareTo()字符串做:字典比较。

但你不想进行词典编纂比较 在您的预期中,您只需要进行数字比较 要实现此目的,请移除String的无数字部分,从中创建两个int并将intInteger.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实例,这意味着少量的内存开销。在大多数情景中都没有考虑到这一点。