Why not using instead a SortedSet with a case insensitive comparator ? With the String.CASE_INSENSITIVE_ORDER comparator
Your code is reduced to
Set<String> a = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
a.add("one");
a.add("three");
a.add("two");
Set<String> a1 = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
a1.add("ONE");
a1.add("two");
a1.add("THREE");
And your equals conditions should work without any issue
EDIT modified according to comments. Thanks to all of you to correct me.
Answer from Riduidel on Stack OverflowWhy not using instead a SortedSet with a case insensitive comparator ? With the String.CASE_INSENSITIVE_ORDER comparator
Your code is reduced to
Set<String> a = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
a.add("one");
a.add("three");
a.add("two");
Set<String> a1 = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
a1.add("ONE");
a1.add("two");
a1.add("THREE");
And your equals conditions should work without any issue
EDIT modified according to comments. Thanks to all of you to correct me.
You need to use
Collections.sort(a, String.CASE_INSENSITIVE_ORDER);
in order to sort ignoring case, you can use the equalsIgnoreCase method on String to compare to values
You can of course create your own CaseInsensitiveList class, we have a CaseInsensitiveSet & CaseInsensitiveMap in our codebase
java - Is there a clean way to ignore case when comparing List<String>? - Stack Overflow
java - ArrayList contains case sensitivity - Stack Overflow
java - Option to ignore case with .contains method? - Stack Overflow
How To Ignore Case When Comparing ArrayList Elements To String ?
Just make a lowercase copy before using the intersection method:
return ListUtils.intersection(names1.stream().map(String::toLowerCase).collect(Collectors.toList()),
names2.stream().map(String::toLowerCase).collect(Collectors.toList()));
Put the contents of one list into a Set<String>, lower-cased, say:
Set<String> lcNames2 =
names2.stream().map(String::toLowerCase).collect(Collectors.toSet());
Then:
List<String> intersection =
names2.stream()
.filter(n -> lcNames2.contains(n.toLowerCase())
.collect(Collectors.toList());
But note that the notion of intersection is rather ill-defined when you are not dealing with equality as the equivalence relation.
Lists.intersection effectively treats the two lists as sets, since it will not add the same element twice.
But if you're not dealing with equals, what does it mean "not to add the same element twice"?
- Do you mean that you only add one representative of every equivalence class (e.g. you won't add "Ab" if you already added "ab")? If so, how do you pick that representative? Unless you add a normalized form (e.g. the lower-cased string), your result depends upon order of appearance (which may or may not be what you desire).
- Do you mean that you add all members of an equivalence class that you see, just not adding the exact same string twice (e.g. add both "Ab" and "ab", but not add "ab" again)?
Or something else.
The exact solution depends upon your actual requirements.
Since you are comparing sizes, I'll assume that order is relevant, as lists are ordered collections. The code shown in the question ignores order.
To compare all elements case-insensitively, in order, you should parallel iterate both lists. Since get(int) is not fast for all List implementations, a parallel iteration using Iterator is best:
private static boolean equalsIgnoreCase(List<String> list1, List<String> list2) {
if (list1.size() != list2.size())
return false;
for (Iterator<String> iter1 = list1.iterator(), iter2 = list2.iterator(); iter1.hasNext(); )
if (! iter1.next().equalsIgnoreCase(iter2.next()))
return false;
return true;
}
I am assuming you want to compare 2 lists.
Ensure neither list is null.
if(list1 == null || list2 == null) return false;
Check sizes.
if(list1.size() != list2.size()) return false;
Check elements in lists (including the ordering of strings(?), but not casing)
for(int i = 0 ; i < list1.size() ; i++) {
// i think equalsIgnoreCase takes care of null strings
// if it doesn't, do it yourself :)
String first = list1.get(i);
String second = list2.get(i);
if(first == null && second != null)
return false;
if(first == null && second == null)
continue;
if( !(first.equalsIgnoreCase(second)) )
return false;
}
If you got here. Everything is probably good.
return true;
As Andreas noted, for lists that are implemented like LinkedList the get(..) gives bad performance. An iterator based approached like his answer solves that issue.
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;
}
}
In Java8, using anyMatch
List<String> list = Arrays.asList("XYZ", "ABC");
String matchingText = "xYz";
boolean isMatched = list.stream().anyMatch(matchingText::equalsIgnoreCase);
If you're using Java 8
List<String> list = new ArrayList<>();
boolean containsSearchStr = list.stream().anyMatch("search_value"::equalsIgnoreCase);
I'm guessing you mean ignoring case when searching in a string?
I don't know any, but you could try to convert the string to search into either to lower or to upper case, then search.
// s is the String to search into, and seq the sequence you are searching for.
bool doesContain = s.toLowerCase().contains(seq);
Edit: As Ryan Schipper suggested, you can also (and probably would be better off) do seq.toLowerCase(), depending on your situation.
import java.util.ArrayList;
public class WordsCounter {
public static int occurences(String string, ArrayList<String> words){
int number = 0;
for(int i = 0; i < words.size(); i++){
if(words.get(i).equalsIgnoreCase(string)){
number++;
}
}
return number;
}
}I want to make a method that takes a string and a list of words as parameters, and returns how many of the words in the list could be found in the string at least once. It doesn't have to be the word exactly, just that a part of the string matches, like such:
If the String was "Sunshine is nice", and the list elements were "shine" and "nice", it would return 2.
I can't get it to work with the ignore of case, the program doesn't ignore case despite the method I used. I looked up String methods and equalsIgnoreCase seemed to be a good one but it does not work. I don't know if it's because it can't be applied to list elements (although they are Strings). Do any of you know how I should think regarding this?
The best way is to use str.equalsIgnoreCase("foo"). It's optimized specifically for this purpose.
You can also convert both strings to upper- or lowercase before comparing them with equals. This is a trick that's useful to remember for other languages which might not have an equivalent of equalsIgnoreCase.
str.toUpperCase().equals(str2.toUpperCase())
If you are using a non-Roman alphabet, take note of this part of the JavaDoc of equalsIgnoreCase which says
Note that this method does not take locale into account, and will result in unsatisfactory results for certain locales. The Collator class provides locale-sensitive comparison.
Use String.equalsIgnoreCase().
Use the Java API reference to find answers like these:
https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html#equalsIgnoreCase(java.lang.String)
https://docs.oracle.com/javase/1.5.0/docs/api/