-
Notifications
You must be signed in to change notification settings - Fork 5.9k
8356995: Provide default methods min(T, T) and max(T, T) in Comparator interface #25297
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
/csr |
👋 Welcome back tvaleev! A progress list of the required criteria for merging this PR into |
❗ This change is not yet ready to be integrated. |
@amaembo has indicated that a compatibility and specification (CSR) request is needed for this pull request. @amaembo please create a CSR request for issue JDK-8356995 with the correct fix version. This pull request cannot be integrated until the CSR request is approved. |
Webrevs
|
IMHO it makes sense. It's the min/max analog to a stable sort. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Min and Max for the equals case would be more consistent if the value returned for equals was the same as the condition, as if =>
or <=
were used for the comparison.
The code would be easier to read and match the description if max used >=
and min used <=
.
…rator); junit tests
@rgiulietti I tried to mimic the nearby tests which use testng. Converted to junit 5.
On the second thought, there is a consistency argument. We already have BinaryOperator.minBy and BinaryOperator.maxBy, which always return the first argument in case of tie (though this is not specified, probably it should be?). So it looks like it will be better to have both APIs consistent. One more point is that Guava's |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of nits.
* @param b another argument. | ||
* @return the larger of {@code a} and {@code b} according to this comparator. | ||
* @throws ClassCastException if the collection contains elements that are | ||
* not <i>mutually comparable</i> (for example, strings and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<em>
is more intent revealing.
* not <i>mutually comparable</i> (for example, strings and | |
* not <em>mutually comparable</em> (for example, strings and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I copied this sentence from java.util.Collections
where <i>
is used 48 times. I'll replace it here with <em>
, but probably it should be updated en-masse for consistency?
|
||
public class MinMaxTest { | ||
@Test | ||
public void testMin() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to this, test methods do not need to be public
(but cannot be private
).
public void testMin() { | |
void testMin() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks
Hi, There exists a class implementing Comparator and min and max methods too. But they are generic:
So when I have:
...then the type of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Thanks
What I was trying to say is that not only would Guava's Ordering not compile any more (it would still be binary compatible I think, as both methods have same erasure), but I also think that generic max and min as defined by Guava's Ordering are more useful too. So what do you think of making them generic like this: default <E extends T> E max(E e1, E e2) {
return compare(e1, e2) >= 0 ? e1 : e2;
}
default <E extends T> E min(E e1, E e2) {
return compare(e1, e2) <= 0 ? e1 : e2;
} |
/reviewers 2 reviewer |
@RogerRiggs |
@plevart this is definitely a good idea, and it will make the methods more convenient. I used |
* | ||
* @since 25 | ||
*/ | ||
default <U extends T> U max(U a, U b) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parameter names are o1 and o2 in the compare
method min and max build on.
Though a and b are used in the class javadoc example and x and y are used in the spec description.
Can we be consistent in the API? (o1, o2) perhaps. Someday, the parameter names may be more significant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks.
* @param b another argument. | ||
* @param <U> the type of the arguments and the result. | ||
* @return the larger of {@code a} and {@code b} according to this comparator. | ||
* @throws ClassCastException if the collection contains elements that are |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What 'collection' meaned here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, thank you. The description was copied from Collections::max
, which is not so appropriate here. I think it's better to copy it from Comparator::compare
(also, added @throws NPE
for consistency).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re-reviewed the PR and CSR. Thanks for the updates. Looks good.
Set the fixVersion to 25 and Finalize or at least Proposed to start the CSR review.
@RogerRiggs thank you! I always forget that CSR should be moved forward by its author... |
Implementation of Comparator.min and Comparator.max methods. Preliminary discussion is in this thread:
https://mail.openjdk.org/pipermail/core-libs-dev/2025-May/145638.html
The specification is mostly composed of Math.min/max and Collections.min/max specifications.
The methods are quite trivial, so I don't think we need more extensive testing (e.g., using different comparators). But if you have ideas of new useful tests, I'll gladly add them.
I'm not sure whether we should specify exactly the behavior in case if the comparator returns 0. I feel that it could be a useful invariant that
Comparator.min(a, b)
andComparator.max(a, b)
always return different argument, partitioning the set of {a, b} objects (even if they are equal). But I'm open to suggestions here.Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/25297/head:pull/25297
$ git checkout pull/25297
Update a local copy of the PR:
$ git checkout pull/25297
$ git pull https://git.openjdk.org/jdk.git pull/25297/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 25297
View PR using the GUI difftool:
$ git pr show -t 25297
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/25297.diff
Using Webrev
Link to Webrev Comment