null - Purpose, use of and queries regarding the Objects.compare utility method -
i have question using new objects.compare(o1, o2, comparator) method - own testing of it, if both o1 , o2 null returns 0, however, if 1 of them null still throws null pointer exception. have found lot of material on objects.equals , of other objects utility methods not @ on objects.compare , when expected use / replace old code it.
so here this:
string s1 = "hi"; string s2 = "hi"; int x = objects.compare(s1, s2, comparator.naturalorder()); system.out.println("x = " + x);
that works fine, returns 0, this:
string s1 = null; string s2 = null;
also works fine , returns 0. however, this:
string s1 = "hi"; strng s2 = null;
throws nullpointerexception. i'm guessing benefit of objects.compare(o1,o2,comparator) vs o1.compareto(o2) @ least handles circumstances both objects null , when 1 of them null allows design comparator handle it. i'm supposing, e.g.
int x = objects.compare(s1, s2, comparator.nullsfirst(comparator.naturalorder()));
whereas x.compareto(y) there's no way handle null unless beforehand? java library developers intend replace calls compareto objects.compare, when we're concerned nulls? e.g. in our comparable implementations?
side query 1: regards using nullsfirst if use pass in comparator, chained using comparing, thencomparing, etc, apply of inner comparators? e.g.
comparator.nullsfirst(comparator.comparing(song::gettitle) .thencomparing(song::getartist) .thencomparing(song::getduration) )
would apply nullsfirst inside or need use nullsfirst individually on each of them? think testing applies actual song objects being null, not fields of title or artist being null, i.e. if null nullpointerexception still thrown. anyway around that?
side query 2: final question because comparator.comparing syntax, i'm proposing start write compareto implementions using - struggling think how replace traditional approach, e.g.
public int compareto(song other) { int result = this.title.compareto(other.title); if (result == 0) { result = this.artist.compareto(other.artist); if (result == 0) { result = integer.compare(this.duration, other.duration); } } return result; }
then thought use objects.compare(...) follows:
public int compareto(song other) { return objects.compare(this, other, comparator.nullsfirst( comparator.comparing(song::gettitle) .thencomparing(song::getartist) .thencomparingint(song::getduration) )); }
i thought version more elegant - assuming working think is, e.g. passing , other first 2 arguments comparator, has same effect traditional compareto approach if statements? whilst can see benefit of objects.compare catching 2 nulls never occur if null compareto method call never reached (either handling exception or being thrown). using nullsfirst suppose if argument passed in, i.e. other, null, handle safely?
many in advance help.
objects.compare
not meant provide null
safe comparison, since there no default behavior implemented. implements shortcut of not invoking comparator
’s method when both objects identical. in other words, a==b? 0: c.compare(a, b)
, nothing more. not breaking when both objects null
side-effect. encapsulated code might trivial other methods in class of similar category. using small utility methods lot might still result in notable win.
by way, it’s not java 8 method @ all. exists since java 7.
regarding second question, comparator.nullsfirst(…)
decorates existing comparator
, enforce rule null
values before delegating provided comparator purpose of comparator shield existing 1 ever seeing null
values. doesn’t matter whether decorated comparator chained 1 or not. long called “inner comparator”, as
you must not invoke thencomparing
on result of nullsfirst
imply calling next comparator when both values null
.
comparator.nullsfirst(comparator.comparing(a).thencomparing(b)) // perfect comparator.nullsfirst(comparator.comparing(a)).thencomparing(b) // ouch
now third question, implementing compareto
method using nullsfirst
comparator violating interface
specification:
the implementor must ensure
sgn(x.compareto(y)) == -sgn(y.compareto(x))
x
,y
. (this impliesx.compareto(y)
must throw exception iffy.compareto(x)
throws exception.)
this implies passing null
argument should result in nullpointerexception
swapping argument , receiver throw well, unconditionally.
orders including null
policy should provided separate comparator
s.
note quite inefficient create new comparator
(multiple comparators
, precise) every compareto
call. image sorting rather large list of these objects…
Comments
Post a Comment