Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #35711 > unrolled thread
| Started by | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| First post | 2016-10-04 07:25 -0700 |
| Last post | 2016-10-05 22:41 +0200 |
| Articles | 15 — 7 participants |
Back to article view | Back to comp.lang.java.programmer
Comparison structure? Eric Douglas <e.d.programmer@gmail.com> - 2016-10-04 07:25 -0700
Re: Comparison structure? Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-10-04 10:46 -0400
Re: Comparison structure? Roedy Green <inquiry@mindprod.com> - 2016-10-04 09:53 -0700
Re: Comparison structure? Eric Douglas <e.d.programmer@gmail.com> - 2016-10-04 10:29 -0700
Re: Comparison structure? Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-10-04 15:35 -0400
Re: Comparison structure? Arne Vajhøj <arne@vajhoej.dk> - 2016-10-04 20:16 -0400
Re: Comparison structure? Arne Vajhøj <arne@vajhoej.dk> - 2016-10-04 22:29 -0400
Re: Comparison structure? Eric Sosman <esosman@comcast-dot-net.invalid> - 2016-10-05 08:08 -0400
Re: Comparison structure? Arne Vajhøj <arne@vajhoej.dk> - 2016-10-05 20:27 -0400
Re: Comparison structure? Martin Gregorie <martin@address-in-sig.invalid> - 2016-10-04 17:37 +0000
Re: Comparison structure? Eric Douglas <e.d.programmer@gmail.com> - 2016-10-04 12:02 -0700
Re: Comparison structure? j4n bur53 <janburse@fastmail.fm> - 2016-10-05 17:12 +0200
Re: Comparison structure? j4n bur53 <janburse@fastmail.fm> - 2016-10-05 17:14 +0200
Re: Comparison structure? Arne Vajhøj <arne@vajhoej.dk> - 2016-10-04 20:03 -0400
Re: Comparison structure? Marcel Mueller <news.5.maazl@spamgourmet.org> - 2016-10-05 22:41 +0200
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-10-04 07:25 -0700 |
| Subject | Comparison structure? |
| Message-ID | <59c17fe5-61a6-46dc-918f-ee5aa348e3fd@googlegroups.com> |
I used some hard coded values to make a test block that compiles. Suffice to say these are dynamically assigned. The 3-way IF block sounds messy. Is there a better structure?
int compareMe = 1;
int compareTo = 2;
final int assignMe;
if (compareMe == compareTo) {
assignMe = 4;
} else {
if (compareMe > compareTo) {
assignMe = compareMe + 2;
} else {
assignMe = compareMe;
}
}
[toc] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2016-10-04 10:46 -0400 |
| Message-ID | <nt0fbh$qv2$1@dont-email.me> |
| In reply to | #35711 |
On 10/4/2016 10:25 AM, Eric Douglas wrote:
> I used some hard coded values to make a test block that compiles. Suffice to say these are dynamically assigned. The 3-way IF block sounds messy. Is there a better structure?
>
> int compareMe = 1;
> int compareTo = 2;
> final int assignMe;
> if (compareMe == compareTo) {
> assignMe = 4;
> } else {
> if (compareMe > compareTo) {
> assignMe = compareMe + 2;
> } else {
> assignMe = compareMe;
> }
> }
You could rearrange it in many ways, but you're still stuck
with selecting among three distinct outcomes. Therefore, at least
two tests are necessary.
Some people frown on the ?: operator -- maybe they're just
grumpy by nature, I dunno -- but in situations of this kind I feel
it can reduce visual clutter and thereby improve readability.
if (compareMe == compareTo) {
assignMe = 4;
} else {
assignMe = compareMe + (compareMe > compareTo ? 2 : 0);
}
Further condensation is certainly possible, but I'd likely not go there.
--
esosman@comcast-dot-net.invalid
The Tooth Fairy has gone high-tech, now pays in Bitecoin.
[toc] | [prev] | [next] | [standalone]
| From | Roedy Green <inquiry@mindprod.com> |
|---|---|
| Date | 2016-10-04 09:53 -0700 |
| Message-ID | <vin7vbtorg7k171plq29ve3fo4fut237d5@4ax.com> |
| In reply to | #35711 |
On Tue, 4 Oct 2016 07:25:22 -0700 (PDT), Eric Douglas <e.d.programmer@gmail.com> wrote: >Is there a better structure? the only alternative I can think of is to use a compare method that returns +1 -1 0. Then you could use a switch.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-10-04 10:29 -0700 |
| Message-ID | <cfb773de-671a-46e7-9d79-e821780c7bcb@googlegroups.com> |
| In reply to | #35713 |
On Tuesday, October 4, 2016 at 12:53:51 PM UTC-4, Roedy Green wrote:
> >Is there a better structure?
> the only alternative I can think of is to use a compare method that
> returns +1 -1 0.
> Then you could use a switch.
In that case you'd have to override the compareTo?
I read the doc on that method and it says returns a zero, or a value less than or greater than zero. If it's not guaranteed to return specific values for less than or greater than, what would be the switch case?
This seems at least one reason people in the following thread suggest sticking with the 3-way if.
http://stackoverflow.com/questions/18510360/how-to-use-greater-than-or-equal-in-a-switch-statement
Otherwise that code would be equivalent to
Integer compareMe = 1;
int compareTo = 2;
final int assignMe;
switch (compareMe.compareTo(compareTo)) {
case 0:
assignMe = 4;
break;
case 1:
assignMe = compareMe + 2;
break;
case -1:
assignMe = compareMe;
break;
}
Of course Integer is final so you couldn't even just subclass it to override compareTo. Without having 3 certain return values, this method ends up uglier.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2016-10-04 15:35 -0400 |
| Message-ID | <nt109m$r82$1@dont-email.me> |
| In reply to | #35714 |
On 10/4/2016 1:29 PM, Eric Douglas wrote:
> On Tuesday, October 4, 2016 at 12:53:51 PM UTC-4, Roedy Green wrote:
>>> Is there a better structure?
>> the only alternative I can think of is to use a compare method that
>> returns +1 -1 0.
>> Then you could use a switch.
>
> In that case you'd have to override the compareTo?
> I read the doc on that method and it says returns a zero, or a value less than or greater than zero. If it's not guaranteed to return specific values for less than or greater than, what would be the switch case?
> This seems at least one reason people in the following thread suggest sticking with the 3-way if.
> http://stackoverflow.com/questions/18510360/how-to-use-greater-than-or-equal-in-a-switch-statement
>
> Otherwise that code would be equivalent to
> Integer compareMe = 1;
> int compareTo = 2;
> final int assignMe;
> switch (compareMe.compareTo(compareTo)) {
> case 0:
> assignMe = 4;
> break;
> case 1:
> assignMe = compareMe + 2;
> break;
> case -1:
> assignMe = compareMe;
> break;
> }
>
> Of course Integer is final so you couldn't even just subclass it to override compareTo. Without having 3 certain return values, this method ends up uglier.
You could use some static methods of Integer to eliminate
the Integer object instances and fix the range problem:
int compareMe = 1;
int compareTo = 2;
final int assignMe;
switch(Integer.signum(Integer.compare(compareMe, compareTo))) {
case 0:
assignMe = 4;
break;
case 1:
assignMe = compareMe + 2;
break;
default: // not "case -1:"
assignMe = compareMe;
break;
}
However, I'd be disinclined to call this an "improvement" over
the original code.
--
esosman@comcast-dot-net.invalid
The Tooth Fairy has gone high-tech, now pays in Bitecoin.
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2016-10-04 20:16 -0400 |
| Message-ID | <nt1gom$thu$1@gioia.aioe.org> |
| In reply to | #35717 |
On 10/4/2016 3:35 PM, Eric Sosman wrote:
> On 10/4/2016 1:29 PM, Eric Douglas wrote:
>> On Tuesday, October 4, 2016 at 12:53:51 PM UTC-4, Roedy Green wrote:
>>>> Is there a better structure?
>>> the only alternative I can think of is to use a compare method that
>>> returns +1 -1 0.
>>> Then you could use a switch.
>>
>> In that case you'd have to override the compareTo?
>> I read the doc on that method and it says returns a zero, or a value
>> less than or greater than zero. If it's not guaranteed to return
>> specific values for less than or greater than, what would be the
>> switch case?
>> This seems at least one reason people in the following thread suggest
>> sticking with the 3-way if.
>> http://stackoverflow.com/questions/18510360/how-to-use-greater-than-or-equal-in-a-switch-statement
>>
>>
>> Otherwise that code would be equivalent to
>> Integer compareMe = 1;
>> int compareTo = 2;
>> final int assignMe;
>> switch (compareMe.compareTo(compareTo)) {
>> case 0:
>> assignMe = 4;
>> break;
>> case 1:
>> assignMe = compareMe + 2;
>> break;
>> case -1:
>> assignMe = compareMe;
>> break;
>> }
>>
>> Of course Integer is final so you couldn't even just subclass it to
>> override compareTo. Without having 3 certain return values, this
>> method ends up uglier.
>
> You could use some static methods of Integer to eliminate
> the Integer object instances and fix the range problem:
>
> int compareMe = 1;
> int compareTo = 2;
> final int assignMe;
> switch(Integer.signum(Integer.compare(compareMe, compareTo))) {
> case 0:
> assignMe = 4;
> break;
> case 1:
> assignMe = compareMe + 2;
> break;
> default: // not "case -1:"
> assignMe = compareMe;
> break;
> }
>
> However, I'd be disinclined to call this an "improvement" over
> the original code.
Well - if one is competing in a code obfuscation contest then I will
suggest:
int compareMe = 1;
final int assignMe = cases[Integer.signum(compareMe - compareTo) +
1].option(compareMe, compareTo);
int compareTo = 2;
with:
@FunctionalInterface
private interface Case {
public int option(int compareMe, int compareTo);
}
private static Case[] cases = { (me,to) -> me, (me,to) -> 4, (me,to) ->
me + 2 };
:-)
Arne
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2016-10-04 22:29 -0400 |
| Message-ID | <nt1oim$1646$1@gioia.aioe.org> |
| In reply to | #35721 |
On 10/4/2016 8:16 PM, Arne Vajhøj wrote:
> Well - if one is competing in a code obfuscation contest then I will
> suggest:
>
> int compareMe = 1;
> final int assignMe = cases[Integer.signum(compareMe - compareTo) +
> 1].option(compareMe, compareTo);
> int compareTo = 2;
>
> with:
>
> @FunctionalInterface
> private interface Case {
> public int option(int compareMe, int compareTo);
> }
> private static Case[] cases = { (me,to) -> me, (me,to) -> 4, (me,to)
> -> me + 2 };
>
> :-)
Well - I think the concept can actually be twisted into something
that is almost readable!
@FunctionalInterface
private static interface Case {
public int option(int compareMe, int compareTo);
}
public static abstract class Comparison {
protected Case lt;
protected Case eq;
protected Case gt;
private int compareMe;
private int compareTo;
public Comparison(int compareMe, int compareTo) {
this.compareMe = compareMe;
this.compareTo = compareTo;
}
public int execute() {
switch(Integer.signum(compareMe - compareTo)) {
case -1:
return lt.option(compareMe, compareTo);
case 0:
return eq.option(compareMe, compareTo);
case 1:
return gt.option(compareMe, compareTo);
default:
throw new RuntimeException("Bye bye");
}
}
}
int compareMe = 1;
int compareTo = 2;
final int assignMe = new Comparison(compareMe, compareTo) {
{
lt = (me,to) -> me;
eq = (me,to) -> 4;
gt = (me,to) -> me + 2;
}
}.execute();
Arne
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2016-10-05 08:08 -0400 |
| Message-ID | <nt2qg6$o96$1@dont-email.me> |
| In reply to | #35722 |
On 10/4/2016 10:29 PM, Arne Vajhøj wrote:
>[...]
> private int compareMe;
> private int compareTo;
> [...]
> switch(Integer.signum(compareMe - compareTo)) {
Bad Arne! B-A-A-D Arne! Wear this dunce cap and sit in the corner!
(Hint: Why do "sign-of-difference" and "comparison" sometimes
give different answers?)
(Hint #2: compareMe = -100000, compareTo = 0x7fffffff)
--
esosman@comcast-dot-net.invalid
The Tooth Fairy has gone high-tech, now pays in Bitecoin.
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2016-10-05 20:27 -0400 |
| Message-ID | <nt45q4$vuf$1@gioia.aioe.org> |
| In reply to | #35724 |
On 10/5/2016 8:08 AM, Eric Sosman wrote:
> On 10/4/2016 10:29 PM, Arne Vajhøj wrote:
>> [...]
>> private int compareMe;
>> private int compareTo;
>> [...]
>> switch(Integer.signum(compareMe - compareTo)) {
>
> Bad Arne! B-A-A-D Arne! Wear this dunce cap and sit in the corner!
>
> (Hint: Why do "sign-of-difference" and "comparison" sometimes
> give different answers?)
>
> (Hint #2: compareMe = -100000, compareTo = 0x7fffffff)
OK. Integer.compare then.
Arne
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| Date | 2016-10-04 17:37 +0000 |
| Message-ID | <nt0pcj$r9u$1@dont-email.me> |
| In reply to | #35711 |
On Tue, 04 Oct 2016 07:25:22 -0700, Eric Douglas wrote:
> I used some hard coded values to make a test block that compiles.
> Suffice to say these are dynamically assigned. The 3-way IF block
> sounds messy. Is there a better structure?
>
> int compareMe = 1;
> int compareTo = 2;
> final int assignMe;
> if (compareMe == compareTo) {
> assignMe = 4;
> } else {
> if (compareMe > compareTo) {
> assignMe = compareMe + 2;
> } else {
> assignMe = compareMe;
> }
> }
>
Three ways is always a bit of a toss-up because it looks messy any way
you implement it.
Personally, I think a switch is more readable: with four or more branches
its the way to go but I might also use it for a three way branch,
especially if each branch is only a few lines of inline code.
I'd only ever assign constants to assignMe, preferably defining them as
an enum list or a set of named integer constants. Using a mix of
constants and calculated values is bound to trip a maintenance programmer
at some point.
You could also use an enum with class bodies.
--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2016-10-04 12:02 -0700 |
| Message-ID | <18de28f1-b2f2-4905-92db-1c5e3e6c4a5f@googlegroups.com> |
| In reply to | #35715 |
On Tuesday, October 4, 2016 at 1:37:44 PM UTC-4, Martin Gregorie wrote: > Three ways is always a bit of a toss-up because it looks messy any way > you implement it. > > Personally, I think a switch is more readable: with four or more branches > its the way to go but I might also use it for a three way branch, > especially if each branch is only a few lines of inline code. > > I'd only ever assign constants to assignMe, preferably defining them as > an enum list or a set of named integer constants. Using a mix of > constants and calculated values is bound to trip a maintenance programmer > at some point. > > You could also use an enum with class bodies. There are no constants in this example. The 1, 2s, and 4 are there for show, so it compiles. In the actual implementation those are all complex object.method() results.
[toc] | [prev] | [next] | [standalone]
| From | j4n bur53 <janburse@fastmail.fm> |
|---|---|
| Date | 2016-10-05 17:12 +0200 |
| Message-ID | <nt358q$lld$1@news.albasani.net> |
| In reply to | #35715 |
Martin Gregorie schrieb:
> Three ways is always a bit of a toss-up because it looks messy any way
> you implement it.
since JDK 1.7 there is the class Integer:
public static int compare(int x, int y);
which avoids the boxing overhead.
the contract says <0, 0, >0,
but the implementation does -1,0,+1
(historically compare to could be implemented
by x-y, if |x| and |y| are less than 2^30,
because then the difference can be correctly
represented with the desired sign,
this works fine for byte, short and
char, if int widening is used, we therefore
find in JDK 1.7 in the corresponding wrapper
classes:
public static int compare(byte x, byte y) {
return x - y;
}
public static int compare(short x, short y) {
return x - y;
}
public static int compare(char x, char y) {
return x - y;
}
but the exception is int, since for int
arguments the condition |x| and |y| are less
than 2^30, since the int range is one binary
magnitude bigger, similar problem with long:
public static int compare(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
public static int compare(long x, long y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
[toc] | [prev] | [next] | [standalone]
| From | j4n bur53 <janburse@fastmail.fm> |
|---|---|
| Date | 2016-10-05 17:14 +0200 |
| Message-ID | <nt35c8$lld$2@news.albasani.net> |
| In reply to | #35725 |
j4n bur53 schrieb: > (historically compare to could be implemented historically CPU CMP is just a SUB and checking some flags
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2016-10-04 20:03 -0400 |
| Message-ID | <nt1g10$snf$1@gioia.aioe.org> |
| In reply to | #35711 |
On 10/4/2016 10:25 AM, Eric Douglas wrote:
> I used some hard coded values to make a test block that compiles.
> Suffice to say these are dynamically assigned. The 3-way IF block sounds
> messy. Is there a better structure?
>
> int compareMe = 1;
> int compareTo = 2;
> final int assignMe;
> if (compareMe == compareTo) {
> assignMe = 4;
> } else {
> if (compareMe > compareTo) {
> assignMe = compareMe + 2;
> } else {
> assignMe = compareMe;
> }
> }
It is all about readability.
That code is very readable. The reader easily understand
what the code does. Good code in my opinion.
I would flatten it like:
int compareMe = 1;
int compareTo = 2;
final int assignMe;
if (compareMe == compareTo) {
assignMe = 4;
} else if (compareMe > compareTo) {
assignMe = compareMe + 2;
} else {
assignMe = compareMe;
}
but that is just a minor change.
Arne
[toc] | [prev] | [next] | [standalone]
| From | Marcel Mueller <news.5.maazl@spamgourmet.org> |
|---|---|
| Date | 2016-10-05 22:41 +0200 |
| Message-ID | <nt3oi7$ihi$1@gwaiyur.mb-net.net> |
| In reply to | #35711 |
On 04.10.16 16.25, Eric Douglas wrote:
> I used some hard coded values to make a test block that compiles. Suffice to say these are dynamically assigned. The 3-way IF block sounds messy. Is there a better structure?
>
> int compareMe = 1;
> int compareTo = 2;
> final int assignMe;
> if (compareMe == compareTo) {
> assignMe = 4;
> } else {
> if (compareMe > compareTo) {
> assignMe = compareMe + 2;
> } else {
> assignMe = compareMe;
> }
> }
This is a common pattern and I do not know any significantly better
solution than this.
I would only omit the first else brace to clarify that all three paths
are at the same level.
if (compareMe == compareTo) {
assignMe = 4;
} else if (compareMe > compareTo) {
assignMe = compareMe + 2;
} else {
assignMe = compareMe;
}
Marcel
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web