1. 概述

在Java中处理字符串时,通常需要确定一个字符串是否完全由大写或小写字母组成。

本教程将探讨执行此检查的不同方法。

2. 问题介绍

首先,我们准备三个输入字符串:

static final String UPPER_INPUT = "1: COOL!";
static final String LOWER_INPUT = "2: cool!";
static final String MIXED_INPUT = "3: Cool!";

如图所示,每个字符串都包含一个空格和两个标点符号。非字母字符(如数字和标点符号)是否属于大写或小写取决于需求。在这个教程中,我们将非字母字符视为大写和小写字母。

我们在CaseCheck类中创建静态检查方法:

class CaseChecker {
    static boolean allUpperX(String input){...}
    static boolean allLowerX(String input){...}
    ...
}

通过利用Java字符串类和字符操作的强大功能,我们可以轻松执行这些检查并处理各种用例。为了简洁,我们将使用单元测试断言来验证每个方法是否返回预期结果。

现在,让我们深入研究!

3. 转换与比较

我们知道String类提供了两种方法:toUpperCase()toLowerCase()如果字符串s的所有字符都是大写的,那么s必须等于s.toUpperCase()的结果。因此,根据这个思路,我们创建两个检查方法,一个用于大写检查,另一个用于小写检查:

static boolean allUpper1(String input) {
    return input.equals(input.toUpperCase());
}

static boolean allLower1(String input) {
    return input.equals(input.toLowerCase());
}

接下来,使用我们的预设输入字符串测试这些方法:

assertTrue(CaseChecker.allLower1(LOWER_INPUT));
assertFalse(CaseChecker.allLower1(UPPER_INPUT));
assertFalse(CaseChecker.allLower1(MIXED_INPUT));

assertFalse(CaseChecker.allUpper1(LOWER_INPUT));
assertTrue(CaseChecker.allUpper1(UPPER_INPUT));
assertFalse(CaseChecker.allUpper1(MIXED_INPUT));

如果执行测试通过,那么检查方法就解决了问题。

4. 检查每个字符

虽然我们已经成功地使用转换和比较的方法解决了问题,如input.equals(input.toUpperCase()),但当处理长输入字符串时,这种方法可能不是最优的。它会转换每个字符的大小写,这可能会变得耗时且对长字符串来说可能不必要的。

另一种想法是遍历输入字符串中的字符。一旦我们发现一个不是大写或小写字母的字符,就可以确定结果。所以我们可以跳过进一步的检查

我们可以使用String.toCharArray()将字符串拆分为char数组,并使用Character.isLowerCase()Character.isUpperCase()方法判断char是否为小写或大写字母。

接下来,我们将这两种方法结合起来创建我们的检查方法:

static boolean allUpper2(String input) {
    for (char c : input.toCharArray()) {
        //  don't write in this way: if (!Character.isUpperCase(c))
        if (Character.isLowerCase(c)) {
            return false;
        }
    }
    return true;
}

static boolean allLower2(String input) {
    for (char c : input.toCharArray()) {
        //  don't write in this way: if (!Character.isLowerCase(c))
        if (Character.isUpperCase(c)) {
            return false;
        }
    }
    return true;
}

实现起来并不难理解。然而,代码中的注释可能会引起疑问,例如,在allUpper2()中,为什么我们不写if (!Character.isUpperCase(c)) return false;

这是因为对于任何非字母字符,如.7CharacterisUpperCase()isLowerCase()方法都会返回false但在我们的大写/小写检查逻辑中,我们需要忽略非字母字符。因此,使用if (Character.isLowerCase(c)) return false;更为合适,而不是if (!Character.isUpperCase(c)) return false;

测试显示,我们的检查方法也能完成任务:

assertTrue(CaseChecker.allLower2(LOWER_INPUT));
assertFalse(CaseChecker.allLower2(UPPER_INPUT));
assertFalse(CaseChecker.allLower2(MIXED_INPUT));

assertFalse(CaseChecker.allUpper2(LOWER_INPUT));
assertTrue(CaseChecker.allUpper2(UPPER_INPUT));
assertFalse(CaseChecker.allUpper2(MIXED_INPUT));

另外,我们也可以使用Java 8的流API实现相同的功能:

static boolean allUpper3(String input) {
    return input.chars().noneMatch(Character::isLowerCase);
}

static boolean allLower3(String input) {
    return input.chars().noneMatch(Character::isUpperCase);
}

5. 关于Apache Commons Lang 3库中的StringUtils

Apache Commons Lang 3提供了方便的StringUtils类。这个实用类有两个方法:isAllLowerCase()isAllUpperCase()

值得注意的是,这些方法将非字母字符视为既不是大写也不是小写:

assertFalse(StringUtils.isAllLowerCase(LOWER_INPUT));
assertFalse(StringUtils.isAllLowerCase(UPPER_INPUT));
assertFalse(StringUtils.isAllLowerCase(MIXED_INPUT));

assertFalse(StringUtils.isAllLowerCase("a b"));
assertTrue(StringUtils.isAllLowerCase("ab"));

assertFalse(StringUtils.isAllUpperCase(LOWER_INPUT));
assertFalse(StringUtils.isAllUpperCase(UPPER_INPUT));
assertFalse(StringUtils.isAllUpperCase(MIXED_INPUT));

assertFalse(StringUtils.isAllUpperCase("A B"));
assertTrue(StringUtils.isAllUpperCase("AB"));

在使用它们时,请记住这一点。

6. 总结

在这篇文章中,我们探讨了在Java中检查字符串是否全为大写或小写的不同方法。转换和比较方法直观易懂。但如果输入字符串较长,我们可能希望遍历字符并尽早停止以提高性能。

如往常一样,这里展示的所有代码片段可在GitHub上找到。