Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #35533

Re: Why not String compare?

From Eric Sosman <esosman@comcast-dot-net.invalid>
Newsgroups comp.lang.java.programmer
Subject Re: Why not String compare?
Date 2016-09-01 17:57 -0400
Organization A noiseless patient Spider
Message-ID <nqa891$nvj$1@dont-email.me> (permalink)
References <33463070-424f-4fb0-956b-2849f1a400eb@googlegroups.com> <nppu0n$nle$1@dont-email.me> <855574dd-f21f-46f9-8972-a55aa189cf27@googlegroups.com> <1pr3rgydxxzp5.dlg@kimmeringer.de>

Show all headers | View raw


On 9/1/2016 2:42 PM, Lothar Kimmeringer wrote:
> Eric Douglas wrote:
>
>> Not trying to reverse it, why would I need to reverse it?
>
> Maybe not you but the common use-case that uses compareTo
>
>> I have a TreeSet called records, and I do this.
>> records.stream().filter(item -> item.getKey(currKnum).compareTo(currKey) > 0)
>>
>> The getKey() method of the objects in this TreeSet accepts an int and returns a (non-null)String. I want this filter to return all items.  What better way than to pass in null as the value to compareTo?  Shouldn't everything be greater than null?
>
> compareTo is commonly used for sorting data. So a.compareTo(b)
> is called to decide what element should be sorted to "the left"
> and what element should be sorted to "the right". What element
> is a and b is dependent on the implementation of the sorting
> algortithm and the actual data within the set.
>
> Allowing a.compareTo(null) to return something would lead to
> non-deterministic behavior since the sort might succeed if by
> chance null ends up being b all the time. But an optimization
> of the sorting algorithm or a new element in the set might
> lead to null end up as a and referencing null always leads to
> a NPE. Throwing a NPE when compareTo is called with null as
> parameter brings back the deterministic behavior and therefor
> is declared as requirement for implementations of compareTo.

     Exactly: A Comparable must implement a /total order/ (see, for
example, <https://en.wikipedia.org/wiki/Total_order>).  One of the
defining characteristics of a total order is antisymmetry: The
results of X.compareTo(Y) and Y.compareTo(X) must be opposite
in sign, or both zero.  If either is unable to deliver a result
and throws an exception instead, so too must the other.  This may
seem odd, but it's really just "If one doesn't throw, then the
other mustn't either" written the other way around.

     A Comparator has a bit more freedom.  It must still implement
a total order, but because neither of the compared items is `this'
it is not obliged to throw NPE when one of them is null.  (It is
allowed to do so, of course, provided it does so consistently.)

     An algorithm using Comparable or a Comparator is "entitled" to
rely on the fact that it is dealing with a total order, so it can
deduce the outcome of a comparison not actually performed if other
comparisons imply the result.  A TreeMap, for example, can compare
the search key to an item in the Map and know which branch to follow;
it need not explore the ruled-out branch at all because it "knows"
the results of all potential key-to-item comparisons in that branch
without needing to make them.  This "knowledge" flows directly from
the properties of the total order; if the Comparable or Comparator
does *not* implement a total order, what the algorithm "knows" may
cause it to go innocently off the rails.

     ... but back to the O.P.'s problem: He wants to apply a filter
to a stream of Strings, so he needs to give the filter() method a
Predicate<String>.  He wrote a Predicate that exploits the fact
that String implements Comparable<String>, but this fails because his
intended use involves theString.compareTo(null) which as we've seen
above must be consistent with null.compareTo(theString).  Since the
Predicate as written won't do the job, he needs a different one.  Three
possibilities occur to me.  Most directly:

	filter((item) -> currKey == null
	      || item.getKey(currKnum).compareTo(currKey) > 0)

Alternatively, let `currKey' be the least included element instead
of the greatest excluded, using "" to mean "include everything":

	filter((item) -> item.getKey(currKnum).compareTo(currKey) >= 0)

Finally, instead of using `currKnum' and `currKey' as the "globals"
for the operation, he might instead use the Predicate<String>:

	Predicate<String> currPred = ...;

	filter(currPred)

... in which case "include everything" is just

	Predicate<String> currPred = () -> true;

-- 
esosman@comcast-dot-net.invalid
The Tooth Fairy has gone high-tech, now pays in Bitecoin.

Back to comp.lang.java.programmer | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Why not String compare? Eric Douglas <e.d.programmer@gmail.com> - 2016-08-26 09:00 -0700
  Re: Why not String compare? Robert Klemme <shortcutter@googlemail.com> - 2016-08-26 18:49 +0200
    Re: Why not String compare? Eric Douglas <e.d.programmer@gmail.com> - 2016-08-26 10:09 -0700
      Re: Why not String compare? Robert Klemme <shortcutter@googlemail.com> - 2016-08-26 22:48 +0200
        Re: Why not String compare? Eric Douglas <e.d.programmer@gmail.com> - 2016-08-26 13:55 -0700
          Re: Why not String compare? Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-08-26 17:29 -0400
          Re: Why not String compare? Lew <lewbloch@gmail.com> - 2016-08-30 22:20 -0700
          Re: Why not String compare? Robert Klemme <shortcutter@googlemail.com> - 2016-08-31 08:17 +0200
            Re: Why not String compare? Andreas Leitgeb <avl@logic.at> - 2016-08-31 09:45 +0000
              Re: Why not String compare? Robert Klemme <shortcutter@googlemail.com> - 2016-08-31 19:24 +0200
                Re: Why not String compare? Andreas Leitgeb <avl@logic.at> - 2016-09-01 10:17 +0000
                Re: Why not String compare? Robert Klemme <shortcutter@googlemail.com> - 2016-09-02 18:29 +0200
  Re: Why not String compare? Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-08-26 13:24 -0400
    Re: Why not String compare? Eric Douglas <e.d.programmer@gmail.com> - 2016-08-26 10:48 -0700
      Re: Why not String compare? Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-08-26 14:50 -0400
        Re: Why not String compare? Eric Douglas <e.d.programmer@gmail.com> - 2016-08-26 12:19 -0700
      Re: Why not String compare? Lothar Kimmeringer <news200709@kimmeringer.de> - 2016-09-01 20:42 +0200
        Re: Why not String compare? Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-09-01 17:57 -0400
    Re: Why not String compare? Eric Douglas <e.d.programmer@gmail.com> - 2016-08-26 11:03 -0700
      Re: Why not String compare? Lothar Kimmeringer <news200709@kimmeringer.de> - 2016-09-02 21:54 +0200

csiph-web