1. Introduction
1.介绍
In this tutorial, we’ll look at how to sort alphanumeric Strings by the numbers they contain. We’ll focus on removing all non-numeric characters from the String before sorting multiple Strings by the numerical characters that remain.
在本教程中,我们将探讨如何按字母数字Strings所包含的数字进行排序。我们将重点关注从字符串中删除所有非数字字符,然后根据剩下的数字字符对多个字符串进行排序。
We’ll look at common edge cases, including empty Strings and invalid numbers.
我们将研究常见的边缘情况,包括空的Strings和无效的数字。
Finally, we’ll unit test our solution to ensure it works as expected.
最后,我们将对我们的解决方案进行单元测试,以确保它按预期工作。
2. Outlining the Problem
2.概述问题
Before we begin, we need to describe what we want our code to achieve. For this particular problem, we’ll make the following assumptions:
在我们开始之前,我们需要描述一下我们希望我们的代码能够实现什么。对于这个特定的问题,我们将做出以下假设。
- Our strings may contain only numbers, only letters or a mix of the two.
- The numbers in our strings may be integers or doubles.
- When numbers in a string are separated by letters, we should remove the letter and condense the digits together. For example, 2d3 becomes 23.
- For simplicity, when an invalid or missing number appears, we should treat them as 0.
With this established, let’s get stuck into our solution.
有了这个基础,让我们开始着手解决这个问题。
3. A Regex Solution
3.一个Regex解决方案
Since our first step is to search for numeric patterns within our input String, we can put to use regular expressions, commonly known as a regex.
由于我们的第一步是在我们的输入String中搜索数字模式,我们可以使用正则表达式,通常被称为regex。
The first thing we need is our regex. We want to conserve all integers as well as decimal points from the input String. We can achieve our goal with the following:
我们需要的第一件事是我们的regex。我们想保留输入String中的所有整数和小数点。我们可以通过以下方式实现我们的目标。
String DIGIT_AND_DECIMAL_REGEX = "[^\\d.]"
String digitsOnly = input.replaceAll(DIGIT_AND_DECIMAL_REGEX, "");
Let’s briefly explain what’s happening:
让我们简单地解释一下发生了什么。
- ‘[^ ]’ – denotes a negated set, therefore targetting any character not specified by the enclosed regex
- ‘\d’ – match any digit character (0 – 9)
- ‘.’ – match any “.” character
We then use String.replaceAll method to remove any characters not specified by our regex. By doing this, we can ensure that the first three points of our goal can be achieved.
然后,我们使用String.replaceAll方法来删除任何未被我们的regex指定的字符。通过这样做,我们可以确保我们目标的前三点可以实现。
Next, we need to add some conditions to ensure empty and invalid Strings return 0, while valid Strings return a valid Double:
接下来,我们需要添加一些条件,确保空的和无效的字符串返回0,而有效的字符串返回有效的Double。
if("".equals(digitsOnly)) return 0;
try {
return Double.parseDouble(digitsOnly);
} catch (NumberFormatException nfe) {
return 0;
}
That completes our logic. All that’s left to do is plug it into a comparator so that we can conveniently sort Lists of input Strings.
这就完成了我们的逻辑。剩下的就是把它插入一个比较器,这样我们就可以方便地对输入字符串的列表进行排序。字符串的列表。
Let’s create an efficient method to return our comparator from anywhere we may want it:
让我们创建一个有效的方法,从我们可能需要的任何地方返回我们的比较器。
public static Comparator<String> createNaturalOrderRegexComparator() {
return Comparator.comparingDouble(NaturalOrderComparators::parseStringToNumber);
}
4. Test, Test, Test
4.测试、测试、测试
What good is code without tests to verify its functionality? Let’s set up a quick unit test to ensure it all works as we planned:
没有测试来验证其功能的代码有什么用?让我们建立一个快速的单元测试,以确保这一切都按计划进行。
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);
In this unit test, we’ve packed in all of the scenarios we’ve planned for. Invalid numbers, integers, decimals, and letter-separated numbers all in included in our testStrings variable.
在这个单元测试中,我们已经把我们计划的所有场景都纳入了。无效数字、整数、小数和字母分隔的数字都包含在我们的testStrings变量中。
5. Conclusion
5.结论
In this short article, we’ve demonstrated how to sort alphanumeric strings based on the numbers within them – making use of regular expressions to do the hard work for us.
在这篇短文中,我们演示了如何根据字母数字字符串中的数字进行排序–利用正则表达式来为我们做艰苦的工作。
We’ve handled standard exceptions that may occur when parsing input strings and tested the different scenarios with unit testing.
我们已经处理了解析输入字符串时可能出现的标准异常,并通过单元测试测试了不同的场景。
As always, the code can be found over on GitHub.
一如既往,代码可以在GitHub上找到。