1. Overview
1.概述
When working with String types in Java, it’s often necessary to analyze the composition of the characters within them. One common task is counting the number of uppercase and lowercase letters in a given String.
在 Java 中处理 String 类型时,经常需要分析其中的字符组成。一个常见的任务是计算给定 String 中大写和小写字母的数量。
In this tutorial, we’ll explore several simple and practical approaches to achieve this using Java.
在本教程中,我们将使用 Java 探索几种简单实用的方法来实现这一目标。
2. Introduction to the Problem
2.问题介绍
Before diving into the code, let’s first clarify the problem at hand. We want to create a Java method that takes a String as input and counts the number of uppercase and lowercase letters simultaneously. In other words, the solution will produce a result containing two counters.
在深入学习代码之前,让我们首先明确当前的问题。我们希望创建一个 Java 方法,将 String 作为输入,同时计算大写和小写字母的数量。换句话说,解决方案将产生一个包含两个计数器的结果。
For example, we’ll take the following String as the input:
例如,我们将以下 String 作为输入:
static final String MY_STRING = "Hi, Welcome to Baeldung! Let's count letters!";
Uppercase letters are characters from ‘A‘ to ‘Z‘, and lowercase letters are characters from ‘a‘ to ‘z‘. That is to say, special characters such as ‘,’ and ‘!’ within the example String are considered neither uppercase nor lowercase letters.
大写字母是指从”A“到”Z“的字符,小写字母是指从”a“到”z“的字符。也就是说,示例 String 中的’,’和’!’等特殊字符既不被视为大写字母,也不被视为小写字母。
Looking at the example, we have four uppercase letters and 31 lowercase letters in MY_STRING.
从示例来看,MY_STRING.中有 4 个大写字母和 31 个小写字母。
Since we’ll calculate two counters simultaneously, let’s create a simple result class to carry the two counters so that we can verify the outcome more easily:
由于我们将同时计算两个计数器,因此让我们创建一个简单的结果类来携带这两个计数器,这样我们就能更容易地验证结果:
class LetterCount {
private int uppercaseCount;
private int lowercaseCount;
private LetterCount(int uppercaseCount, int lowercaseCount) {
this.uppercaseCount = uppercaseCount;
this.lowercaseCount = lowercaseCount;
}
public int getUppercaseCount() {
return uppercaseCount;
}
public int getLowercaseCount() {
return lowercaseCount;
}
// ... counting solutions come later ...
}
Later, we’ll add counting solutions as static methods to this class.
稍后,我们将在该类中添加计数解决方案作为 静态方法。
So, if an approach correctly counts the letters, it should produce a LetterCount object with uppercaseCount = 4 and lowercaseCount = 31.
因此,如果一种方法能正确计算字母,那么它应该产生一个 LetterCount 对象,其中 uppercaseCount = 4 和 lowercaseCount = 31。
Next, let’s count letters.
接下来,让我们数字母。
3. Using Character Ranges
3.使用字符范围
To solve this problem, we’ll iterate through each character in the given String and determine whether it’s an uppercase or lowercase letter by checking if it falls in one of the corresponding character ranges:
为了解决这个问题,我们将遍历给定字符串中的每个字符,并通过检查它是否属于相应的字符范围之一来确定它是大写字母还是小写字母:
static LetterCount countByCharacterRange(String input) {
int upperCount = 0;
int lowerCount = 0;
for (char c : input.toCharArray()) {
if (c >= 'A' && c <= 'Z') {
upperCount++;
}
if (c >= 'a' && c <= 'z') {
lowerCount++;
}
}
return new LetterCount(upperCount, lowerCount);
}
As the code above shows, we maintain separate counters for uppercase and lowercase letters and increment them accordingly during iteration. After walking through the input String, we create the LetterCount object using the two counters and return it as the result:
如上面的代码所示,我们为大写字母和小写字母分别保留计数器,并在迭代过程中相应地递增。在遍历输入的 String 之后,我们使用两个计数器创建 LetterCount 对象,并将其作为结果返回:
LetterCount result = LetterCount.countByCharacterRange(MY_STRING);
assertEquals(4, result.getUppercaseCount());
assertEquals(31, result.getLowercaseCount());
It’s worth noting that this approach is only applicable to String inputs consisting of ASCII characters.
值得注意的是,这种方法仅适用于由 ASCII 字符组成的 String 输入。
4. Using the isUpperCase() and isLowerCase() Methods
4.使用 isUpperCase() 和 isLowerCase() 方法
In the previous solution, we determine if a character is an uppercase or lowercase letter by checking its range. Actually, the Character class has provided the isUpperCase() and isLowerCase() methods for this check.
在前面的解决方案中,我们通过检查字符的范围来确定该字符是大写字母还是小写字母。实际上,字符类提供了isUpperCase()和isLowerCase()方法来进行这种检查。
It’s important to highlight that isUpperCase() and isLowerCase() also work with Unicode characters:
需要强调的是,isUpperCase() 和 isLowerCase() 也适用于Unicode字符:
assertTrue(Character.isLowerCase('ä'));
assertTrue(Character.isUpperCase('Ä'));
So, let’s replace the range checks with the case-checking methods from the Character class:
因此,让我们用 Character 类中的大小写检查方法来替换范围检查:
static LetterCount countByCharacterIsUpperLower(String input) {
int upperCount = 0;
int lowerCount = 0;
for (char c : input.toCharArray()) {
if (Character.isUpperCase(c)) {
upperCount++;
}
if (Character.isLowerCase(c)) {
lowerCount++;
}
}
return new LetterCount(upperCount, lowerCount);
}
As we can see, the two case-checking methods make the code easier to understand, and they produce the expected result:
我们可以看到,这两种情况检查方法使代码更容易理解,并产生了预期的结果:
LetterCount result = LetterCount.countByCharacterIsUpperLower(MY_STRING);
assertEquals(4, result.getUppercaseCount());
assertEquals(31, result.getLowercaseCount());
5. Using the Stream API’s filter() and count() Methods
5.使用流 API 的 filter() 和 count() 方法
The Stream API stands out as a significant feature introduced in Java 8.
Stream API 是 Java 8 中引入的一项重要功能。
Next, let’s solve this problem using filter() and count() from the Stream API:
接下来,让我们使用流 API 中的 filter() 和 count() 来解决这个问题:
static LetterCount countByStreamAPI(String input) {
return new LetterCount(
(int) input.chars().filter(Character::isUpperCase).count(),
(int) input.chars().filter(Character::isLowerCase).count()
);
}
As the count() method returns a long value, we must cast it to an int to instantiate the LetterCount object.
由于 count()方法返回一个 long 值,我们必须将其转换为 int 以实例化 LetterCount 对象。
It may appear at first glance that this solution is straightforward and much more compact than the other loop-based approaches. However, it’s worth noting that this approach walks through the characters in the input String twice.
乍一看,这种解决方案似乎简单明了,而且比其他基于循环的方法更紧凑。但是,值得注意的是,这种方法会对输入 String 中的字符执行两次。
Finally, let’s write a test to verify if this approach yields the expected result:
最后,让我们编写一个测试来验证这种方法是否能产生预期的结果:
LetterCount result = LetterCount.countByStreamAPI(MY_STRING);
assertEquals(4, result.getUppercaseCount());
assertEquals(31, result.getLowercaseCount());
6. Conclusion
6.结论
In this article, we’ve explored different approaches to counting uppercase and lowercase letters in a given String.
在本文中,我们探讨了计算给定 String 中大写和小写字母的不同方法。
These simple yet effective approaches provide a foundation for more complex String analysis tasks in real-world work.
这些简单而有效的方法为实际工作中更复杂的 String 分析任务奠定了基础。
As always, the complete source code for the examples is available over on GitHub.
与往常一样,这些示例的完整源代码可在 GitHub 上获取。