【问题标题】:How to sort the keys with alphanumeric in TreeMap如何在 TreeMap 中使用字母数字对键进行排序
【发布时间】:2016-08-25 14:54:06
【问题描述】:

我有关注TreeMap:

Map<String, Map<String, String>> result = new TreeMap<String, Map<String, String>>();            

result.put("Tier 1",  "My First String", "My First String ABC");
result.put("Tier 2",  "My First String", "My First String DEF");
result.put("Tier 3",  "My First String", "My First String DDD");
result.put("Tier 10", "My Last String", "My First String TTT");

打印出来的结果在“Tier 10”处不按顺序排列String:

Tier 1,  My First String, My First String ABC
Tier 10, My First String, My First String TTT
Tier 2,  My First String, My First String DEF
Tier 3,  My First String, My First String DDD

我希望它符合逻辑顺序:

Tier 1,  My First String, My First String ABC
Tier 2,  My First String, My First String DEF
Tier 3,  My First String, My First String DDD
Tier 10, My First String, My First String TTT

我尝试使用Comparator如下:

Map<String, Map<String, String>> result = new TreeMap<String, Map<String, String>>(
    new Comparator<String>() {
      @Override
      public int compare(String o1, String o2) {
        return o1.compareTo(o2);
      }
    });

但这没有帮助。

【问题讨论】:

  • 定义比较器来进行你想要的比较并使用它。
  • 我确实定义了一个比较器,但它不起作用
  • 您可能想要使用自然顺序排序。 compareTo() 方法将进行字母排序。
  • 您是否考虑过比String 更丰富的密钥类型?也许类似于一个简单的对象,它有一个名为“label”的String 和一个名为“index”的Integer? (但不要忘记实现equalshashCode!)

标签: java sorting key treemap


【解决方案1】:

您可以使用 lambda 表达式轻松定义Comparator

TreeMap<String, String> result = new TreeMap<String, String>((String s1, String s2) -> {
    Matcher m1 = Pattern.compile("\\d+").matcher(s1);
    Matcher m2 = Pattern.compile("\\d+").matcher(s2);
    m1.find();
    m2.find();
    return Integer.compare(Integer.parseInt(m1.group()), Integer.parseInt(m2.group()));
});

result.put("Tier 3",  "My First String");
result.put("Tier 10", "My Last String");
result.put("Tier 1",  "My First String");
result.put("Tier 2",  "My First String");

System.out.println(result);

输出:

{Tier 1=我的第一个字符串,Tier 2=我的第一个字符串,Tier 3=我的第一个字符串,Tier 10=我的最后一个字符串}

【讨论】:

  • 我的 TreeMap 不仅仅包含“Tier XXX”。许多其他带有一些文本和数值的字符串。例如,桥 1、桥 20、成本 1 到成本 100。
  • Maljam,我的 TreeMap 是 Map> result = new TreeMap>()
  • Maljam,什么是 -->?我是 Java 新手
  • 这是 Java 中最近添加的一个称为 lambda 表达式的功能,它允许您将方法作为参数提供给另一个方法/构造函数。它与实现Comparator 和定义compare() 方法的想法相同,它只是节省了代码并提高了可读性。你可以阅读它:Lambda Expressions
  • 我收到“Integer 类型的方法 compare(int, int) 未定义”
【解决方案2】:

这就是我现在拥有的并且效果很好:(在这里回答了我自己的问题)

Map<String, Map<String, String>> result = new TreeMap<String, Map<String, String>>(
    new Comparator<String>() {

      @Override
      public int compare(String s1, String s2) {
        Integer i1 = null;
        Integer i2 = null;
        int retVal = 99;

        if (containsDigit(s1) && containsDigit(s2) && (extractString(s1).equals(extractString(s2)))) {
          i1 = new Integer(extractNumber(s1));
          i2 = new Integer(extractNumber(s2));

          if (i1 != null && i2 != null) {
            retVal = i1.compareTo(i2);
          }
        } else {
          retVal = s1.compareTo(s2);
        }
        return retVal;
      }
    });

其他支持的方法:

private String extractNumber(final String str) {
    if (str == null || str.isEmpty()) {
        return emptyString_;
    }
    return str.replaceAll("\\p{Alpha}", emptyString_).trim();
   }

private String extractString(final String str) {
    if (str == null || str.isEmpty()) {
      return emptyString_;
    }
    return str.replaceAll("[^a-zA-Z]", emptyString_);
}

private boolean containsDigit(String s) {
    boolean found = false;
    if (s != null && !s.isEmpty()) {
      for (char c : s.toCharArray()) {
        if (Character.isDigit(c)) {
           found = true;
           break;
        }
      }
    }
     return found;
   }

【讨论】:

    猜你喜欢
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 2013-07-27
    • 2015-10-01
    • 1970-01-01
    • 2021-08-20
    • 1970-01-01
    相关资源
    最近更新 更多