I tried to convert the body of a method boolean exists(String value, boolean isCaseSensitive)
:
for(String str : existingNames){
if(isCaseSensitive ? str.equals(name) : str.equalsIgnoreCase(name)){
return true;
}
}
return false;
to a solution that utilises java8 method references:
Predicate<String> equalityPred = isCaseSensitive ?
name::equals :
name::equalsIgnoreCase;
return existingNames.stream().anyMatch(equalityPred);
Then I saw that this way the equality is performed in the opposite direction (e.g. value.equals(str)
).
Is there a way to fix this and still use method references, and if no what would be the java8 way.
There is no “opposite direction” for equality. The only issue might be the behavior for null
values. Your loop might fail, if the collection contains null
, your method references will fail, if name
is null
.
You may achieve the original behavior using lambda expressions:
boolean check(Collection<String> existingNames, String name, boolean isCaseSensitive) {
Predicate<String> equalityPred = isCaseSensitive?
s -> s.equals(name):
s -> s.equalsIgnoreCase(name);
return existingNames.stream().anyMatch(equalityPred);
}
but it makes little sense to consider null
for the name
parameter, when it will never be equal, as the code will fail with a NullPointerException
, if the collection contains null
.
To get a sensible behavior for null
, you may use
boolean check(Collection<String> existingNames, String name, boolean isCaseSensitive) {
Predicate<String> equalityPred = name==null? Objects::isNull:
isCaseSensitive? name::equals: name::equalsIgnoreCase;
return existingNames.stream().anyMatch(equalityPred);
}
or just
boolean check(Collection<String> existingNames, String name, boolean isCaseSensitive) {
return name==null || isCaseSensitive?
existingNames.contains(name):
existingNames.stream().anyMatch(name::equalsIgnoreCase);
}
If you know that the Collection will never contain null
, but want to support null
for the name
parameter, you could also use
boolean check(Collection<String> existingNames, String name, boolean isCaseSensitive) {
return name!=null && existingNames.stream()
.anyMatch(isCaseSensitive? name::equals: name::equalsIgnoreCase);
}
Well don't use a method reference then and write your lambda directly:
static boolean existsJDK8(List<String> existingNames, String value, boolean isCaseSensitive) {
Predicate<String> equalityPred = isCaseSensitive ? s -> value.equals(s) : s -> value.equalsIgnoreCase(s);
Predicate<String> equalityPredReversed = isCaseSensitive ? s -> s.equals(value) : s -> s.equalsIgnoreCase(value);
// return existingNames.stream().anyMatch(equalityPredReversed);
return existingNames.stream().anyMatch(equalityPred);
}
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