ArrayList contains case sensitivity
我目前正在使用属于ArrayList类的contains方法进行搜索。 有没有办法使此搜索在Java中不区分大小写? 我发现在C#中可以使用OrdinalIgnoreCase。 是否有等效的Java或另一种方法?
谢谢。
您可以像使用其他任何ArrayList一样使用它。您可以将该列表传递给其他代码,并且外部代码不必了解任何字符串包装器类。
1 2 3 4 5 6 7 8 9 10 |
在Java8中,使用anyMatch
1 2 3 4 |
如果您使用的是Java 8,请尝试:
1 2 3 | List<String> list = ...; String searchStr = ...; boolean containsSearchStr = list.stream().filter(s -> s.equalsIgnoreCase(searchStr)).findFirst().isPresent(); |
传统上,您可以开发自己的逻辑来比较
1 2 3 4 5 6 7 8 9 10 11 |
为什么不应该使用一些直接且方便的方式,例如不区分大小写的比较器使用如下所示的SortedSet?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
在这种特殊情况下,将比较两个不同的集合而忽略大小写并返回
看一下Java API,没有包含这种方法。
但是您至少可以做两件事:
编写您自己的contains方法,该方法应遍历ArrayList实体,并进行手动检查。
假设您有一个
我能想到的唯一方法是在String周围创建一个非常轻巧的包装类,并覆盖equals和hashcode以忽略大小写,并尽可能利用
您可以使用collections4(apache)中的IterableUtils和Predicate。
1 2 3 4 5 6 | 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
对于java8
list.stream()。anyMatch(s-> s.equalsIgnoreCase(yourString))
对于
因此,例如,您可以使用这样的类(代码可能仍包含一些错字)
就我而言,由于ArrayList中的所有字符串均为小写形式,因此我只需对contains()参数执行String.toLowerCase()方法。像这样:
如您所见,如果arrayList具有upperCase字符串,则可以做相反的事情:
使用这种方法,您不需要覆盖任何内容。当您的arrayList包含大小写混合时,例外。
另一个解决方案:
您还应该考虑使用Set而不是List。
2
3
4
5
6
7
8
9
10
11
12
13
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();
}
}
2
3
// your code here
}
2
3
// your code here
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@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;
}
}
ArrayList的contains()方法通过在您提供的对象上调用equals()方法(而不是数组中的对象)来检查是否相等。因此,一种有点怪异的方法是围绕String对象创建一个包装器类,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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(); } } |
然后,您可以使用它来执行测试。示例"手动"测试用例:
1 2 3 4 5 6 7 8 9 | 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"))); } } |
我会这样:
1 2 3 | public boolean isStringInList(final List<String> myList, final String stringToFind) { return myList.stream().anyMatch(s -> s.equalsIgnoreCase(stringToFind)); } |
不要重新发明轮子。 使用经过良好测试的API。 为了您的目的,请使用Apache Commons StringUtils。
从Javadoc:
将给定的字符串与searchStrings的CharSequences变量比较
如果字符串等于任何searchStrings,则返回true,忽略大小写。
1 2 3 4 5 6 7 8 | 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 |
不需要附加功能,可以通过将比较的字符串转换为大写或小写字母来实现所需的结果
(我知道这已在评论中提出,但并未提供完整答案)
例如:根据JTextField提供的输入过滤JList内容时忽略大小写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | 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. */ } |
这是将列表项转换为小写字母的最佳方法。转换后,您将使用包含方法。喜欢
1 2 3 | List<String> name_list = new ArrayList<>(); name_list.add("A"); name_list.add("B"); |
使用上面创建的
1 2 3 4 5 6 7 8 9 10 11 12 | 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 } } |
第一种方式
1 2 3 4 |
第二路
1 2 3 4 |
如果您不想创建新函数,可以尝试以下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 } } |
通过使用compareToIgnoreCase(http://docs.oracle.com/javase/1.3/docs/api/java/lang/String.html#compareToIgnoreCase%28java.lang.String%29),您应该能够执行想要的操作!