.contains()
メソッドで大文字と小文字を区別しないオプションはありますか?
ArrayList
のDVDオブジェクトがあります。各DVDオブジェクトにはいくつかの要素があり、そのうちの1つはタイトルです。そして、特定のタイトルを検索するメソッドがあります。動作しますが、大文字と小文字を区別しません。
文字列を検索するときに大文字と小文字を無視することを意味すると思いますか?
私は何も知りませんが、検索する文字列を小文字または大文字に変換してから検索することができます。
// s is the String to search into, and seq the sequence you are searching for.
bool doesContain = s.toLowerCase().contains(seq);
編集:ライアン・シッパーが提案したように、状況に応じてseq.toLowerCase()を実行することもできます(おそらくより良いでしょう)。
Java 8を使用している場合
List<String> list = new ArrayList<>();
boolean containsSearchStr = list.stream().anyMatch("search_value"::equalsIgnoreCase);
private boolean containsIgnoreCase(List<String> list, String soughtFor) {
for (String current : list) {
if (current.equalsIgnoreCase(soughtFor)) {
return true;
}
}
return false;
}
これはおそらく特定の問題に最適な方法ではありませんが、String.matches(String regex)
メソッドまたは同等のマッチャーを使用できます。将来のタイトルから正規表現を作成するだけです。ここでは複雑になります。
_List<DVD> matchingDvds(String titleFragment) {
String escapedFragment = Pattern.quote(titleFragment);
// The pattern may have contained an asterisk, dollar sign, etc.
// For example, M*A*S*H, directed by Robert Altman.
Pattern pat = Pattern.compile(escapedFragment, Pattern.CASE_INSENSITIVE);
List<DVD> foundDvds = new ArrayList<>();
for (DVD dvd: catalog) {
Matcher m = pat.matcher(dvd.getTitle());
if (m.find()) {
foundDvds.add(dvd);
}
}
return foundDvds;
}
_
しかし、これは非効率的であり、純粋にJavaで行われています。次の手法のいずれかを試してみることをお勧めします。
Collator
およびCollationKey
クラスを学びます。boolean matches(String fragment)
を追加します。DVDに一致するものを教えてください。title
テーブルのDVD
列をそのように宣言します。 JDBC、Hibernate、JPA、Spring Dataのいずれかを選択します。Apache Lucene
_を使用し、場合によっては_Apache Solr
_を使用します。Java 8まで待つことができる場合、ラムダ式を使用します。このように正規表現を作成することで、上記で使用したPattern and Matcherクラスを回避できます。
_ String escapedFragment = Pattern.quote(titleFragment);
String fragmentAnywhereInString = ".*" + escapedFragment + ".*";
String caseInsensitiveFragment = "(?i)" + fragmentAnywhereInString;
// and in the loop, use:
if(dvd.getTitle().matches(caseInsensitiveFragment)) {
foundDvds.add(dvd);
}
_
しかし、これはパターンを何度もコンパイルします。すべてを下に向けるのはどうですか?
_if (dvd.getTitle().toLowerCase().contains(titleFragment.toLowerCase()))
_
おめでとうございます。トルコの問題を発見したばかりです。ロケールをtoLowerCase
で指定しない限り、Javaは現在のロケールを検出します。また、トルコ語のドットなしiおよびドット付きIを考慮する必要があるため、下位のケーシングは低速です。少なくとも、パターンもマッチャーもありません。
Java 8では、Streamインターフェースを使用できます。
return dvdList.stream().anyMatch(d -> d.getTitle().equalsIgnoreCase("SomeTitle"));
両方のオペランドを小文字(または大文字)に変換する直感的なソリューションには、各アイテムの追加のStringオブジェクトをインスタンス化する効果がありますが、これは大規模なコレクションには効率的ではありません。また、正規表現は、単純な文字の比較よりも桁違いに遅くなります。
String.regionMatches()
は、大文字と小文字を区別しない方法で2つの文字列領域を比較できます。これを使用すると、大文字と小文字を区別しない「contains」メソッドの効率的なバージョンを作成できます。次の方法は私が使用するものです。 Apache commons-langのコードに基づいています。
public static boolean containsIgnoreCase(final String str, final String searchStr) {
if (str == null || searchStr == null) {
return false;
}
final int len = searchStr.length();
final int max = str.length() - len;
for (int i = 0; i <= max; i++) {
if (str.regionMatches(true, i, searchStr, 0, len)) {
return true;
}
}
return false;
}
常にString
オブジェクトを取得すること、またはList
で作業しているオブジェクトが大文字小文字を無視する方法を実装することを保証することはできません。
コレクション内のString
sを大文字と小文字を区別しないものと比較する場合は、コレクションを反復処理し、大文字と小文字を区別せずに比較する必要があります。
String Word = "Some Word";
List<String> aList = new ArrayList<>(); // presume that the list is populated
for(String item : aList) {
if(Word.equalsIgnoreCase(item)) {
// operation upon successful match
}
}
private List<String> FindString(String stringToLookFor, List<String> arrayToSearchIn)
{
List<String> ReceptacleOfWordsFound = new ArrayList<String>();
if(!arrayToSearchIn.isEmpty())
{
for(String lCurrentString : arrayToSearchIn)
{
if(lCurrentString.toUpperCase().contains(stringToLookFor.toUpperCase())
ReceptacleOfWordsFound.add(lCurrentString);
}
}
return ReceptacleOfWordsFound;
}
Java 8の場合、以下のようなソリューションがもう1つあります
List<String> list = new ArrayList<>();
String searchTerm = "dvd";
if(String.join(",", list).toLowerCase().contains(searchTerm)) {
System.out.println("Element Present!");
}