Comparable Predicates
The following additional methods are available to a ReferenceField
that is always associated to a Comparable
field (e.g. Integer
, String
, Date
, Time
etc.). Comparable fields can be tested for equality and can also be compared to other objects of the same type. The "Condition" in the table below is the condition for which the corresponding Predicate
will hold true
:
Method | Param Type | Operation | Condition |
---|---|---|---|
equal |
|
Objects.equals(p, field) |
the field is equal to the parameter |
notEqual |
|
!Objects.equals(p, field) |
the field is not equal to the parameter |
lessThan |
|
field < p |
the field is less than the parameter |
lessOrEqual |
|
field ⇐ p |
the field is less or equal to the the parameter |
greaterThan |
|
field > p |
the field is greater than the parameter |
greaterOrEqual |
|
field >= p |
the field is greater or equal to the parameter |
between |
|
field >= s && field < e |
the field is between s (inclusive) and e (exclusive) |
between |
|
field >? s && field <? e |
the field is between s and e with inclusion according to the given Inclusion parameter ( |
notBetween |
|
field < s && field >= e |
the field is not between p1 (exclusive) and p2 (inclusive) |
notBetween |
|
field <? s && field >? e |
the field is not between s and e with inclusion according to the given Inclusion parameter ( |
in |
|
array p contains field |
the array parameter contains the field |
in |
|
p.contains(field) |
the |
notIn |
|
array p does not contain field |
the array parameter does not contain the field |
notIn |
|
!p.contains(field) |
the |
Fields that are null will never fulfill any of the predicates in the list above. Thus, neither equals nor notEquals will return true for null values.
|
The reason equal is not named equals is that the latter name is already used as a method name by the Object class (that every other class inherits from). The latter method has a different meaning than function than equal so a new name had to be used.
|
A ComparableField
implements the interface traits HasReferenceOperators
and HasComparableOperators
.
Examples
Here is a list with examples for the Comparable Predicates.
The examples below assume that the database contains a number of films with ratings according to the Motion Picture Association of America (MPAA) film rating system:
G | General Audience |
---|---|
PG |
Parental Guidance Suggested |
PG-13 |
PG-13 – Parents Strongly Cautioned |
R |
R – Restricted |
NC-17 |
NC-17 – Adults Only |
equal
To count all films with a rating that equals "PG-13" you can write the following snippet:
long count = jpaStreamer.stream(Film.class)
.filter(Film$.rating.equal("PG-13"))
.count();
System.out.format("There are %d films(s) with a PG-13 rating %n", count);
The code will produce the following output:
There are 223 films(s) with a PG-13 rating
notEqual
The following example prints all films that has a rating that is not "PG-13":
jpaStreamer.stream(Film.class)
.filter(Film$.rating.notEqual("PG-13"))
.forEachOrdered(System.out::println);
The code will produce the following output:
Film { filmId = 1, title = ACADEMY DINOSAUR, ..., rating = PG, ...
Film { filmId = 2, title = ACE GOLDFINGER, ..., rating = G, ...
Film { filmId = 3, title = ADAPTATION HOLES, ..., rating = NC-17, ...
Film { filmId = 4, title = AFFAIR PREJUDICE, ..., rating = G, ...
Film { filmId = 5, title = AFRICAN EGG, ..., rating = G, ...
Film { filmId = 6, title = AGENT TRUMAN, ..., rating = PG, ...
Film { filmId = 8, title = AIRPORT POLLOCK, ..., rating = R, ...
...
lessThan
The following example prints all films that has a length that is less or equal to 120:
jpaStreamer.stream(Film.class)
.filter(Film$.length.lessThan(120))
.forEachOrdered(System.out::println);
The code will produce the following output:
Fil { filmId = 1, title = ACADEMY DINOSAUR, ..., length = 86, ...
Film { filmId = 2, title = ACE GOLDFINGER, ..., length = 48, ...
Film { filmId = 3, title = ADAPTATION HOLES, ..., length = 50, ...
Film { filmId = 4, title = AFFAIR PREJUDICE, ..., length = 117, ...
Film { filmId = 7, title = AIRPLANE SIERRA, ..., length = 62, ...
...
greaterThan
The following example prints all films that has a length that is greater than 120:
jpaStreamer.stream(Film.class)
.filter(Film$.length.greaterThan(120))
.forEachOrdered(System.out::println);
The code will produce the following output:
Film { filmId = 5, title = AFRICAN EGG, ..., length = 130, ...
Film { filmId = 6, title = AGENT TRUMAN, ..., length = 169, ...
Film { filmId = 11, title = ALAMO VIDEOTAPE, ..., length = 126, ...
...
greaterOrEqual
The following example prints all films that has a length that is greater than or equal to 120:
jpaStreamer.stream(Film.class)
.filter(Film$.length.greaterOrEqual(120))
.forEachOrdered(System.out::println);
The code will produce the following output:
Film { filmId = 5, title = AFRICAN EGG, ..., length = 130, ...
Film { filmId = 6, title = AGENT TRUMAN, ..., length = 169, ...
Film { filmId = 11, title = ALAMO VIDEOTAPE, ..., length = 126, ...
...
between
The following example prints all films that has a length that is between 60 (inclusive) and 120 (exclusive):
jpaStreamer.stream(Film.class)
.filter(Film$.length.between(60, 120))
.forEachOrdered(System.out::println);
The code will produce the following output:
Film { filmId = 1, title = ACADEMY DINOSAUR, ..., length = 86, ...
Film { filmId = 4, title = AFFAIR PREJUDICE, ...,, length = 117, ...
Film { filmId = 7, title = AIRPLANE SIERRA, ..., length = 62, ...
Film { filmId = 9, title = ALABAMA DEVIL, ..., length = 114, ...
...
There is also another variant of the between
predicate where an {{site.data.javadoc.Inclusion}} parameter determines if a range of results should be start and/or end-inclusive.
For an example, take the series [1 2 3 4 5]. If we select elements in the range (2, 4) from this series, we will get the following results:
# | Inclusive Enum Constant |
Included Elements |
---|---|---|
0 |
|
[2, 3, 4] |
1 |
|
[2, 3] |
2 |
|
[3, 4] |
3 |
|
[3] |
Here is an example that prints all films that has a length that is between 3 (inclusive) and 9 (inclusive):
jpaStreamer.stream(Film.class)
.filter(Film$.length.between(60, 120, Inclusion.START_INCLUSIVE_END_INCLUSIVE))
The code will produce the following output:
Film { filmId = 1, title = ACADEMY DINOSAUR, ..., length = 86, ...
Film { filmId = 4, title = AFFAIR PREJUDICE, ...,, length = 117, ...
Film { filmId = 7, title = AIRPLANE SIERRA, ..., length = 62, ...
Film { filmId = 9, title = ALABAMA DEVIL, ..., length = 114, ...
...
The order of the two parameters start and end is significant. If the start parameter is larger than the end parameter, then the between Predicate will always evaluate to false .
|
notBetween
The following example prints all films that has a length that is not between 60 (inclusive) and 120 (exclusive):
jpaStreamer.stream(Film.class)
.filter(Film$.length.notBetween(60, 120))
.forEachOrdered(System.out::println);
The code will produce the following output:
Film { filmId = 2, ..., length = 48, ...
Film { filmId = 3, ..., length = 50, ...
Film { filmId = 5, ..., length = 130, ...
Film { filmId = 6, ..., length = 169, ...
Note that a film with length 120 is printed because 120 is outside the range 60 (inclusive) and 120 (exclusive) (because 120 is NOT in the range as 120 is exclusive).
There is also another variant of the notBetween
predicate where an {{site.data.javadoc.Inclusion}} parameter determines if a range of results should be start and/or end-inclusive.
For an example, take the series [1 2 3 4 5]. If you select elements not in the range (2, 4) from this series, we will get the following results:
# | Inclusive Enum Constant |
Included Elements |
---|---|---|
0 |
|
[1, 5] |
1 |
|
[1, 4, 5] |
2 |
|
[1, 2, 5] |
3 |
|
[1, 2, 4, 5] |
Here is an example that prints all films that has a length that is not between 60 (inclusive) and 120 (inclusive):
jpaStreamer.stream(Film.class)
.filter(Film$.length.notBetween(60, 120, Inclusion.START_INCLUSIVE_END_INCLUSIVE))
.forEachOrdered(System.out::println);
The code will produce the following output:
Film { filmId = 2, ..., length = 48, ...
Film { filmId = 3, ..., length = 50, ...
Film { filmId = 5, ..., length = 130, ...
Film { filmId = 6, ..., length = 169, ...
...
The order of the two parameters start and end is significant. If the start parameter is larger than the end parameter, then the notBetween Predicate will always evaluate to true .
|
in
Here is an example that prints all films that has a rating that is either "G", "PG" or "PG-13":
jpaStreamer.stream(Film.class)
.filter(Film$.rating.in("G", "PG", "PG-13"))
.forEachOrdered(System.out::println);
The code will produce the following output:
Film { filmId = 1, ..., rating = PG, ...
Film { filmId = 2, ..., rating = G, ...
Film { filmId = 4, ..., rating = G, ...
...
There is also a variant of the in
predicate that takes a Collection
as a parameter. For example like this:
Set<String> set = Stream.of("G", "PG", "PG-13").collect(toSet());
jpaStreamer.stream(Film.class)
.filter(Film$.rating.in(set))
.forEachOrdered(System.out::println);
The code will produce the following output:
Film { filmId = 1, ..., rating = PG, ...
Film { filmId = 2, ..., rating = G, ...
Film { filmId = 4, ..., rating = G, ...
...
notIn
Here is an example that prints all films that has a rating that is neither "G", "PG" nor "PG-13":
jpaStreamer.stream(Film.class)
.filter(Film$.rating.notIn("G", "PG", "PG-13"))
.forEachOrdered(System.out::println);
The code will produce the following output:
Film { filmId = 3, ..., rating = NC-17, ...
Film { filmId = 8, ..., rating = R, ...
Film { filmId = 10, ..., rating = NC-17, ...
There is also a variant of the noIn
predicate that takes a Collection
as a parameter. For example like this:
Set<String> set = Stream.of("G", "PG", "PG-13").collect(toSet());
jpaStreamer.stream(Film.class)
.filter(Film$.rating.notIn(set))
.forEachOrdered(System.out::println);
The code will produce the following output:
Film { filmId = 3, ..., rating = NC-17, ...
Film { filmId = 8, ..., rating = R, ...
Film { filmId = 10, ..., rating = NC-17, ...
...