在 Java 中,获取字符串的首字母是一个常见的需求,下面我将为你详细介绍几种实现方法,从最简单到更健壮、更通用的方案,并附上完整的代码示例。

使用 charAt(0) 和 toUpperCase() (最常用)
这是最直接、最简单的方法,适用于大多数情况。
核心思想:
- 使用
String.charAt(0)方法获取字符串的第一个字符。 - 使用
Character.toUpperCase(char ch)方法将该字符转换为大写。
优点:
- 代码简洁,易于理解。
- 性能高。
缺点:

- 不安全:如果字符串为
null或空字符串 (),会抛出异常。str.charAt(0)在str为null时会抛出NullPointerException。str.charAt(0)在str为 时会抛出StringIndexOutOfBoundsException。
示例代码:
public class FirstLetterExample {
public static void main(String[] args) {
String str1 = "hello";
String str2 = "World";
String str3 = "java";
String str4 = ""; // 空字符串
String str5 = null; // null 字符串
System.out.println("--- 安全处理前 ---");
try {
// 正常情况
System.out.println("首字母 of '" + str1 + "': " + getFirstLetterUnsafe(str1));
System.out.println("首字母 of '" + str2 + "': " + getFirstLetterUnsafe(str2));
// 异常情况
System.out.println("首字母 of '" + str3 + "': " + getFirstLetterUnsafe(str3));
System.out.println("首字母 of '" + str4 + "': " + getFirstLetterUnsafe(str4)); // 抛出 StringIndexOutOfBoundsException
} catch (Exception e) {
System.err.println("捕获到异常: " + e.getMessage());
}
try {
System.out.println("首字母 of '" + str5 + "': " + getFirstLetterUnsafe(str5)); // 抛出 NullPointerException
} catch (Exception e) {
System.err.println("捕获到异常: " + e.getMessage());
}
System.out.println("\n--- 安全处理后 ---");
// 推荐使用安全的方法
System.out.println("首字母 of '" + str1 + "': " + getFirstLetterSafe(str1));
System.out.println("首字母 of '" + str2 + "': " + getFirstLetterSafe(str2));
System.out.println("首字母 of '" + str3 + "': " + getFirstLetterSafe(str3));
System.out.println("首字母 of '" + str4 + "': " + getFirstLetterSafe(str4)); // 输出空字符串 ""
System.out.println("首字母 of '" + str5 + "': " + getFirstLetterSafe(str5)); // 输出 null
}
/**
* 不安全的方法:直接获取首字母并大写
*/
public static String getFirstLetterUnsafe(String str) {
if (str == null || str.isEmpty()) {
// 为了演示,这里直接返回,实际调用时还是会出问题
return "";
}
// 这一行在 str 为 "" 时会抛出异常
return Character.toString(Character.toUpperCase(str.charAt(0)));
}
/**
* 安全的方法:处理 null 和空字符串的情况
*/
public static String getFirstLetterSafe(String str) {
// 1. 检查字符串是否为 null 或空
if (str == null || str.isEmpty()) {
return ""; // 或者 return null,取决于你的业务需求
}
// 2. 获取首字母并转换为大写
return Character.toString(Character.toUpperCase(str.charAt(0)));
}
}
使用 substring() 和 toUpperCase()
这种方法与方法一类似,只是用 substring() 来获取第一个字符。
核心思想:
- 使用
String.substring(0, 1)获取从索引 0 开始(包含)到 1 结束(不包含)的子字符串,也就是第一个字符。 - 使用
String.toUpperCase()将子字符串转换为大写。
示例代码:
public class FirstLetterSubstringExample {
public static void main(String[] args) {
String str = "java";
// 安全处理
if (str != null && !str.isEmpty()) {
String firstLetter = str.substring(0, 1).toUpperCase();
System.out.println("首字母: " + firstLetter); // 输出: J
} else {
System.out.println("字符串为 null 或空");
}
}
}
charAt() vs substring():
charAt(0)返回的是一个char基本类型,如果只需要字符本身,它更轻量。substring(0, 1)返回的是一个String对象,如果你需要的结果本身就是字符串,那么可以直接链式调用.toUpperCase(),代码上可能更连贯。
两者性能差异极小,在大多数情况下可以互换使用。关键在于必须进行 null 和空检查。
使用 Java 8+ Stream API (函数式风格)
如果你喜欢函数式编程,可以使用 Java 8 引入的 Stream API 来实现。
核心思想:
- 将字符串转换为字符流
str.chars()。 - 获取流的第一个元素
findFirst()。 - 如果存在,则将其转换为大写并映射为字符串;如果不存在(即字符串为空或null),则返回一个空字符串(或默认值)。
示例代码:
import java.util.Optional;
public class FirstLetterStreamExample {
public static void main(String[] args) {
String str1 = "stream";
String str2 = "";
String str3 = null;
// 安全处理
String firstLetter1 = str1 != null ? str1.chars().findFirst().stream().mapToObj(c -> String.valueOf((char) Character.toUpperCase(c))).findFirst().orElse("") : "";
String firstLetter2 = str2 != null ? str2.chars().findFirst().stream().mapToObj(c -> String.valueOf((char) Character.toUpperCase(c))).findFirst().orElse("") : "";
String firstLetter3 = str3 != null ? str3.chars().findFirst().stream().mapToObj(c -> String.valueOf((char) Character.toUpperCase(c))).findFirst().orElse("") : "";
System.out.println("首字母 of '" + str1 + "': " + firstLetter1); // 输出: S
System.out.println("首字母 of '" + str2 + "': " + firstLetter2); // 输出: (空字符串)
System.out.println("首字母 of '" + str3 + "': " + firstLetter3); // 输出: (空字符串)
}
}
注意:上面的 str.chars().findFirst().stream() 写法有点绕,更简洁的写法是直接使用 str.chars() 的 findFirst(),它返回一个 OptionalInt。
// 更简洁的 Stream 写法
public static String getFirstLetterWithStream(String str) {
if (str == null) {
return "";
}
return str.chars() // 获取一个 IntStream
.findFirst() // 获取第一个 OptionalInt
.stream() // 将 OptionalInt 转为 Stream<Integer>
.mapToObj(c -> String.valueOf((char) Character.toUpperCase(c))) // 转换
.findFirst() // 再次获取 Optional<String>
.orElse(""); // 如果没有值,则返回空字符串
}
这种方法非常强大,但比前两种方法复杂,对于“取首字母”这个简单任务来说,有点“杀鸡用牛刀”。
总结与最佳实践
| 方法 | 优点 | 缺点 | 推荐度 |
|---|---|---|---|
charAt() + toUpperCase() |
代码简洁,性能高 | 不安全,需手动处理 null 和空字符串 | ⭐⭐⭐⭐⭐ (最常用,但必须配合安全检查) |
substring() + toUpperCase() |
代码连贯,直接得到 String | 不安全,需手动处理 null 和空字符串 | ⭐⭐⭐⭐ (与方法一同样推荐) |
| Java 8 Stream API | 函数式风格,表达力强 | 代码复杂,可读性稍差 | ⭐⭐ (特定场景或偏好函数式编程时使用) |
最佳实践:
始终优先使用安全的方法。 在任何生产环境中,都不要直接调用 charAt(0) 而不进行前置检查。
以下是推荐的、健壮的获取首字母的函数:
/**
* 安全地获取字符串的首字母(大写)。
*
* @param str 输入的字符串,可以为 null 或空。
* @return 首字母的大写字符串,如果输入为 null 或空,则返回空字符串 ""。
*/
public static String getFirstLetter(String str) {
if (str == null || str.isEmpty()) {
return "";
}
return Character.toString(Character.toUpperCase(str.charAt(0)));
}
// 或者使用 substring 版本
public static String getFirstLetterWithSubstring(String str) {
if (str == null || str.isEmpty()) {
return "";
}
return str.substring(0, 1).toUpperCase();
}
使用场景建议:
- 如果只是简单地、一次性地获取一个已知非空字符串的首字母,可以直接用
str.charAt(0)。 - 在任何方法、工具类或需要处理未知输入的代码中,务必使用包含了
null和isEmpty()检查的安全版本,这是编写健壮 Java 代码的基本要求。
