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, ...
...