【问题标题】:Option to ignore case with .contains method?使用 .contains 方法忽略大小写的选项?
【发布时间】:2013-03-27 07:49:06
【问题描述】:

.contains() 方法是否可以忽略大小写?

我有一个 DVD 对象的ArrayList。每个 DVD 对象都有几个元素,其中一个是标题。我有一个搜索特定标题的方法。它有效,但我希望它不区分大小写。

【问题讨论】:

  • 不,没有。但是,如果您解释了您要做什么,我们可能会建议一种替代方法来满足您的需求。
  • 要在 Java 中执行不区分大小写的匹配,可以使用 String.matches 和正则表达式 .*(?i:abcd).*。将abcd 替换为您的字符串。

标签: java list arraylist


【解决方案1】:

如果您使用的是 Java 8

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

boolean containsSearchStr = list.stream().anyMatch("search_value"::equalsIgnoreCase);

【讨论】:

    【解决方案2】:

    我猜你的意思是在搜索字符串时忽略大小写?

    我不知道,但是您可以尝试将要搜索的字符串转换为小写或大写,然后搜索。

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

    编辑: 正如 Ryan Schipper 建议的那样,您也可以(并且可能会更好)执行 seq.toLowerCase(),具体取决于您的情况。

    【讨论】:

    【解决方案3】:
    private boolean containsIgnoreCase(List<String> list, String soughtFor) {
        for (String current : list) {
            if (current.equalsIgnoreCase(soughtFor)) {
                return true;
            }
        }
        return false;
    }
    

    【讨论】:

    【解决方案4】:

    在 Java 8 中,您可以使用 Stream 接口:

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

    【讨论】:

      【解决方案5】:

      这可能不是解决您的特定问题的最佳方法,但您可以使用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. 了解CollatorCollationKey 课程。
      2. 如果您别无选择,只能留在 Java 世界,请在 DVD 中添加一个方法,boolean matches(String fragment)。让 DVD 告诉您匹配的内容。
      3. 使用数据库。如果它支持不区分大小写的排序规则,则以这种方式声明DVD 表的title 列。使用 JDBC 或 Hibernate 或 JPA 或 Spring Data,任您选择。
      4. 如果数据库支持高级文本搜索,如 Oracle,请使用它。
      5. 回到 Java 世界,使用 Apache Lucene 和可能的 Apache Solr
      6. 使用针对不区分大小写匹配而调整的语言。

      如果您可以等到 Java 8,请使用 lambda 表达式。您可以通过这种方式构建正则表达式来避免我在上面使用的 Pattern 和 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。至少你没有模式和匹配器。

      【讨论】:

        【解决方案6】:

        你不能保证你总是会得到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
            }
        }
        

        【讨论】:

        • 如果他使用List&lt;String&gt;,他就会知道。
        • ...此时,您可以在List 中的单个元素上使用String 方法,但不能直接在List 上使用。
        【解决方案7】:

        将两个操作数转换为小写(或大写)的直观解决方案具有为每个项目实例化一个额外的 String 对象的效果,这对于大型集合来说效率不高。此外,正则表达式比简单的字符比较慢一个数量级。

        String.regionMatches() 允许以不区分大小写的方式比较两个字符串区域。使用它,可以编写不区分大小写的“包含”方法的有效版本。以下方法是我使用的;它基于 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;
        }
        

        【讨论】:

          【解决方案8】:

          我知道我参加聚会有点晚了,但在 Kotlin 中你可以轻松使用:

          fun Collection<String>.containsIgnoreCase(item: String) = any {
              it.equals(item, ignoreCase = true)
          }
          
          
          val list = listOf("Banana")
          
          println(list.contains("banana"))
          println(list.containsIgnoreCase("BaNaNa"))
          

          【讨论】:

            【解决方案9】:

            Kotlin 开发人员,请使用 any / none

            private fun compareCategory(
                    categories: List<String>?,
                    category: String
                ) = categories?.any { it.equals(category, true) } ?: false
            

            【讨论】:

              【解决方案10】:

              使用 Kotlin 扩展功能的强大功能非常简单,这个答案可能对 Java 和 Kotlin 开发人员有所帮助。

              inline fun List<String>.contains(text: String, ignoreCase: Boolean = false) = this.any { it.equals(text, ignoreCase) }
              
              // Usage
              list.contains("text", ignoreCase = true)
              

              【讨论】:

                【解决方案11】:

                您可以使用 stream() 将 contains() 替换为 equalsIgnoreCase,如下所示

                    List<String> names = List.of("One","tWo", "ThrEe", "foUR", "five", "Six", "THREE");
                    boolean contains = names.stream().filter(i -> i.equalsIgnoreCase("three")).collect(Collectors.toList()).size() > 0;
                

                【讨论】:

                  【解决方案12】:
                   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;
                   }
                  

                  【讨论】:

                    【解决方案13】:

                    对于 Java 8,您可以有如下另一种解决方案

                    List<String> list = new ArrayList<>();
                    String searchTerm = "dvd";
                    
                    if(String.join(",", list).toLowerCase().contains(searchTerm)) {
                      System.out.println("Element Present!");
                    }
                    

                    【讨论】:

                      【解决方案14】:

                      如果您正在寻找包含 & 不等于,那么我会提出以下解决方案。 唯一的缺点是,如果您在以下解决方案中的 searchItem 是“DE”,那么它也会匹配

                          List<String> list = new ArrayList<>();
                          public static final String[] LIST_OF_ELEMENTS = { "ABC", "DEF","GHI" };
                          String searchItem= "def";
                      
                           if(String.join(",", LIST_OF_ELEMENTS).contains(searchItem.toUpperCase())) {
                                  System.out.println("found element");
                                  break;
                          }
                      

                      【讨论】:

                        【解决方案15】:

                        dvdList 和您的searchString 进行空检查

                            if (!StringUtils.isEmpty(searchString)) {
                                return Optional.ofNullable(dvdList)
                                               .map(Collection::stream)
                                               .orElse(Stream.empty())
                                               .anyMatch(dvd >searchString.equalsIgnoreCase(dvd.getTitle()));
                              }
                        

                        【讨论】:

                          【解决方案16】:

                          对于 Java 8+,我建议使用以下库方法。

                          org.apache.commons.lang3.StringUtils

                          list.stream()
                             .filter(text -> StringUtils.containsIgnoreCase(text, textToSearch))
                          

                          【讨论】:

                            【解决方案17】:

                            您可以对此应用小技巧。
                            将所有字符串更改为相同大小写大写小写
                            对于 C# 代码:

                            列出 searchResults = sl.FindAll(s => s.ToUpper().Contains(seachKeyword.ToUpper()));

                            对于 Java 代码:

                            import java.util.*; 
                            
                            class Test
                            {
                                public static void main(String[] args)
                                {
                                    String itemCheck="check";
                                    ArrayList<String> listItem =new ArrayList<String>();
                                    listItem.add("Check");
                                    listItem.add("check");
                                    listItem.add("CHeck");
                                    listItem.add("Make");
                                    listItem.add("CHecK");
                                    for(String item :listItem)
                                    {
                                        if(item.toUpperCase().equals(itemCheck.toUpperCase()))
                                        {
                                            System.out.println(item);
                                        }
                                    }
                            
                                }
                            
                            }
                            

                            【讨论】:

                            • 这是一个关于如何在 Java 中而不是在 C# 中的问题。
                            • 好的。同样的技巧也可以应用于java。现在,我还添加了 java 代码。 @PeterNeyens
                            猜你喜欢
                            • 2013-10-09
                            • 2021-12-26
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2011-09-09
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多