web-dev-qa-db-ja.com

.containsメソッドで大文字小文字を無視するオプション?

.contains()メソッドで大文字と小文字を区別しないオプションはありますか?

ArrayListのDVDオブジェクトがあります。各DVDオブジェクトにはいくつかの要素があり、そのうちの1つはタイトルです。そして、特定のタイトルを検索するメソッドがあります。動作しますが、大文字と小文字を区別しません。

39
trama

文字列を検索するときに大文字と小文字を無視することを意味すると思いますか?

私は何も知りませんが、検索する文字列を小文字または大文字に変換してから検索することができます。

// s is the String to search into, and seq the sequence you are searching for.
bool doesContain = s.toLowerCase().contains(seq);

編集:ライアン・シッパーが提案したように、状況に応じてseq.toLowerCase()を実行することもできます(おそらくより良いでしょう)。

26
Spam

Java 8を使用している場合

List<String> list = new ArrayList<>();

boolean containsSearchStr = list.stream().anyMatch("search_value"::equalsIgnoreCase);
64
private boolean containsIgnoreCase(List<String> list, String soughtFor) {
    for (String current : list) {
        if (current.equalsIgnoreCase(soughtFor)) {
            return true;
        }
    }
    return false;
}
12

これはおそらく特定の問題に最適な方法ではありませんが、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で行われています。次の手法のいずれかを試してみることをお勧めします。

  1. CollatorおよびCollationKeyクラスを学びます。
  2. Javaの世界にとどまること以外に選択肢がない場合は、DVDにメソッドboolean matches(String fragment)を追加します。DVDに一致するものを教えてください。
  3. データベースを使用します。大文字と小文字を区別しない照合をサポートしている場合は、titleテーブルのDVD列をそのように宣言します。 JDBC、Hibernate、JPA、Spring Dataのいずれかを選択します。
  4. データベースがOracleなどの高度なテキスト検索をサポートしている場合は、それを使用します。
  5. Java world)に戻り、_Apache Lucene_を使用し、場合によっては_Apache Solr_を使用します。
  6. 大文字と小文字を区別しない一致用に調整された言語を使用します。

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を考慮する必要があるため、下位のケーシングは低速です。少なくとも、パターンもマッチャーもありません。

4
Eric Jablow

Java 8では、Streamインターフェースを使用できます。

return dvdList.stream().anyMatch(d -> d.getTitle().equalsIgnoreCase("SomeTitle"));
4
Paul Bonneau

両方のオペランドを小文字(または大文字)に変換する直感的なソリューションには、各アイテムの追加の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;
}
2
BladeCoder

常にStringオブジェクトを取得すること、またはListで作業しているオブジェクトが大文字小文字を無視する方法を実装することを保証することはできません。

コレクション内のStringsを大文字と小文字を区別しないものと比較する場合は、コレクションを反復処理し、大文字と小文字を区別せずに比較する必要があります。

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
    }
}
2
Makoto
 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;
 }
0
Br0thazS0ul

Java 8の場合、以下のようなソリューションがもう1つあります

List<String> list = new ArrayList<>();
String searchTerm = "dvd";

if(String.join(",", list).toLowerCase().contains(searchTerm)) {
  System.out.println("Element Present!");
}
0
Pavan