如何根据键为字母数字的键对 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() 所做的:字典顺序比较。

但您不需要字典序比较。
在您的预期中,您只需要一个数字比较。
要实现它,删除 Strings 的无数字部分,从中创建两个 ints 并将 ints 与 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 实例,这意味着少量的内存开销。在大多数情况下无需考虑。