Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #35466 > unrolled thread
| Started by | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| First post | 2016-08-26 09:00 -0700 |
| Last post | 2016-09-02 21:54 +0200 |
| Articles | 20 — 6 participants |
Back to article view | Back to comp.lang.java.programmer
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
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-08-26 09:00 -0700 |
| Subject | Why not String compare? |
| Message-ID | <33463070-424f-4fb0-956b-2849f1a400eb@googlegroups.com> |
This seems odd, the String class returns false if you pass a null into equals(), but throws NPE if you pass null into compareTo(). The Javadoc on it's compareTo() doesn't mention nulls much less NPE. The Javadoc on Comparator mentions it'll return NPE by default for a null, but any time I write a custom Comparator I return 1 for compareTo() if argument is null.
[toc] | [next] | [standalone]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2016-08-26 18:49 +0200 |
| Message-ID | <e2ba8jF67mfU1@mid.individual.net> |
| In reply to | #35466 |
On 26.08.2016 18:00, Eric Douglas wrote: > This seems odd, the String class returns false if you pass a null > into equals(), but throws NPE if you pass null into compareTo(). The > Javadoc on it's compareTo() doesn't mention nulls much less NPE. The > Javadoc on Comparator mentions it'll return NPE by default for a > null, but any time I write a custom Comparator I return 1 for > compareTo() if argument is null. http://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html#compareTo-T- -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-08-26 10:09 -0700 |
| Message-ID | <1c9ad1a1-ee44-4a9f-a307-1dab14c4a921@googlegroups.com> |
| In reply to | #35467 |
On Friday, August 26, 2016 at 12:49:32 PM UTC-4, Robert Klemme wrote: http://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html#compareTo-T- > What's your point? Did you read the question?
[toc] | [prev] | [next] | [standalone]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2016-08-26 22:48 +0200 |
| Message-ID | <e2bo9iF9m4nU1@mid.individual.net> |
| In reply to | #35468 |
On 26.08.2016 19:09, Eric Douglas wrote: > On Friday, August 26, 2016 at 12:49:32 PM UTC-4, Robert Klemme wrote: > http://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html#compareTo-T- >> > > What's your point? Did you read the question? Did you read the documentation? -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-08-26 13:55 -0700 |
| Message-ID | <d9d392a6-7361-4743-aaef-22ec3d126722@googlegroups.com> |
| In reply to | #35475 |
On Friday, August 26, 2016 at 4:49:05 PM UTC-4, Robert Klemme wrote: > On 26.08.2016 19:09, Eric Douglas wrote: > > On Friday, August 26, 2016 at 12:49:32 PM UTC-4, Robert Klemme wrote: > > http://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html#compareTo-T- > >> > > > > What's your point? Did you read the question? > > Did you read the documentation? > > > -- > remember.guy do |as, often| as.you_can - without end > http://blog.rubybestpractices.com/ Do you always answer a question with a question? Yes, if you read my message, I am well aware the default for the Comparable class is to throw NPE if you try to compareTo(null). I'm asking why. This doesn't make sense. myString.compareTo(null) should return 1, just as myString.equals(null) returns false. Why shouldn't it make sense for everything to reutrn 1 (greater than) if you compare to a null? Is there another value to pass into the String.compareTo() to return the lowest possible String? This seems dumb that everyone who wants to compare Strings has to null check first.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2016-08-26 17:29 -0400 |
| Message-ID | <npqcbm$bai$1@dont-email.me> |
| In reply to | #35476 |
On 8/26/2016 4:55 PM, Eric Douglas wrote:
> [...] I am well aware the default for the Comparable class is to throw NPE if you try to compareTo(null). I'm asking why. This doesn't make sense. myString.compareTo(null) should return 1, just as myString.equals(null) returns false. Why shouldn't it make sense for everything to reutrn 1 (greater than) if you compare to a null? Is there another value to pass into the String.compareTo() to return the lowest possible String? This seems dumb that everyone who wants to compare Strings has to null check first.
Point #1: There is no "Comparable class"; Comparable is an interface
implemented by many classes (the Javadoc lists one hundred fifty-two),
each with its own behaviors.
Point #2: Comparable has no "default" behavior at all, not even with
the introduction of `default' methods for Java 1.8 interfaces.
Point #3: This whole thread ultimately boils down to "I'm unhappy
with the way java.lang.String implements Comparable." Okay, fine: I'm
unhappy with some pieces of Java, too (that's not one of them). Express
your unhappiness, stop whining, and get on with your life. Or go look
up Guy Steele and give *him* a tongue-lashing.
--
esosman@comcast-dot-net.invalid
The Tooth Fairy has gone high-tech, now pays in Bitecoin.
[toc] | [prev] | [next] | [standalone]
| From | Lew <lewbloch@gmail.com> |
|---|---|
| Date | 2016-08-30 22:20 -0700 |
| Message-ID | <c00873ef-4b47-4e26-a0d9-e61bbcdbacca@googlegroups.com> |
| In reply to | #35476 |
Eric Douglas wrote: > Robert Klemme wrote: > > Eric Douglas wrote: > > > Robert Klemme wrote: > > > http://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html#compareTo-T- > > >> > > > > > > What's your point? Did you read the question? > > > > Did you read the documentation? > > Do you always answer a question with a question? > Yes, if you read my message, I am well aware the default for the Comparable class is to > throw NPE if you try to compareTo(null). "Default"? It's not the "default". If you actually had read the documentation you would know that. Here's what the documentation says: "Throws: NullPointerException - if the specified object is null" Not as a "default". As the requirement. The requirement. It's required. That's why the implementor did it, to satisfy the requirement, as required. Not as a "default". > I'm asking why. Because it's required. The docs say so. > This doesn't make sense. Sounds like your problem, not the documentation's. It makes sense to most Java programmers: The docs say to throw an NPE if the argument is null. So the implementation did. That seems awfully easy to understand. > myString.compareTo(null) should return 1, just as myString.equals(null) returns false. Why No, it shouldn't. That would violate the requirement, and code isn't supposed to violate requirements. Why would you think that it should? > shouldn't it make sense for everything to reutrn 1 (greater than) if you compare to a null? Nope. Because NULL is neither greater than, less than, equal to, or unequal to anything else in maths. That it sometimes does in computers is silliness, and anyway, "it makes sense" or not is an entirely subjective assessment. You should phrase it more responsibly as "I say that", not as some glorious Platonic ideal "it should be". This is just your personal opinion for which you have not offered a jot of any objective rationale, but againsty which there is ample objective rationale. Like that fact that NULL (represented by `null`) is an out-of-band value and therefore not sensibly comparable to in-bad values > Is there another value to pass into the String.compareTo() to return the lowest possible String? This seems dumb that everyone who wants to compare Strings has to null check first. Again with "seems dumb" as a cover for "I in my infinite wisdom and arrogant judgment pronounce that it is dumb". It only seems dumb to you, because you aren't thinking about it as offered to you. Perhaps you should abandon your prejudices and embrace things as they are. Happy to help. -- Lew
[toc] | [prev] | [next] | [standalone]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2016-08-31 08:17 +0200 |
| Message-ID | <e2nb40F26seU1@mid.individual.net> |
| In reply to | #35476 |
On 26.08.2016 22:55, Eric Douglas wrote: > On Friday, August 26, 2016 at 4:49:05 PM UTC-4, Robert Klemme wrote: >> On 26.08.2016 19:09, Eric Douglas wrote: >>> On Friday, August 26, 2016 at 12:49:32 PM UTC-4, Robert Klemme wrote: >>> http://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html#compareTo-T- >>>> >>> >>> What's your point? Did you read the question? >> >> Did you read the documentation? > Do you always answer a question with a question? Why should I? Seriously, that reply of mine was probably not the most inspired one. The intention was to suggest to read the documentation again. It's all in there, as others have pointed out already. > Yes, if you read my message, I am well aware the default for the > Comparable class is to throw NPE if you try to compareTo(null). I'm > asking why. This doesn't make sense. myString.compareTo(null) > should return 1, just as myString.equals(null) returns false. Why > shouldn't it make sense for everything to reutrn 1 (greater than) if > you compare to a null? Is there another value to pass into the > String.compareTo() to return the lowest possible String? This seems > dumb that everyone who wants to compare Strings has to null check > first. To me it makes perfectly sense, especially in light of this: The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y. (This implies that x.compareTo(y) must throw an exception iff y.compareTo(x) throws an exception.) Cheers robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
[toc] | [prev] | [next] | [standalone]
| From | Andreas Leitgeb <avl@logic.at> |
|---|---|
| Date | 2016-08-31 09:45 +0000 |
| Message-ID | <slrnnsd9q3.456.avl@login.logic.tuwien.ac.at> |
| In reply to | #35512 |
Robert Klemme <shortcutter@googlemail.com> wrote: > The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) > for all x and y. (This implies that x.compareTo(y) must throw an > exception iff y.compareTo(x) throws an exception.) An equivalent "symmetry" could be expected from .equals, but isn't. It's not "symmetry" as such, that implied the requirement. It was just pragmatically defined so for .compareTo while not for .equals. Any usecase for including null into the natural ordering of certain Comparable objects is just flawed.
[toc] | [prev] | [next] | [standalone]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2016-08-31 19:24 +0200 |
| Message-ID | <e2oi5kFbhheU1@mid.individual.net> |
| In reply to | #35515 |
On 31.08.2016 11:45, Andreas Leitgeb wrote: > Robert Klemme <shortcutter@googlemail.com> wrote: >> The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) >> for all x and y. (This implies that x.compareTo(y) must throw an >> exception iff y.compareTo(x) throws an exception.) > > An equivalent "symmetry" could be expected from .equals, but isn't. Not necessarily since the underlying concept is different - equivalence relation vs. total order. You can reasonably say "that nothing is not equivalent to myself" while from "not equivalent" nothing follows for order. And btw. the concept of treating null special is quite common, for example with RDBMS. > It's not "symmetry" as such, that implied the requirement. It was > just pragmatically defined so for .compareTo while not for .equals. Well, but that is the contract. And I can see some sense in this. > Any usecase for including null into the natural ordering of certain > Comparable objects is just flawed. There, now you said it yourself. :-) Cheers robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
[toc] | [prev] | [next] | [standalone]
| From | Andreas Leitgeb <avl@logic.at> |
|---|---|
| Date | 2016-09-01 10:17 +0000 |
| Message-ID | <slrnnsg01f.456.avl@login.logic.tuwien.ac.at> |
| In reply to | #35527 |
Robert Klemme <shortcutter@googlemail.com> wrote: > On 31.08.2016 11:45, Andreas Leitgeb wrote: >> Robert Klemme <shortcutter@googlemail.com> wrote: >>> The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) >>> for all x and y. (This implies that x.compareTo(y) must throw an >>> exception iff y.compareTo(x) throws an exception.) >> An equivalent "symmetry" could be expected from .equals, but isn't. > Not necessarily since the underlying concept is different That's not the point. If it *was* about symmetry (or anti- for compareTo) then both compareTo and equals would have to throw NPE for null argument, because obviously both throw NPE when called on a null reference. > You can reasonably say "that nothing is not equivalent to myself" If symmetry really was the requirement, then it would need to include symmetry to null.equals(...). It isn't, though. That .compareTo(null) throws NPE is *not* "for symmetry", but for a design decision, which defined compareTo to be NPE-symmetric. For equals a different decision was made. And both these decisions still make sense. I think, we're in "violent agreement" here, anyway.
[toc] | [prev] | [next] | [standalone]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2016-09-02 18:29 +0200 |
| Message-ID | <e2tnn7Fil46U1@mid.individual.net> |
| In reply to | #35529 |
On 01.09.2016 12:17, Andreas Leitgeb wrote: > Robert Klemme <shortcutter@googlemail.com> wrote: >> On 31.08.2016 11:45, Andreas Leitgeb wrote: >>> Robert Klemme <shortcutter@googlemail.com> wrote: >>>> The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) >>>> for all x and y. (This implies that x.compareTo(y) must throw an >>>> exception iff y.compareTo(x) throws an exception.) >>> An equivalent "symmetry" could be expected from .equals, but isn't. >> Not necessarily since the underlying concept is different > > That's not the point. If it *was* about symmetry (or anti- for compareTo) > then both compareTo and equals would have to throw NPE for null argument, > because obviously both throw NPE when called on a null reference. Symmetry is not a value in itself, right? The point is that for different concepts (equivalence vs. total order) the requirement for symmetry can also be different. Both are too unrelated to require their implementations to behave identical with regard to exceptions and symmetry. >> You can reasonably say "that nothing is not equivalent to myself" > > If symmetry really was the requirement, then it would need to > include symmetry to null.equals(...). It isn't, though. > > That .compareTo(null) throws NPE is *not* "for symmetry", but for > a design decision, which defined compareTo to be NPE-symmetric. > For equals a different decision was made. And both these decisions > still make sense. Absolutely. > I think, we're in "violent agreement" here, anyway. :-) Yes. I think we've reached state of hair splitting. Cheers robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2016-08-26 13:24 -0400 |
| Message-ID | <nppu0n$nle$1@dont-email.me> |
| In reply to | #35466 |
On 8/26/2016 12:00 PM, Eric Douglas wrote:
> This seems odd, the String class returns false if you pass a null into equals(), but throws NPE if you pass null into compareTo().
> The Javadoc on it's compareTo() doesn't mention nulls much less NPE.
> The Javadoc on Comparator mentions it'll return NPE by default for a null, but any time I write a custom Comparator I return 1 for compareTo() if argument is null.
Are you talking about Comparator, or about Comparable? The
latter has a compareTo() method, the former does not.
If you're speaking of Comparable, I think you're in violation
of the spec. In
ComparableThing x = ...; // non-null
ComparableThing y = null;
int xy = x.compareTo(y);
int yx = y.compareTo(x);
... you don't get xy and yx with opposite signs, as required by
the Comparable documentation:
The implementor must ensure sgn(x.compareTo(y)) ==
-sgn(y.compareTo(x)) for all x and y. (This implies that
x.compareTo(y) must throw an exception iff y.compareTo(x)
throws an exception.)
If you're speaking of Comparator, simply returning 1 when either
argument of compare() is null is also a breach. Consider
Thing x = ...; // non-null
Thing y = null;
Comparator<Thing> c = ...;
int xy = c.compare(x, y);
int yx = c.compare(y, x);
Again, you must ensure that sgn(xy) = -sgn(yx), but if both are 1
this doesn't hold. (You should also arrange that c.compare(null,null)
returns 0, not 1 or -1.)
--
esosman@comcast-dot-net.invalid
The Tooth Fairy has gone high-tech, now pays in Bitecoin.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-08-26 10:48 -0700 |
| Message-ID | <855574dd-f21f-46f9-8972-a55aa189cf27@googlegroups.com> |
| In reply to | #35469 |
On Friday, August 26, 2016 at 1:24:48 PM UTC-4, Eric Sosman wrote: > Are you talking about Comparator, or about Comparable? The > latter has a compareTo() method, the former does not. > > If you're speaking of Comparable, I think you're in violation > of the spec. In > > ComparableThing x = ...; // non-null > ComparableThing y = null; > int xy = x.compareTo(y); > int yx = y.compareTo(x); > > ... you don't get xy and yx with opposite signs, as required by > the Comparable documentation: > > The implementor must ensure sgn(x.compareTo(y)) == > -sgn(y.compareTo(x)) for all x and y. (This implies that > x.compareTo(y) must throw an exception iff y.compareTo(x) > throws an exception.) > > If you're speaking of Comparator, simply returning 1 when either > argument of compare() is null is also a breach. Consider > > Thing x = ...; // non-null > Thing y = null; > Comparator<Thing> c = ...; > int xy = c.compare(x, y); > int yx = c.compare(y, x); > > Again, you must ensure that sgn(xy) = -sgn(yx), but if both are 1 > this doesn't hold. (You should also arrange that c.compare(null,null) > returns 0, not 1 or -1.) Not trying to reverse it, why would I need to reverse it? 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?
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2016-08-26 14:50 -0400 |
| Message-ID | <npq328$a0b$1@dont-email.me> |
| In reply to | #35470 |
On 8/26/2016 1:48 PM, Eric Douglas wrote:
> On Friday, August 26, 2016 at 1:24:48 PM UTC-4, Eric Sosman wrote:
>> Are you talking about Comparator, or about Comparable? The
>> latter has a compareTo() method, the former does not.
>>
>> If you're speaking of Comparable, I think you're in violation
>> of the spec. In
>>
>> ComparableThing x = ...; // non-null
>> ComparableThing y = null;
>> int xy = x.compareTo(y);
>> int yx = y.compareTo(x);
>>
>> ... you don't get xy and yx with opposite signs, as required by
>> the Comparable documentation:
>>
>> The implementor must ensure sgn(x.compareTo(y)) ==
>> -sgn(y.compareTo(x)) for all x and y. (This implies that
>> x.compareTo(y) must throw an exception iff y.compareTo(x)
>> throws an exception.)
>>
>> If you're speaking of Comparator, simply returning 1 when either
>> argument of compare() is null is also a breach. Consider
>>
>> Thing x = ...; // non-null
>> Thing y = null;
>> Comparator<Thing> c = ...;
>> int xy = c.compare(x, y);
>> int yx = c.compare(y, x);
>>
>> Again, you must ensure that sgn(xy) = -sgn(yx), but if both are 1
>> this doesn't hold. (You should also arrange that c.compare(null,null)
>> returns 0, not 1 or -1.)
>
> Not trying to reverse it, why would I need to reverse it?
Um, er, to satisfy the contract of Comparable?
> 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?
When you want all the items, not filtering at all strikes me as
a "better way."
An "Eric Douglas" has many times exhibited in this newsgroup a
preoccupation with efficiency. Clearly, the "Eric Douglas" who runs
an entire TreeSet through a no-op filtering stream has a radically
different world view.
--
esosman@comcast-dot-net.invalid
The Tooth Fairy has gone high-tech, now pays in Bitecoin.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-08-26 12:19 -0700 |
| Message-ID | <15f3116e-9c88-4b69-9667-dc7d31b358dd@googlegroups.com> |
| In reply to | #35472 |
On Friday, August 26, 2016 at 2:50:59 PM UTC-4, Eric Sosman wrote: > When you want all the items, not filtering at all strikes me as > a "better way." > > An "Eric Douglas" has many times exhibited in this newsgroup a > preoccupation with efficiency. Clearly, the "Eric Douglas" who runs > an entire TreeSet through a no-op filtering stream has a radically > different world view. But I am filtering... I'm passing in a key string. I want to get all values from the list that are higher than that string. Then the filter parses those values to get the first one using a custom Comparator. If the key value of the first record may be an empty string how would this find it without passing a null key? I mentioned the filter up to the compareTo so you can see where the problem lies and you mention removing the filter. That is the point. That is the workaround. I have to check if my key passed into the compareTo is null before executing this filter and redirect it to a different filter. The full filter is a find next: final Optional<T> result = records.stream().filter(item -> item.getKey(currKnum).compareTo(currKey) > 0).findFirst(); The records is generic: private TreeSet<T> records; The filter is comparing the keys (Strings). The actual values in the TreeSet are custom objects. The compareTo method is defined in the base of the generic class, accepts another instance of the generic class, and compares the results of the getKey(0). These custom objects have multiple keys for sorting orders, 0 is the default, and this filter is to pick out a record from any of those orders. Of course the findFirst() won't work if any of those orders returns duplicates so I still need to manage those.
[toc] | [prev] | [next] | [standalone]
| From | Lothar Kimmeringer <news200709@kimmeringer.de> |
|---|---|
| Date | 2016-09-01 20:42 +0200 |
| Message-ID | <1pr3rgydxxzp5.dlg@kimmeringer.de> |
| In reply to | #35470 |
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.
Cheers, Lothar
--
Lothar Kimmeringer E-Mail: spamfang@kimmeringer.de
PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)
Always remember: The answer is forty-two, there can only be wrong
questions!
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2016-09-01 17:57 -0400 |
| Message-ID | <nqa891$nvj$1@dont-email.me> |
| In reply to | #35532 |
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.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-08-26 11:03 -0700 |
| Message-ID | <2dca46af-3b1f-4352-82c6-a413d9dac03c@googlegroups.com> |
| In reply to | #35469 |
On Friday, August 26, 2016 at 1:24:48 PM UTC-4, Eric Sosman wrote: > Are you talking about Comparator, or about Comparable? The > latter has a compareTo() method, the former does not. > > If you're speaking of Comparable, I think you're in violation > of the spec. In > > ComparableThing x = ...; // non-null > ComparableThing y = null; > int xy = x.compareTo(y); > int yx = y.compareTo(x); > > ... you don't get xy and yx with opposite signs, as required by > the Comparable documentation: > > The implementor must ensure sgn(x.compareTo(y)) == > -sgn(y.compareTo(x)) for all x and y. (This implies that > x.compareTo(y) must throw an exception iff y.compareTo(x) > throws an exception.) > > If you're speaking of Comparator, simply returning 1 when either > argument of compare() is null is also a breach. Consider > > Thing x = ...; // non-null > Thing y = null; > Comparator<Thing> c = ...; > int xy = c.compare(x, y); > int yx = c.compare(y, x); > > Again, you must ensure that sgn(xy) = -sgn(yx), but if both are 1 > this doesn't hold. (You should also arrange that c.compare(null,null) > returns 0, not 1 or -1.) It seems silly to suggest you can't do x.compareTo(y) unless y.compareTo(x) is also legal, but you can do x.equals(y) where y.equals(x) is also not valid if y is null. Another example where I needed null to be valid in my custom Comparable. I wrote a custom table (extends JTable). Every cell in the table is a custom object. The cell class has a getValue() and a compareTo(). getValue() may return null because null has special meaning. If the cell is editable by default and has a value of empty string it displays as editable for the user to click on it and type into it. If it has a value of null it displays as blank and the user cannot edit. This saves us the trouble of populating the cells with empty strings and separately telling it half those cells are not editable. If it's a check-box style column it can populate with true (checked box), false (unchecked box), or null (blank cell). If the column is sortable the compareTo method sorts nulls to the beginning. null should always be a valid value on that side. You can't compare something to nothing because you have no basis for comparison if you have nothing, but you can always compare nothing to a something.
[toc] | [prev] | [next] | [standalone]
| From | Lothar Kimmeringer <news200709@kimmeringer.de> |
|---|---|
| Date | 2016-09-02 21:54 +0200 |
| Message-ID | <1le6no2qsdcz4.dlg@kimmeringer.de> |
| In reply to | #35471 |
Eric Douglas wrote:
> Another example where I needed null to be valid in my custom
> Comparable. I wrote a custom table (extends JTable).
> Every cell in the table is a custom object. The cell class
> has a getValue() and a compareTo(). getValue() may return
> null because null has special meaning.
You're only one step away from
http://thedailywtf.com/articles/What_Is_Truth_0x3f_
Since you use customized Objects what prevented you from
declaring a final static MyObject EMPTY_OBJECT = new MyObject()
and do a == EMPTY_OBJECT instead of a == null?
One day you will wonder why your application behaves strangely
and after hours of debugging you find out that somewhere null
is set where your special meaning wasn't intended.
Cheers, Lothar
--
Lothar Kimmeringer E-Mail: spamfang@kimmeringer.de
PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)
Always remember: The answer is forty-two, there can only be wrong
questions!
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web