问题
I am currently using the contains method belonging to the ArrayList class for making a search. Is there a way to make this search case insensitive in java? I found that in C# it is possible to use OrdinalIgnoreCase. Is there a java equivalent, or another way to do this? Thanks.
回答1:
You can use this exactly like you'd use any other ArrayList. You can pass this List out to other code, and external code won't have to understand any string wrapper classes.
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;
}
}
回答2:
In Java8, using anyMatch
List<String> list = Arrays.asList("XYZ", "ABC");
String matchingText = "xYz";
boolean isMatched = list.stream().anyMatch(matchingText::equalsIgnoreCase);
回答3:
If you're using Java 8, try:
List<String> list = ...;
String searchStr = ...;
boolean containsSearchStr = list.stream().filter(s -> s.equalsIgnoreCase(searchStr)).findFirst().isPresent();
回答4:
Traditionally, you can develop your own logic to compare strings held by an ArrayList. There may be several ways to do so like the one shown below.
public boolean containsCaseInsensitive(String strToCompare, ArrayList<String>list)
{
for(String str:list)
{
if(str.equalsIgnoreCase(strToCompare))
{
return(true);
}
}
return(false);
}
Why shouldn't be used some direct and convenient ways like a SortedSet as shown below with a 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));
Would compare two different sets ignoring case and return true
, in this particular situation and your comparision would work without any issue.
回答5:
Looking at the Java API, there is no such method for contains.
But you could do at least two things:
- Override the equals method in your ArrayList object with your own, or equalsIgnoreCase(str)
Write your own contains method, which should iterate through your ArrayList entities, and do a manual check.
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; }
回答6:
Assuming you have an ArrayList<String>
About the only way I can think of to do this would be to create a very light wrapper class around a String and override equals and hashcode to ignore case, leveraging equalsIgnoreCase()
where possible. Then you would have an ArrayList<YourString>
. It's kinda an ugly idea though.
回答7:
You can use IterableUtils and Predicate from collections4 (apache).
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
回答8:
The contains
method is based on what the equals
method of the objects stored in your ArrayList
returns. So yes it is possible if you use objects where equals
uses a case insensitive comparison.
So you could for example use a class like this (code might still contain some typos)
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();
}
}
回答9:
ArrayList's contains() method checks equality by calling equals() method on the object you provide (NOT the objects in the array). Therefore, a slightly hackish way is to create a wrapper class around the String object, like this:
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();
}
}
Then you can use it to perform your test. Example "manual" test case:
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")));
}
}
回答10:
Another solution:
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()
method uses indexOf... In this sollution you can also know in where position is the string. list.add("a")
-> list.indexOf("A") == 0
or list.indexOf("a") == 0
..
You should also consider using a Set instead of List.
回答11:
For java8
list.stream().anyMatch(s -> s.equalsIgnoreCase(yourString))
For < java8
- as suggested by Aaron J Lang above
- Or if you know case of your list ( all upper /all lower ) then convert the search string to appropriate case before comparing
回答12:
In my case, as all my strings in the ArrayList are in downcase, I just execute the String.toLowerCase() method on the contains() parameter. Like this:
If (yourArrayList.contains (parameterInput.toLowerCase()) {
// your code here
}
As you can see, you can do the oposite, if yout arrayList has upperCase strings:
If (yourArrayList.contains (parameterInput.toUpperCase ()) {
// your code here
}
Using this approach, you do not need to override anything. The exception is in the case when your arrayList have a mix of upper and lower cases.
回答13:
I would make it like so:
public boolean isStringInList(final List<String> myList, final String stringToFind) {
return myList.stream().anyMatch(s -> s.equalsIgnoreCase(stringToFind));
}
回答14:
There's no need to for the additional function, the desired results can be achieved by casting the compared strings to either uppercase or lowercase
(I know this has been suggested in the comments, but not thoroughly provided as an answer)
Ex: Ignores case while filtering the contents of a JList based on the input provided from a JTextField:
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.
*/
}
回答15:
Don't reinvent the wheel. Use well tested APIs. For your purpose use Apache Commons StringUtils.
From the Javadoc: Compares given string to a CharSequences vararg of searchStrings returning true if the string is equal to any of the searchStrings, ignoring case.
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
回答16:
Its a best way to convert your list item into lowercase. After convert you will use contain method. like
List<String> name_list = new ArrayList<>();
name_list.add("A");
name_list.add("B");
Create lowercase list using above created 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
}
}
回答17:
If you don't want to create a new function, you can try this method:
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
}
}
回答18:
1st way
List<String> list = Arrays.asList("XYZ", "ABC");
String matchingText = "XYZ1";
boolean isMatched = list.stream().anyMatch(matchingText::equalsIgnoreCase);
System.out.println(isMatched);
2nd way
List<String> list1= Arrays.asList("XYZ", "ABC");
String searchStr = "abC";
boolean containsSearchStr = list1.stream().filter(searchStr::equalsIgnoreCase).findFirst().isPresent();
System.out.println(containsSearchStr);
回答19:
By using compareToIgnoreCase, http://docs.oracle.com/javase/1.3/docs/api/java/lang/String.html#compareToIgnoreCase%28java.lang.String%29 you should be able to do what you want!
来源:https://stackoverflow.com/questions/8751455/arraylist-contains-case-sensitivity