-
Enhancement
-
Resolution: Fixed
-
P4
-
8u5
-
b17
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8204706 | 11.0.1 | Jim Laskey | P4 | Resolved | Fixed | team |
A DESCRIPTION OF THE REQUEST :
Please add a method to java.util.Predicate similar to the following:
public static <T> Predicate<T> not(Predicate<T> target) {
return target.negate();
}
JUSTIFICATION :
There is currently no easy way to negate a predicate which is a lambda (as opposed to an actual Predicate object).
Suppose I want to create a list of empty strings using the Stream API. It is easy:
List<String> result = originals.stream().filter(String::isEmpty).collect(Collections.toList());
However, if I instead want to create a list of nonempty strings, I have to do a bit more work. Suddenly, I am forced to introduce a named variable and do an explicit method call:
List<String> result = originals.stream().filter(string -> !string.isEmpty()).collect(Collections.toList());
I can't use a method reference here because there is no method in the String class for determining if a string is not empty. (I wish there were!)
In principle, the Predicate.negate() method is intended to be used in these sorts of situations, but in this case it can't be, because String::isEmpty is not a Predicate<String> until and unless it is assigned to one, so I would have to create a temporary Predicate object (or use a cast) to get a Predicate to call negate() on.
I would like to be able to easily create a negated version of a lambda, like this:
import static java.util.function.Predicate.not;
List<String> result = originals.stream().filter(not(String::isEmpty)).collect(Collections.toList());
Also see discussion here:
http://stackoverflow.com/questions/21488056/how-to-negate-a-method-reference-predicate
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would like to be able to write this:
import static java.util.function.Predicate.not;
List<String> result = originals.stream().filter(not(String::isEmpty)).collect(Collections.toList());
or for slightly better performance (assuming the JDK's optimizer fails at noticing that 'not(String::isEmpty)' is a constant expression - I'm not sure if it can handle this), I could write this:
Predicate<String> notEmpty = not(String::isEmpty);
List<String> result = originals.stream().filter(notEmpty).collect(Collections.toList());
ACTUAL -
I currently have to write this:
List<String> result = originals.stream().filter(string -> !string.isEmpty()).collect(Collections.toList());
or this:
List<String> result = originals.stream().filter(string -> ((Predicate)String::isEmpty).negate()).collect(Collections.toList());
or this:
Predicate<String> isEmpty = String::isEmpty;
List<String> result = originals.stream().filter(isEmpty.negate()).collect(Collections.toList());
all of which are harder to read and unnecessarily different from the equivalent code which uses a direct method reference to the String::isEmpty method.
Please add a method to java.util.Predicate similar to the following:
public static <T> Predicate<T> not(Predicate<T> target) {
return target.negate();
}
JUSTIFICATION :
There is currently no easy way to negate a predicate which is a lambda (as opposed to an actual Predicate object).
Suppose I want to create a list of empty strings using the Stream API. It is easy:
List<String> result = originals.stream().filter(String::isEmpty).collect(Collections.toList());
However, if I instead want to create a list of nonempty strings, I have to do a bit more work. Suddenly, I am forced to introduce a named variable and do an explicit method call:
List<String> result = originals.stream().filter(string -> !string.isEmpty()).collect(Collections.toList());
I can't use a method reference here because there is no method in the String class for determining if a string is not empty. (I wish there were!)
In principle, the Predicate.negate() method is intended to be used in these sorts of situations, but in this case it can't be, because String::isEmpty is not a Predicate<String> until and unless it is assigned to one, so I would have to create a temporary Predicate object (or use a cast) to get a Predicate to call negate() on.
I would like to be able to easily create a negated version of a lambda, like this:
import static java.util.function.Predicate.not;
List<String> result = originals.stream().filter(not(String::isEmpty)).collect(Collections.toList());
Also see discussion here:
http://stackoverflow.com/questions/21488056/how-to-negate-a-method-reference-predicate
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I would like to be able to write this:
import static java.util.function.Predicate.not;
List<String> result = originals.stream().filter(not(String::isEmpty)).collect(Collections.toList());
or for slightly better performance (assuming the JDK's optimizer fails at noticing that 'not(String::isEmpty)' is a constant expression - I'm not sure if it can handle this), I could write this:
Predicate<String> notEmpty = not(String::isEmpty);
List<String> result = originals.stream().filter(notEmpty).collect(Collections.toList());
ACTUAL -
I currently have to write this:
List<String> result = originals.stream().filter(string -> !string.isEmpty()).collect(Collections.toList());
or this:
List<String> result = originals.stream().filter(string -> ((Predicate)String::isEmpty).negate()).collect(Collections.toList());
or this:
Predicate<String> isEmpty = String::isEmpty;
List<String> result = originals.stream().filter(isEmpty.negate()).collect(Collections.toList());
all of which are harder to read and unnecessarily different from the equivalent code which uses a direct method reference to the String::isEmpty method.
- backported by
-
JDK-8204706 Predicate::not - provide an easier way to negate a predicate
-
- Resolved
-
- csr for
-
JDK-8203428 Predicate::not
-
- Closed
-
- duplicates
-
JDK-8194272 Add a static method Predicate.not
-
- Closed
-
- relates to
-
JDK-8157790 java.util streams "filterNot(predicate)" for collections
-
- Closed
-
-
JDK-8317993 Add capturing factories to classes in java.util.function package
-
- Closed
-