11

Java 7 introduced the Objects class containing “null-safe or null-tolerant” methods, including compare(T, T, Comparator<T>). But when would I ever use

Objects.compare(left, right, comparator);

over simply calling

comparator.compare(left, right);

?

Objects.compare is only null-safe if comparator is as well, so why would I wrap the compare-call? The optimization of first checking for object identity seems like something that should be done in the comparator itself. And the only real difference in behavior I can see is that comparator.compare(left, right) throws a NullPointerException if all of comparator, left and right are null, while Objects.compare does not; this does not really seem like an important enough consideration to warrant a new standard library method.

Am I missing something obvious here?

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
user4235730
  • 2,559
  • 1
  • 23
  • 36
  • 2
    this Method is absolutely stupid, I agree. [Guava's `Ordering`](https://code.google.com/p/guava-libraries/wiki/OrderingExplained) does a much better job at solving that problem. – Sean Patrick Floyd Sep 22 '15 at 16:40
  • The method is not used anywhere in JDK :) probably useless. – ZhongYu Sep 22 '15 at 16:53
  • the only thing this method does is check if both the arguments are null, in case your comparator does not test for that case. quite useless, like most of that class – njzk2 Sep 22 '15 at 17:01
  • 4
    @njzk2 I don't think that “the rest of that class” is “useless”. I find `Objects.hash` to be especially useful, as well as `Objects.requireNonNull` in it's variant with a message. – user4235730 Sep 22 '15 at 17:07

1 Answers1

15

This was interesting to dig into. The Objects class, along with this .compare() method, was introduced in 3b45b809d8ff by Joe Darcy, and the commit message cites Bug 6797535 and indicates "Sherman" (Xueming Shen?) signed off on it. In addition to the bug there is this thread from Sept. 2009 discussing what features to add to Objects. In the thread folks discuss adding compare(int, int) (and the like) primitive comparison methods, and eventually decide these should reside in their respective wrapper classes (see Integer.compare()). This method is introduced later in that thread but without any commentary that I can find.

Later a patch is sent out for review containing Objects.compare(), and Joshua Bloch replies:

I don't think you should add this method ( compare(T a, T b, Comparator c)). Its utility is unclear, and it doesn't have the power-to-weight ratio of the other methods in this class.

Darcy responds:

Yeah, I included this with "Item 12: Consider implementing Comparable" from EJv2 in mind.

It's not clear to me what this method brings to the table regarding Item 12, but the issue doesn't appear to have been raised again. I infer that the intent was to provide a method equivalent to the primitive compare()'s for stylistic reasons, but I haven't found evidence that was actually the reason.


It's worth noticing that in the same exchange between Darcy and Bloch the Objects.toString() method is similarly criticized by Bloch:

I would definitely /not/ add this method (Objects.toString). It brings nothing to the table that isn't already there. People know and use String.valueOf. Let's not muddy the waters by adding another choice.

But as we know it was not removed, Darcy simply responded:

So noted.


So in conclusion, it seems to me like this was introduced without much intent. It was proposed and the objections that were raised did not block it being checked in. I imagine that a more rigorous design review would have erred on the side of leaving it out, like Bloch suggested.

You might also be interested in this similar question (though it's about an implementation detail, not an API change): Why is Arrays.fill() not used in HashMap.clear() anymore?

Community
  • 1
  • 1
dimo414
  • 47,227
  • 18
  • 148
  • 244
  • 2
    Bounty incoming. Thank you for your research and your superb answer. A bonus to this is what we could learn from the history: mostly the insights into API design in general, and insights into Oracle processes. Josh Bloch god-like level confirmed. It's a shame the guy isn't publicly visible so much anymore. – Petr Janeček Nov 12 '15 at 10:27
  • 1
    My pleasure :) I always enjoy digging into why decisions like this were made. – dimo414 Nov 12 '15 at 14:07