1. 概述
在Java中处理整数时,我们有时需要将它们分解成单个数字,以完成各种计算或数据操作任务。
在这篇教程中,我们将探讨使用Java分解一个整数为各个组成数字的不同方法。
2. 问题介绍
让我们通过一个例子来理解这个问题。假设我们有一个整数:
int THE_NUMBER = 1230456;
我们的目标是按照顺序将这个数分解成数字:
1, 2, 3, 0, 4, 5, 6
为了简化,本教程主要关注的是正十进制整数。然而,根据特定需求,我们可能希望得到每个数字作为Integer
、char
或String
类型。
接下来,我们将探索不同的方法来适应这些不同的返回类型。
3. 分解为Integer
列表
首先,我们将给定的整数分解为一个Integer
列表。也就是说,我们目标是获取这样的列表:
List<Integer> EXPECTED_INT_LIST = Lists.newArrayList(1, 2, 3, 0, 4, 5, 6);
一个最直接的方法是使用循环,反复将数字除以10,在每次迭代中提取余数,直到数字变为零:
1230456 / 10 = 123045 Reminder: 6
|-> 123045 / 10 = 12304 Reminder: 5
|-> 12304 / 10 = 1230 Reminder: 4
|-> 1230 / 10 = 123 Reminder: 0
|-> 123 / 10 = 12 Reminder: 3
|-> 12 / 10 = 1 Reminder: 2
|-> 1 / 10 = 0 Reminder: 1
然而,如上所示,这种方法会产生反向的数字顺序。为了解决这个问题,我们可以使用LinkedList
作为栈并在每次步骤中将余数推入栈中:
int number = THE_NUMBER;
LinkedList<Integer> result = new LinkedList<>();
while (number > 0) {
result.push(number % 10);
number /= 10;
}
assertEquals(EXPECTED_INT_LIST, result);
此外,我们也可以使用递归实现相同的想法:
void collectDigits(int num, List<Integer> digitList) {
if (num / 10 > 0) {
collectDigits(num / 10, digitList);
}
digitList.add(num % 10);
}
然后,我们可以调用collectDigits()
方法获取结果:
List<Integer> result = new ArrayList<>();
collectDigits(THE_NUMBER, result);
assertEquals(EXPECTED_INT_LIST, result);
如果我们的Java版本是Java 9或更高版本,我们可以使用String.chars()
和IntStream
来获取数字列表:
String numStr = String.valueOf(THE_NUMBER);
List<Integer> result = numStr.chars().map(Character::getNumericValue).boxed().collect(Collectors.toList());
assertEquals(EXPECTED_INT_LIST, result);
如代码所示,我们首先将整数转换为字符串。然后,numStr.chars()
方法将数字字符串分解为IntStream
中的字符。接下来,Character
类的**getNumericValue()
**方法从IntStream
中的字符获取数字作为int
。最后,我们将int
值装箱成Integer
,并使用收集器收集结果到一个列表中。
4. 分解为char
数组
有时,我们希望将给定的整数分解为char[]
数组:
char[] EXPECTED_CHAR_ARRAY = new char[] { '1', '2', '3', '0', '4', '5', '6' };
这个任务很简单,因为标准String
类提供了toCharArray()
方法来将字符串分解为char[]
。我们需要做的只是将整数转换为String
并调用toCharArray()
方法:
String numStr = String.valueOf(THE_NUMBER);
char[] result = numStr.toCharArray();
assertArrayEquals(EXPECTED_CHAR_ARRAY, result);
当然,如果需要,我们可以快速地将数组转换为列表。
5. 分解为String
数组或String
列表
最后,让我们看看如何将一个整数分解为String[]
数组或String
列表:
String[] EXPECTED_STR_ARRAY = new String[] { "1", "2", "3", "0", "4", "5", "6" };
List<String> EXPECTED_STR_LIST = Lists.newArrayList("1", "2", "3", "0", "4", "5", "6");
既然我们称这个操作为“分割”,那么强大的split()
方法可以帮助我们解决问题:
String numStr = String.valueOf(THE_NUMBER);
String[] result = numStr.split("(?<=.)");
assertArrayEquals(EXPECTED_STR_ARRAY, result);
如我们所见,代码看起来相当简洁。关键是我们split()
函数中使用的正则表达式模式。**(?<=.)
是一个向前查找表达式**。例如,"(?<=X)a"
匹配所有紧跟在X
字符之后的'a'
。
然而,我们的模式中只有(?<=.)
。这意味着这个模式匹配零宽度的“字符”。所以,split()
方法会把任何字符后的零宽度“字符”作为分隔符。如果将数字字符串中的零宽度“字符”替换为'#'
,可能会更容易理解:“1#2#3#0#4#5#6#”。
另外,split()
方法默认会丢弃尾随的空元素。因此,它能产生我们想要的结果。
6. 总结
在这篇文章中,我们探讨了多种将整数分解为数字的方法,并通过示例展示了如何根据不同的类型(如Integer
、char
和String
)获取这些数字。
一如既往,每个示例的完整源代码可在GitHub上找到。