ArrayList 中不區分大小寫的搜索
一、概述
使用ArrayList
時,在列表中搜索元素是標準操作。 contains()
方法讓我們知道列表對像是否包含我們要查找的元素。
在本教程中,我們將探討如何在不區分大小寫的情況下在ArrayList<String>
對像中搜索字符串。
二、問題簡介
在內部, ArrayList.contains()
方法使用equals()
方法來確定列表是否具有給定元素。如果ArrayList
中的所有元素都是字符串,即在使用ArrayList<String>
時, contains()
方法會區分大小寫地搜索給定的字符串。讓我們通過一個例子來快速理解它。
假設我們有一個包含六個字符串的List
對象:
List<String> LANGUAGES = Arrays.asList("Java", "Python", "Kotlin", "Ruby", "Javascript", "Go");
當我們檢查LANGUAGES
是否包含“jAvA”
時, contains()
方法報告false
,因為“jAvA”
不等於“Java”
:
String searchStr = "jAvA";
boolean result = LANGUAGES.contains(searchStr);
assertFalse(result);
在本教程中,讓我們學習一些在ArrayList<String>
實例中搜索字符串而不關心大小寫的方法。
為簡單起見,我們將使用單元測試斷言來驗證解決方案是否按預期工作。
那麼接下來,讓我們看看他們的行動。
3.使用流API
Java Stream API 提供了許多方便的接口,使我們能夠輕鬆地將集合作為流處理。它在 Java 8 及更高版本上可用。
例如,我們可以使用Stream
的anyMatch()
方法進行不區分大小寫的字符串搜索:
String searchStr = "koTliN";
boolean result = LANGUAGES.stream().anyMatch(searchStr::equalsIgnoreCase);
assertTrue(result);
正如我們在上面的示例中看到的,我們在LANGUAGES
列表中搜索字符串“ koTliN
”。然後,如果我們運行它,測試就會通過。
值得一提的是,我們傳遞給anyMatch()
方法的searchStr::equalsIgnoreCase
是一個方法引用。將為流中的每個字符串元素調用searchStr.equalsIgnoreCase()
方法。
4. 創建實用方法
我們已經看到 Stream API 可以直接解決這個問題。但是,如果我們的 Java 版本低於 8,則無法使用 Stream API。在這種情況下,解決該問題的經典方法是創建一個實用方法:
public class IgnoreCaseSearchUtil {
public static boolean ignoreCaseContains(List<String> theList, String searchStr) {
for (String s : theList) {
if (searchStr.equalsIgnoreCase(s)) {
return true;
}
}
return false;
}
}
如上面的代碼所示,我們在 for 循環中檢查給定列表中的每個字符串元素。一旦某個元素不區分大小寫地等於searchStr
,該方法將立即返回true
,而不檢查列表中的其他元素。
接下來,讓我們創建一個測試來驗證它是否按預期工作:
String searchStr = "ruBY";
boolean result = IgnoreCaseSearchUtil.ignoreCaseContains(LANGUAGES, searchStr);
assertTrue(result);
這次,我們在列表中搜索字符串“ ruBY
”。同樣,如果我們運行它,測試就會通過。
5. 創建ArrayList<String>
的子類
到目前為止,我們已經學習了兩種方法來確定ArrayList<String>
對像是否包含忽略大小寫的給定字符串。這兩種解決方案都非常容易理解。但是,如果我們需要在項目中經常執行此操作,則必須多次調用實用程序方法或 Stream API 的anyMatch()
方法。
如果是這種情況,我們可能想要創建一個特定的ArrayList<String>
類型,它本身支持不區分大小寫的contains()
方法。
那麼接下來,讓我們創建一個ArrayList<String>
的子類:
public class IgnoreCaseStringList extends ArrayList<String> {
public IgnoreCaseStringList() {
}
public IgnoreCaseStringList(Collection<? extends String> c) {
super(c);
}
@Override
public boolean contains(Object o) {
String searchStr = (String) o;
for (String s : this) {
if (searchStr.equalsIgnoreCase(s)) {
return true;
}
}
return false;
}
}
在上面的代碼中我們可以看到, IgnoreCaseStringList
類繼承了ArrayList<String>.
我們創建了兩個構造函數來更輕鬆地初始化IgnoreCaseStringList
實例。此外,為了使IgnoreCaseStringList
支持不區分大小寫的contains()
,我們重寫了contains()
方法。實施對我們來說並不陌生。它與我們學習的實用方法非常相似。
接下來,讓我們測試IgnoreCaseStringList
是否有效:
String searchStr = "pYtHoN";
List<String> ignoreCaseList = new IgnoreCaseStringList(LANGUAGES);
boolean result = ignoreCaseList.contains(searchStr);
assertTrue(result);
如我們所見,在初始化IgnoreCaseList
實例後,我們可以簡單地調用contains()
方法來搜索給定的字符串,不區分大小寫。當我們執行上面的測試時,它通過了。因此, IgnoreCaseStringList
巧妙地完成了這項工作。
值得一提的是, IgnoreCaseList
方法帶來了另一個好處。它也使containsAll()
方法區分大小寫。這是因為containsAll()
方法是在ArrayList
的超類型AbstractCollection
類中實現的。此外,它在內部調用contains()
方法:
public boolean containsAll(Collection<?> c) {
Iterator var2 = c.iterator();
Object e;
do {
if (!var2.hasNext()) {
return true;
}
e = var2.next();
} while(this.contains(e));
return false;
}
最後我們寫一個測試來驗證一下:
boolean resultContainAll = ignoreCaseList.containsAll(Arrays.asList("pYtHon", "jAvA", "koTliN", "ruBY"));
assertTrue(resultContainAll);
另一方面,如果我們希望 Stream API 和實用方法方法也支持區分大小寫的containsAll()
特性,我們必須自己實現它,例如,通過添加另一個實用方法。
六,結論
在本文中,我們探討瞭如何在ArrayList<String>
中執行不區分大小寫的搜索。我們已經通過示例學習了三種解決問題的方法。
與往常一樣,本文中提供的所有代碼片段都可以在 GitHub 上找到。