ArrayList包含区分大小写

时间:2012-01-05 23:31:49

标签: java arraylist

我目前正在使用属于ArrayList类的contains方法进行搜索。有没有办法让这个搜索案例在java中不敏感?我发现在C#中可以使用OrdinalIgnoreCase。有没有Java等价物,或其他方式来做到这一点? 感谢。

20 个答案:

答案 0 :(得分:64)

您可以像使用任何其他ArrayList一样使用它。您可以将此List传递给其他代码,外部代码不必理解任何字符串包装类。

public class CustomStringList3 extends ArrayList<String> {
    @Override
    public boolean contains(Object o) {
        String paramStr = (String)o;
        for (String s : this) {
            if (paramStr.equalsIgnoreCase(s)) return true;
        }
        return false;
    }
}

答案 1 :(得分:33)

如果您使用的是Java 8,请尝试:

List<String> list = ...;
String searchStr = ...;
boolean containsSearchStr = list.stream().filter(s -> s.equalsIgnoreCase(searchStr)).findFirst().isPresent();

答案 2 :(得分:29)

在Java8中,使用anyMatch

List<String> list = Arrays.asList("XYZ", "ABC");
String matchingText = "xYz";

boolean isMatched = list.stream().anyMatch(matchingText::equalsIgnoreCase);

答案 3 :(得分:14)

传统上,您可以开发自己的逻辑来比较ArrayList所持有的字符串。可能有几种方法可以实现,如下所示。

public boolean containsCaseInsensitive(String strToCompare, ArrayList<String>list)
{
    for(String str:list)
    {
        if(str.equalsIgnoreCase(strToCompare))
        {
            return(true);
        }
    }
    return(false);
}

为什么不应该使用像SortedSet这样直接方便的方式,如下所示case insensitive comparator

Set<String> a = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);

a.add("A");
a.add("B");
a.add("C");


Set<String> b = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);

b.add("a");
b.add("b");
b.add("c");

System.out.println(b.equals(a));

比较两个不同的集合,忽略大小写并返回true,在这种特殊情况下,你的比较可以毫无问题地进行。

答案 4 :(得分:9)

查看Java API,没有包含此类方法。

但你至少可以做两件事:

  1. 使用您自己的或者equalsIgnoreCase(str)覆盖ArrayList对象中的equals方法
  2. 编写自己的contains方法,该方法应遍历您的ArrayList实体,并进行手动检查。

    ArrayList<String> list = new ArrayList<String>();
    ...
    containsIgnoreCase("a", list);
    
    public boolean containsIgnoreCase(String str, ArrayList<String> list){
        for(String i : list){
            if(i.equalsIgnoreCase(str))
                return true;
        }
        return false;
    }
    

答案 5 :(得分:7)

假设您有ArrayList<String>

关于我能想到的唯一方法是在String周围创建一个非常轻的包装类,并覆盖equals和hashcode以忽略大小写,尽可能利用equalsIgnoreCase()。然后你会有一个ArrayList<YourString>。虽然这有点丑陋。

答案 6 :(得分:3)

您可以使用collections4(apache)中的IterableUtils和Predicate。

List<String> pformats= Arrays.asList("Test","tEst2","tEsT3","TST4");

Predicate<String> predicate  = (s) -> StringUtils.equalsIgnoreCase(s, "TEST");
if(IterableUtils.matchesAny(pformats, predicate)) {
    // do stuff
}

IterableUtils(collections4):org.apache.commons.collections4.IterableUtils.html

答案 7 :(得分:2)

另一种解决方案:

public class IgnorecaseList extends ArrayList<String>{

    @Override
    public boolean contains(Object o) {
        return indexOf(o) >= 0;
    } 

    @Override
    public int indexOf(Object o) {
        if(o instanceof String){
            for (int i = 0; i < this.size(); i++) {
                if(((String)o).equalsIgnoreCase(get(i))){
                    return i;
                }
            }
        }
        return -1;
    }
}

contains()方法使用indexOf ...在此sollution中,您还可以知道位置是字符串的位置。 list.add("a") - &gt; list.indexOf("A") == 0list.indexOf("a") == 0 ..

您还应该考虑使用Set而不是List。

答案 8 :(得分:2)

ArrayList的contains()方法通过在您提供的对象上调用equals()方法来检查相等性(而不是数组中的对象)。因此,稍微犹豫不决的方法是在String对象周围创建一个包装类,如下所示:

class InsensitiveStringComparable {
    private final String val;

    public InsensitiveStringComparable(String val) {
        this.val = val;
    }

    @Override
    public boolean equals(Object x) {
        if (x == this)
            return true;
        else if (x == null)
            return false;
        else if (x instanceof InsensitiveStringComparable)
            return ((InsensitiveStringComparable) x).val.equalsIgnoreCase(val);
        else if (x instanceof String)
            /* Asymmetric equals condition */
            return val.equalsIgnoreCase((String) x);
        else
            return false;
    }

    @Override
    public int hashCode() {
        return val.toUpperCase().hashCode();
    }
}

然后您可以使用它来执行测试。示例&#34;手册&#34;测试用例:

public class Test {
    public static void main(String[] args) {
        ArrayList<Object> a = new ArrayList<Object>();
        a.add("test");
        System.out.println(a.contains(new InsensitiveStringComparable("TEST")));
        System.out.println(a.contains(new InsensitiveStringComparable("tEsT")));
        System.out.println(a.contains(new InsensitiveStringComparable("different")));
    }
}

答案 9 :(得分:2)

contains方法基于equals中存储的对象的ArrayList方法返回的内容。所以,如果您使用equals使用不区分大小写的比较的对象,则可以。

所以你可以使用像这样的类(代码可能仍然包含一些拼写错误)

public class CaseInsensitiveString{
  private final String contents;

  public CaseInsensitiveString( String contents){ this.contents = contents; }

  public boolean equals( Object o ){
    return o != null && o.getClass() == getClass() && o.contents.equalsIgnoreCase( contents);
  }

  public int hashCode(){
    return o.toUpperCase().hashCode();
  }
}

答案 10 :(得分:2)

适用于java8

list.stream()。anyMatch(s - &gt; s.equalsIgnoreCase(yourString))

For&lt; java8

  • 按照 Aaron J Lang
  • 的建议
  • 或者,如果您知道列表的大小写(全部大写/全部更低),那么在比较之前将搜索字符串转换为适当的大小写

答案 11 :(得分:2)

在我的例子中,由于ArrayList中的所有字符串都是小写的,我只是在contains()参数上执行String。 toLowerCase()方法。像这样:

If (yourArrayList.contains (parameterInput.toLowerCase()) {
    // your code here
}

如您所见,如果您的arrayList具有upperCase字符串,则可以执行oposite:

If (yourArrayList.contains (parameterInput.toUpperCase ()) {
    // your code here
}

使用此方法,您无需覆盖任何内容。例如,当您的arrayList混合使用大写和小写时。

答案 12 :(得分:1)

没有必要使用附加功能,可以通过将比较的字符串转换为大写或小写来实现所需的结果

(我知道这些已在评论中提出,但没有作为答案彻底提供)

Ex:根据JTextField提供的输入过滤JList内容时忽略大小写:

private ArrayList<String> getFilteredUsers(String filter, ArrayList<User> users) {
    ArrayList<String> filterUsers = new ArrayList<>();
    users.stream().filter((user) -> (user.getUsername().toUpperCase().contains(filter.toUpperCase()))).forEach((user)-> {
        filterUsers.add(user.getUsername());
    });
    this.userList.setListData(filterUsers.toArray());
    return filterUsers;
    /** 
     *  I see the redundancy in returning the object... so even though,
     *  it is passed by reference you could return type void; but because
     *  it's being passed by reference, it's a relatively inexpensive
     *  operation, so providing convenient access with redundancy is just a 
     *  courtesy, much like putting the seat back down. Then, the next
     *  developer with the unlucky assignment of using your code doesn't 
     *  get the proverbially dreaded "wet" seat.
     */
}

答案 13 :(得分:1)

我会这样做:

public boolean isStringInList(final List<String> myList, final String stringToFind) {
    return myList.stream().anyMatch(s -> s.equalsIgnoreCase(stringToFind));
}  

答案 14 :(得分:1)

不要重新发明轮子。使用经过良好测试的API。为您的目的使用Apache Commons StringUtils

从Javadoc: 将给定的字符串与searchStrings的CharSequences变量比较 如果字符串等于任何searchStrings,则返回true,忽略大小写。

import org.apache.commons.lang3.StringUtils;
...
StringUtils.equalsAnyIgnoreCase(null, (CharSequence[]) null) = false
StringUtils.equalsAnyIgnoreCase(null, null, null)    = true
StringUtils.equalsAnyIgnoreCase(null, "abc", "def")  = false
StringUtils.equalsAnyIgnoreCase("abc", null, "def")  = false
StringUtils.equalsAnyIgnoreCase("abc", "abc", "def") = true
StringUtils.equalsAnyIgnoreCase("abc", "ABC", "DEF") = true

答案 15 :(得分:0)

这是将列表项转换为小写的最佳方法。转换后,您将使用包含方法。像

List<String> name_list = new ArrayList<>();
name_list.add("A");
name_list.add("B");

使用上面创建的name_list

创建小写列表
List<String> name_lowercase_list = new ArrayList<>();
for(int i =0 ; i<name_list.size(); i++){
 name_lowercase_list.add(name_list.get(i).toLowerCase().toString()); 
}

for(int i =0 ; i<name_list.size(); i++){
  String lower_case_name =  name_list.get(i).toLowerCase().toString();
  if(name_list.get(i).contains(your compare item) ||
   name_lowercase_list.get(i).contains(your compare item) ){
     //this will return true
   }
}

答案 16 :(得分:0)

如果您不想创建新功能,可以尝试以下方法:

List<String> myList = new ArrayList<String>(); //The list you're checking
String wordToFind = "Test"; //or scan.nextLine() or whatever you're checking

//If your list has mix of uppercase and lowercase letters letters create a copy...
List<String> copyList = new ArrayList<String>();
for(String copyWord : myList){
   copyList.add(copyWord.toLowerCase());
}

for(String myWord : copyList){
   if(copyList.contains(wordToFind.toLowerCase()){
      //do something
   }
}

答案 17 :(得分:0)

第一种方法

  List<String> list = Arrays.asList("XYZ", "ABC");
    String matchingText = "XYZ1";
        boolean isMatched = list.stream().anyMatch(matchingText::equalsIgnoreCase);
        System.out.println(isMatched);

第二种方式

List<String> list1= Arrays.asList("XYZ", "ABC");
String searchStr = "abC";
boolean containsSearchStr = list1.stream().filter(searchStr::equalsIgnoreCase).findFirst().isPresent();
System.out.println(containsSearchStr);

答案 18 :(得分:0)

虽然这个问题是专门针对 Java 提出的,但 Kotlin 中也存在同样的问题。

您可以为此使用适用于 List、Array 和 ArrayList 的扩展

fun Array<String>.contains(element: String, ignoreCase: Boolean): Boolean {
  forEach { if (it.equals(element, ignoreCase = ignoreCase)) return true }
  return false
}

答案 19 :(得分:-1)

通过使用compareToIgnoreCase,http://docs.oracle.com/javase/1.3/docs/api/java/lang/String.html#compareToIgnoreCase%28java.lang.String%29,你应该能够做你想做的事情!