Imagine I have the following lists
List a
- ("One", "Two", "Three", "Four", "Five")
List b
- ("oNe", "two", "THREE")
I want to consider b
as a subset of a
(ignoring the case).
For now I'm using loops and a bit of lambda like so
boolean subset = true;
for(String bWord : b) {
if(!a.stream().anyMatch(aWord -> aWord.equalsIgnoreCase(bWord))) {
subset = false;
break;
}
}
Is there a shorter way to do this maybe with lambdas?
Convert arrays to lowercase:
a.stream().map(String::toLowerCase).collect(Collectors.toList());
and use containsAll
:
b.containsAll(a);
You can transform a
to a HashSet
of lower case String
s, which would make it faster to check for subset (since it would take constant time to check whether any element of b
belongs to aset
, instead of the linear time required for checking for inclusion in a List
):
Set<String> aset = a.stream().map(String::toLowerCase).collect(Collectors.toCollection(HashSet::new));
boolean subset = b.stream().map(String::toLowerCase).allMatch(aset::contains);
P.S., you are using the term subset, but in fact what you are checking for is not whether one List
is a subset of the other, since your List
s are not Set
s, which means they may contain duplicate values. It would make more sense to begin with Set
s in the first place.
EDIT:
If using containsAll
seems better to you, at least run it on two Set
s instead of two List
s. You'll get linear running time instead of quadratic running time:
Set<String> aset = a.stream().map(String::toLowerCase).collect(Collectors.toCollection(HashSet::new));
Set<String> bset = b.stream().map(String::toLowerCase).collect(Collectors.toCollection(HashSet::new));
boolean subset = aset.containsAll(bset);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With