1. 概述

在Java中,列表(List) 是一个非常常用的数据结构。有时,我们需要不区分大小写地检查一个字符串是否存在于一个字符串列表中。

在这篇简短教程中,我们将探讨解决这个常见问题的各种方法和策略。

2. 问题介绍

列表提供了方便的contains() 方法来检查给定值是否存在于列表中。实际上,***contains()方法通过equals()*方法将给定对象与列表中的每个元素进行比较**。

因此,如果列表是*List,contains()*方法会进行区分大小写的字符串比较。例如,我们有一个电影标题列表:

List<String> THE_LIST = List.of("Game of Thrones", "Forrest Gump", "American Beauty", "Pretty Woman", "Catch Me If You Can");

当我们使用contains()方法检查是否包含“catch me if you can"时,它返回false:

assertFalse(THE_LIST.contains("catch me if you can"));

然而,在许多情况下,我们希望*contains()方法支持忽略大小写的检查。遗憾的是,标准的contains()*方法并没有提供这种选项。接下来,我们将看看如何实现我们的目标。

为了简单起见,我们将利用单元测试断言来验证每种方法是否按预期工作。

3. 使用循环

我们知道String类提供了equalsIgnoreCase() 方法,用于进行不区分大小写的等价性检查。因此,解决我们问题的第一个想法是*遍历列表,使用equalsIgnoreCase()方法检查每个元素和给定值:*

boolean ignoreCaseContainsForLoop(List<String> list, String value) {
    for (String e : list) {
        if (value.equalsIgnoreCase(e)) {
            return true;
        }
    }
    return false;
}

如代码所示,我们使用了for循环检查列表中的每个元素。一旦equalsIgnoreCase()方法在某个元素上报告为true,我们立即返回true并停止进一步检查。如果没有在列表的所有元素中找到匹配项,方法将返回false

我们可以创建一个测试来验证*ignoreCaseContainsForLoop()*方法是否按预期工作:

assertTrue(ignoreCaseContainsForLoop(THE_LIST, "CATCH me if you CAN"));
assertTrue(ignoreCaseContainsForLoop(THE_LIST, "game of thrones"));
assertFalse(ignoreCaseContainsForLoop(THE_LIST, "The Godfather"));

4. 使用流API

从Java 8版本开始引入了流(Stream) API。流API提供了一种高效且有效处理集合的强大机制。

接下来,我们使用流API解决这个问题:

assertTrue(THE_LIST.stream().anyMatch(e -> e.equalsIgnoreCase("CATCH me if you CAN")));

如演示所示,我们利用了流API的anyMatch()方法来确认是否存在符合我们条件的元素。**我们使用lambda表达式将我们的条件传达给anyMatch()方法。

另外,*我们也可以选择使用方法引用将谓词传递给anyMatch()方法:*

assertTrue(THE_LIST.stream().anyMatch("game of thrones"::equalsIgnoreCase));
assertFalse(THE_LIST.stream().anyMatch("The Godfather"::equalsIgnoreCase));

5. 总结

在这篇文章中,我们探讨了两种执行不区分大小写检查以确定字符串列表中是否包含特定字符串的方法。

首先,我们通过构建基于传统循环的方法来解决这个问题。然后,我们利用流API的*anyMatch()*方法的力量来达成同样的目标。

如往常一样,所有示例的完整源代码可在GitHub上查看这里