【问题标题】:Sort ArrayList<String> excluding the digits on the first half of the String对 ArrayList<String> 排序,不包括字符串前半部分的数字
【发布时间】:2019-12-27 12:33:04
【问题描述】:

我正在尝试对由一系列字符串组成的 ArrayList 进行排序(XX 和 YY 是数字):

Test: XX    Genere: Maschio    Eta: YY    Protocollo: A

我将通过仅考虑 YY 值来链接对它们进行排序。我找到了这个方法,但它考虑了字符串的所有数字,我不能在 YY 之前删除 n 个数字,因为我不知道 XX 由多少个数字组成:

Collections.sort(strings, new Comparator<String>() {
    public int compare(String o1, String o2) {
        return extractInt(o1) - extractInt(o2);
    }

    int extractInt(String s) {
        String num = s.replaceAll("\\D", "");
        // return 0 if no digits found
        return num.isEmpty() ? 0 : Integer.parseInt(num);
    }
});

【问题讨论】:

  • 一个想法是将每个字符串分解为一个具有testgenereetaprotocollo字段的对象,并将这些对象放入一个ArrayList中。排序会容易得多。 Object 的 toString 方法将输出您的原始字符串。

标签: java string sorting arraylist


【解决方案1】:

您还需要想出如何对第二部分中没有数字的字符串进行排序。

Collections.sort(strings, new Comparator<String>() {
  public int compare(String o1, String o2) {
    return Comparator.comparingInt(this::extractInt)
        .thenComparing(Comparator.naturalOrder())
        .compare(o1, o2);
  }

  private int extractInt(String s) {
    try {
      return Integer.parseInt(s.split(":")[1].trim());
    }
    catch (NumberFormatException exception) {
      // if the given String has no number in the second part,
      // I treat such Strings equally, and compare them naturally later
      return -1;
    }
  }
});

更新

如果您确定 Integer.parseInt(s.split(":")[1].trim()) 不会因异常而失败,Comparator.comparingInt(this::extractInt) 就足够了,您可以使用更短的比较器。

Collections.sort(strings, 
  Comparator.comparingInt(s -> Integer.parseInt(s.split(":")[1].trim())));

【讨论】:

  • 所有字符串都会有数字所以没有问题
  • @Fabio 如果您确定Integer.parseInt(s.split(":")[1].trim()) 不会因异常而失败,Comparator.comparingInt(this::extractInt) 就足够了。
【解决方案2】:

比较它们的一种方法是找到子字符串“Eta:”并从它的位置比较字符串:

Collections.sort(strings, (String s1, String s2) -> s1.substring((s1.indexOf("Eta: "))).
    compareTo(s2.substring((s2.indexOf("Eta: ")))));

【讨论】:

    【解决方案3】:

    YY 似乎是字符串中的第二个数字,因此您可以使用正则表达式\d+ 提取它并调用Matcher.find() 两次。

    // assuming extractInt is declared in "YourClass"
    static int extractInt(String s) {
        Matcher m = Pattern.compile("\\d+").matcher(s);
        m.find();
        if (m.find()) {
            return Integer.parserInt(m.group());
        } else {
            return 0;
        }
    }
    
    // ...
    
    Collections.sort(strings, Comparator.comparingInt(YourClass::extractInt));
    

    您还应该考虑首先将所有字符串解析为类实例列表的方法,如下所示:

    class MyObject {
        private int test;
        private String genere;
        private int eta;
        private int protocollo;
    
        // getters and constructor...
    }
    

    然后您可以简单地使用Comparator.comparingInt(MyObject::getEta) 作为比较器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-24
      • 1970-01-01
      • 2020-02-20
      • 2014-12-07
      • 2014-05-05
      • 2011-09-19
      • 2014-10-10
      • 1970-01-01
      相关资源
      最近更新 更多