
引言:电话键盘字母到数字的映射
在许多应用场景中,我们需要将文本中的字母转换为数字,最常见的例子就是电话键盘上的字母映射规则。例如,字母'a'、'b'、'c'对应数字'2','d'、'e'、'f'对应'3',以此类推。本教程将详细介绍如何使用java的现代特性,特别是switch表达式和stream api,高效且优雅地实现这一转换。
传统的实现方式可能涉及遍历字符串中的每个字符,然后在一个while或for循环中使用switch语句进行判断,并将结果逐个存储到一个集合中。这种方法虽然可行,但在处理结果存储和代码简洁性方面可能遇到一些挑战,例如原始数组无法直接使用add方法,以及变量作用域问题等。为了解决这些问题并提升代码的可读性和效率,我们将采用Java 14+引入的switch表达式和Java 8引入的Stream API。
使用Switch表达式进行字符到数字映射
switch表达式是Java 14及更高版本中引入的一项特性,它允许switch语句作为表达式使用,可以直接返回值,从而使代码更加简洁。结合Lambda风格的箭头语法,可以大大减少冗余代码。
首先,我们定义一个辅助方法getNumber,用于将单个字符转换为对应的数字。
public static int getNumber(char j) {
return switch (j) {
case 'A', 'B', 'C', 'a', 'b', 'c' -> 2;
case 'D', 'E', 'F', 'd', 'e', 'f' -> 3;
case 'G', 'H', 'I', 'g', 'h', 'i' -> 4;
case 'J', 'K', 'L', 'j', 'k', 'l' -> 5;
case 'M', 'N', 'O', 'm', 'n', 'o' -> 6;
case 'P', 'Q', 'R', 'S', 'p', 'q', 'r', 's' -> 7;
case 'T', 'U', 'V', 't', 'u', 'v' -> 8;
case 'W', 'X', 'Y', 'Z', 'w', 'x', 'y', 'z' -> 9;
default -> 0; // 处理非字母字符,例如数字、符号或空格
};
}在这个方法中:
立即学习“Java免费学习笔记(深入)”;
- 我们使用了switch表达式,它直接返回一个int值。
- case标签支持多值匹配,例如case 'A', 'B', 'C',这使得代码更加紧凑。
- 箭头语法->替代了传统的:和break,避免了break遗漏导致的错误。
- default -> 0处理了所有未匹配的字符,例如输入中可能包含的数字、符号或空格,它们将被映射为0。您可以根据需求调整此默认行为。
结合Stream API进行字符串处理
Java Stream API提供了一种声明式处理数据集合的方式,非常适合对字符串中的字符进行转换和聚合操作。我们可以利用Stream API将输入字符串转换为字符流,然后对每个字符应用getNumber方法,并将结果数字拼接成一个字符串,最终转换为整数。
import java.util.stream.Collectors;
public class PhoneNumberConverter {
// getNumber方法如上所示
public static int getPhoneNumber(String word) {
// 将字符串转换为字符流 (int stream)
return Integer.valueOf(word.chars()
// 将每个字符 (int) 映射为对应的数字字符串
.mapToObj(ch -> String.valueOf(getNumber((char) ch)))
// 将所有数字字符串连接起来形成一个完整的数字字符串
.collect(Collectors.joining()));
}
public static void main(String[] args) {
String inputWord = "Software";
int phoneNumber = getPhoneNumber(inputWord);
System.out.println("单词 '" + inputWord + "' 转换为数字是: " + phoneNumber); // 输出: 单词 'Software' 转换为数字是: 76389273
inputWord = "Hello World!";
phoneNumber = getPhoneNumber(inputWord);
System.out.println("单词 '" + inputWord + "' 转换为数字是: " + phoneNumber); // 输出: 单词 'Hello World!' 转换为数字是: 43556096753
}
}在getPhoneNumber方法中:
- word.chars(): 将输入字符串word转换为一个IntStream,其中每个int代表一个字符的ASCII值。
- .mapToObj(ch -> String.valueOf(getNumber((char) ch))): 这是Stream管道的核心。
- ch是当前字符的ASCII值。
- (char) ch将其转换回char类型。
- getNumber((char) ch)调用我们之前定义的getNumber方法,将字符转换为对应的数字。
- String.valueOf(...)将这个数字转换为字符串,因为collect(Collectors.joining())需要处理String对象。
- .collect(Collectors.joining()): 将所有由mapToObj生成的数字字符串连接起来,形成一个表示最终电话号码的完整字符串。
- Integer.valueOf(...): 将最终的数字字符串转换为一个int类型的整数。
完整代码示例
将上述两个方法组合,构成一个完整的Java程序,实现从单词到电话号码的转换。
import java.util.stream.Collectors; // 导入Collectors类
public class PhoneNumberConverter {
/**
* 将单个字符转换为电话键盘上对应的数字。
* 支持大小写字母,非字母字符映射为0。
*
* @param j 要转换的字符
* @return 对应的数字
*/
public static int getNumber(char j) {
return switch (j) {
case 'A', 'B', 'C', 'a', 'b', 'c' -> 2;
case 'D', 'E', 'F', 'd', 'e', 'f' -> 3;
case 'G', 'H', 'I', 'g', 'h', 'i' -> 4;
case 'J', 'K', 'L', 'j', 'k', 'l' -> 5;
case 'M', 'N', 'O', 'm', 'n', 'o' -> 6;
case 'P', 'Q', 'R', 'S', 'p', 'q', 'r', 's' -> 7;
case 'T', 'U', 'V', 't', 'u', 'v' -> 8;
case 'W', 'X', 'Y', 'Z', 'w', 'x', 'y', 'z' -> 9;
default -> 0; // 处理非字母字符
};
}
/**
* 将整个单词转换为电话键盘数字序列。
*
* @param word 要转换的单词字符串
* @return 转换后的数字整数
*/
public static int getPhoneNumber(String word) {
// 使用Stream API处理字符串中的每个字符
String numberString = word.chars()
// 将每个字符(int)映射为对应的数字字符串
.mapToObj(ch -> String.valueOf(getNumber((char) ch)))
// 将所有数字字符串连接成一个
.collect(Collectors.joining());
// 将最终的数字字符串转换为整数
// 注意:如果生成的数字序列过长,可能会超出int的最大值,此时应考虑使用long或String
return Integer.valueOf(numberString);
}
public static void main(String[] args) {
// 示例用法
String word1 = "Software";
System.out.println("单词 '" + word1 + "' 转换为数字是: " + getPhoneNumber(word1)); // 76389273
String word2 = "Hello World!"; // 包含空格和感叹号
System.out.println("单词 '" + word2 + "' 转换为数字是: " + getPhoneNumber(word2)); // 43556096753 (W和!转换为0)
String word3 = "Java123"; // 包含数字
System.out.println("单词 '" + word3 + "' 转换为数字是: " + getPhoneNumber(word3)); // 528000
}
}注意事项与总结
- Java版本要求: 本教程中使用的switch表达式语法(带箭头->和多值case标签)需要Java 14或更高版本。如果您的项目使用旧版Java,则需要使用传统的switch语句(带:和break)。
-
IntStream与Stream
: String.chars()返回的是IntStream,其元素是字符的ASCII值。如果需要操作Character对象,可以使用word.chars().mapToObj(c -> (char) c)将其转换为Stream 。 - 大数字处理: Integer.valueOf()方法会将字符串转换为int类型。如果转换后的数字序列非常长(例如,超过9-10位),可能会超出int类型的最大值(约21亿),导致NumberFormatException。在这种情况下,应考虑使用Long.valueOf()或直接将结果作为String类型返回。
- 错误处理与输入验证: getNumber方法中的default -> 0处理了非字母字符。在实际应用中,您可能需要更严格的输入验证,例如在getPhoneNumber方法开头检查输入字符串是否为空或只包含特定字符。
- 代码可读性与维护性: 结合switch表达式和Stream API的解决方案,相比于传统的循环和嵌套if-else或冗长的switch语句,代码更加简洁、易读,且易于维护。它以声明式的方式表达了“如何转换”,而不是“一步步如何转换”,符合现代Java编程范式。
通过本教程,您应该已经掌握了如何利用Java的现代特性,优雅地实现单词到电话号码的转换。这种方法不仅高效,而且代码清晰,是处理类似字符映射问题的推荐实践。










