Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check two lists for intersection ignoring case-sensitive?

Tags:

java

list

I have two lists

List<String> names1;
List<String> names2;

I want a new list returned to me with values that exist in both lists. These values should not repeat as retainAll does.

This was my original approach:

return ListUtils.intersection(names1, names2);

And it works fine. But it is case-sensitive so AbC is not the same as abc. I need the comparison to be case insensitive. Is there another way to do this?

like image 950
user6800688 Avatar asked Nov 18 '22 20:11

user6800688


1 Answers

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.

like image 53
Andy Turner Avatar answered Nov 29 '22 05:11

Andy Turner