在Java中按字符串中包含的数字进行排序

2025/04/10

1. 简介

在本教程中,我们将了解如何根据字母数字字符串包含的数字对其进行排序,我们将重点介绍如何从字符串中删除所有非数字字符,然后根据剩余的数字字符对多个字符串进行排序。

我们将研究常见的边缘情况,包括空字符串和无效数字。

最后,我们将对解决方案进行单元测试,以确保它按预期工作。

2. 概述问题

在开始之前,我们需要描述一下想要实现的目标。对于这个特定问题,我们将做出以下假设:

  1. 我们的字符串可能只包含数字、只包含字母或两者的混合。
  2. 我们的字符串中的数字可能是整数或双精度数。
  3. 当字符串中的数字由字母分隔时,我们应该删除字母并将数字合并在一起;例如,2d3变成23。
  4. 为了简单起见,当出现无效或缺失的数字时,我们应该将其视为0。

确定这一点后,我们就开始着手解决问题。

3. 正则表达式解决方案

由于我们的第一步是在输入字符串中搜索数字模式,因此我们可以使用正则表达式。

我们首先需要的是正则表达式,我们希望保留输入字符串中的所有整数和小数点,我们可以通过以下方式实现目标:

String DIGIT_AND_DECIMAL_REGEX = "[^\\d.]"

String digitsOnly = input.replaceAll(DIGIT_AND_DECIMAL_REGEX, "");

让我们简单解释一下发生了什么:

  1. ’[^ ]‘:表示否定集,因此针对的是封闭正则表达式未指定的任何字符
  2. ’\d’:匹配任意数字字符(0–9)
  3. ’.’:匹配任何“.”字符

然后,我们使用String.replaceAll方法删除所有未在正则表达式中指定的字符,通过这样做,我们可以确保实现目标的前三点。

接下来,我们需要添加一些条件来确保空字符串和无效字符串返回0,而有效字符串返回有效的Double:

if("".equals(digitsOnly)) return 0;

try {
    return Double.parseDouble(digitsOnly);
} catch (NumberFormatException nfe) {
    return 0;
}

至此,我们的逻辑就完成了,剩下要做的就是把它插入到比较器中,这样我们就可以方便地对输入字符串列表进行排序。

让我们创建一个有效的方法来从任何我们想要的地方返回我们的比较器:

public static Comparator<String> createNaturalOrderRegexComparator() {
    return Comparator.comparingDouble(NaturalOrderComparators::parseStringToNumber);
}

4. 测试

让我们设置一个快速单元测试来确保一切按计划进行:

List<String> testStrings = Arrays.asList("a1", "d2.2", "b3", "d2.3.3d", "c4", "d2.f4",); // 1, 2.2, 3, 0, 4, 2.4

testStrings.sort(NaturalOrderComparators.createNaturalOrderRegexComparator());

List<String> expected = Arrays.asList("d2.3.3d", "a1", "d2.2", "d2.f4", "b3", "c4");

assertEquals(expected, testStrings);

在这个单元测试中,我们考虑到了所有计划好的场景,无效数字、整数、小数和字母分隔的数字都包含在testStrings变量中。

5. 总结

在这篇短文中,我们演示了如何根据字母数字字符串中的数字对其进行排序-利用正则表达式为我们完成艰苦的工作。

我们处理了解析输入字符串时可能出现的标准异常,并使用单元测试测试了不同的场景。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章