String comparison - which way around?

H

harryajh

Which is best?

String str = "hello";

if("hello".equals(str))

or

if(str.equals("hello")

does it make any difference

thanks

harry
 
I

Ingo R. Homann

Hi,
Which is best?

String str = "hello";

if("hello".equals(str))

or

if(str.equals("hello")

does it make any difference

Yes - if str is null. Try it!

In other cases, it makes no difference.

Ciao,
Ingo
 
L

Lew

Which introduces a purely stylistic question:

if ( str != null && str.equals( "hello" ) )

vs.

if ( "hello".equals( str ))

This is, of course, moot if both comparands are variables. Thus the first form
is more consistent in code that also compares variables to variables, as well
as variables to constants.

The first variant also makes the null condition stand out, and lends itself to
refactoring along the lines of:

assert str != null;
if ( str.equals( "hello" ) )

or other separate handling of the null case.

One might also argue that the first version is more self-documenting.

I think the second form is uglier, and any small efficiency increase doesn't
justify the laziness of ignoring the explicit null case.

- Lew
 
D

Daniel Pitts

Lew said:
Which introduces a purely stylistic question:

if ( str != null && str.equals( "hello" ) )

vs.

if ( "hello".equals( str ))

This is, of course, moot if both comparands are variables. Thus the first form
is more consistent in code that also compares variables to variables, as well
as variables to constants.

The first variant also makes the null condition stand out, and lends itself to
refactoring along the lines of:

assert str != null;
if ( str.equals( "hello" ) )

or other separate handling of the null case.

One might also argue that the first version is more self-documenting.

I think the second form is uglier, and any small efficiency increase doesn't
justify the laziness of ignoring the explicit null case.

- Lew

Why do you think its uglier?

is (2 == a) uglier than (a == 2)?

I think that more people are used to (a == 2), but they both convey the
same idea to me.

-
Daniel.
 
L

Lew

Daniel said:
Why do you think its uglier?

For no rational reason. (Side note: "it's", with the apostrophe.)
is (2 == a) uglier than (a == 2)?

Yes, to me.
I think that more people are used to (a == 2), but they both convey the
same idea to me.

In my own mind, the variable /a/, or /str/ from the earlier posts, is the
center of the idiom, and the proper owner of the /equals()/ behavior.
Actually, whichever variable risks /null/-hood more would be the left-hand
variable in my mind, again just a matter of style not logic.

Since /str/ has the risk of being /null/ and is the first thing to check, it
stays the central variable in the /equals()/ test, in my own mind:

if ( str != null && str.equals( whatever ) )

It comes to me as a strange change in grammatical subject to say:

if ( str != null && whatever.equals( str ) )

even though it means exactly the same thing.

OTOH, if we are checking both operands for /null/ then it's arbitrary even to
me which comes first, but I would use the same variable "on the left" of both
the /null/ check and the /equals()/ check:

if ( (str == null? whatever == null : str.equals( whatever )) )

where /str/ is the "left-hand" variable throughout.

Not much more rational than liking the color indigo more than orange.

- Lew
 
D

Daniel Pitts

Lew said:
For no rational reason. (Side note: "it's", with the apostrophe.)
Is it its or is it it's, it's always its question. :)
Yes, to me.


In my own mind, the variable /a/, or /str/ from the earlier posts, is the
center of the idiom, and the proper owner of the /equals()/ behavior.
Actually, whichever variable risks /null/-hood more would be the left-hand
variable in my mind, again just a matter of style not logic.

Since /str/ has the risk of being /null/ and is the first thing to check, it
stays the central variable in the /equals()/ test, in my own mind:

if ( str != null && str.equals( whatever ) )

It comes to me as a strange change in grammatical subject to say:

if ( str != null && whatever.equals( str ) )

even though it means exactly the same thing.

Actually, the first one would work if whatever == null, the second one
doesn't. Which is why people choose to use "something".equals, because
in that case, "something" can't ever be null (baring some bizarre JVM
error). Think of this case:

if (str == null || !str.equals("foo")) {
System.out.ppintln("str isn't foo");
if (str == null || !str.equals("bar")) {
System.out.println("str isn't foo, and isn't bar either");
}
}

versus

if (!"foo".equals(str)) {
System.out.ppintln("str isn't foo");
if (!"bar".equals(str)) {
System.out.println("str isn't foo, and isn't bar either");
}
}

I think the second approach is far clearer. and is correct for the case
of str == null.
OTOH, if we are checking both operands for /null/ then it's arbitrary even to
me which comes first, but I would use the same variable "on the left" of both
the /null/ check and the /equals()/ check:

if ( (str == null? whatever == null : str.equals( whatever )) )

where /str/ is the "left-hand" variable throughout.

Not much more rational than liking the color indigo more than orange.
Well, indigo IS a better color than orange :)
 
L

Lew

Daniel said:
Think of this case:

if (str == null || !str.equals("foo")) {
System.out.ppintln("str isn't foo");
if (str == null || !str.equals("bar")) {
System.out.println("str isn't foo, and isn't bar either");
}
}

versus

if (!"foo".equals(str)) {
System.out.ppintln("str isn't foo");
if (!"bar".equals(str)) {
System.out.println("str isn't foo, and isn't bar either");
}
}

I think the second approach is far clearer. and is correct for the case
of str == null.

I dislike the second approach because it hides the test for /str == null/.

The first case is coded wrong and makes an unfair comparison. It should be:

if ( str == null )
{
doNullCase(); // doNotFoo(); doNotBarNeither();
/* usually null is a special case to be handled differently */
}
else if ( ! str.equals( "foo" ))
{
doNotFoo();
if ( ! str.equals( "bar" ))
{
doNotBarNeither();
}
}

The difference from your #2 is the addition of the /null/ test through the
corresponding /else/. The rest is just as clean, and now the /null/ test is
explicit where it belongs. While more complex than #2, it's substantially less
tangled than #1.

- Lew
 
M

maaxiim

Which is best?

String str = "hello";

if("hello".equals(str))

or

if(str.equals("hello")

does it make any difference

thanks

harry

It may be that I'm jumping into this conversation a little late, but I
thought some history might be interesting for someone out there:

I think this idiom is a hangover from procedural languages that didn't
support the concept of exceptions. For example, in C,

if (LHS == RHS)

if you inadvertently type

if (LHS = RHS)

then the compiler may not warn you that you attempted to assign a
variable and the bug would be a lot harder to find than tracking down a
NullPointerException.
One way to mitigate this problem would be to have any literal on the
LHS of the expression because then the C (or place favorite procedural
language here) compiler
would complain that you can't assign a value to a literal.

However, in Java throwing a NullPointerException at the exact point
that the code failed is a much better way to find bugs, so letting the
runtime warn you when you pass a null
pointer is less error prone. Besides I hate seeing literals on the RHS
of expressions :)
 
C

Chris Uppal

Lew said:
if ( str == null )
{
doNullCase(); // doNotFoo(); doNotBarNeither();
/* usually null is a special case to be handled differently */
}
else if ( ! str.equals( "foo" ))

That is a good point. Usually, either null should be handled specially, or it
should be handled in the normal way by throwing a NullPointerException. It
shouldn't be masked by putting the comparison the wrong (IMO) way around.

Also, if there /is/ a need to treat null is if it were a String which is
unequal to all other Strings (not in itself absurd) then the code should /show/
that that rather unusual interpretation applies.

But I admit that even if String.equals() were defined to throw an NPE when the
argument is null, then I'd /still/ dislike this idiom.

-- chris
 
D

Daniel Pitts

Lew said:
I dislike the second approach because it hides the test for /str == null/.

The first case is coded wrong and makes an unfair comparison. It should be:

if ( str == null )
{
doNullCase(); // doNotFoo(); doNotBarNeither();
/* usually null is a special case to be handled differently */
}
else if ( ! str.equals( "foo" ))
{
doNotFoo();
if ( ! str.equals( "bar" ))
{
doNotBarNeither();
}
}

The difference from your #2 is the addition of the /null/ test through the
corresponding /else/. The rest is just as clean, and now the /null/ test is
explicit where it belongs. While more complex than #2, it's substantially less
tangled than #1.

- Lew

Personally, I think Conditional Complexity (*Kerievsky, p. 41) is worse
than masking the _non-exceptional_ case of a null.

Null doesn't always have to be a "special case", and I think that
reducing the number of special cases is one way to improve design.

Think of it this way; If you needed to add a further check that str
isn't some other value either, now you have two places to add the
business logic to, even if it is just a single method call. Where as in
my version, you only had to add it in one place.

-
Daniel.
 
O

Oliver Wong

Which introduces a purely stylistic question:

if ( str != null && str.equals( "hello" ) )

vs.

if ( "hello".equals( str ))
[...]

The first variant also makes the null condition stand out

The second variant is funky enough that it stands out to me and makes me
ask myself "Now why did they write it that way?" and I've seen it often
enough so that a split second later, I answer myself "Oh, to handle nulls."
IOW, I've now been trained to see the implicit check against null in the
second variant.

- Oliver
 
D

Daniel Pitts

maaxiim said:
It may be that I'm jumping into this conversation a little late, but I
thought some history might be interesting for someone out there:

I think this idiom is a hangover from procedural languages that didn't
support the concept of exceptions. For example, in C,

if (LHS == RHS)

if you inadvertently type

if (LHS = RHS)

then the compiler may not warn you that you attempted to assign a
variable and the bug would be a lot harder to find than tracking down a
NullPointerException.
One way to mitigate this problem would be to have any literal on the
LHS of the expression because then the C (or place favorite procedural
language here) compiler
would complain that you can't assign a value to a literal.

However, in Java throwing a NullPointerException at the exact point
that the code failed is a much better way to find bugs, so letting the
runtime warn you when you pass a null
pointer is less error prone. Besides I hate seeing literals on the RHS
of expressions :)

Actually, the problem you described is accidental assignment, rather
than anything about NULL.
That particular problem is partially solved in java because java
requires a boolean inside conditionals, where as C/C++ (and possibly
others) allow any numeric value, and treat 0 as false, and not 0 as
true.

I say Java has partially solved, because if(aBoolean = anotherBoolean)
is a valid expression, even though the probably intention is aBoolean
== anotherBoolean.
 
M

maaxiim

Actually, the problem you described is accidental assignment, rather
than anything about NULL.
That particular problem is partially solved in java because java
requires a boolean inside conditionals, where as C/C++ (and possibly
others) allow any numeric value, and treat 0 as false, and not 0 as
true.

I say Java has partially solved, because if(aBoolean = anotherBoolean)
is a valid expression, even though the probably intention is aBoolean
== anotherBoolean.

True. I actually considered sending a quick post to clarify that I was
talking about the origin of the idiom
of placing literals on the LHS of an expression, not commenting on the
problem about nulls. I realize
I wasn't exactly clear about that and maybe was straying ever so
slightly off-topic. I had already spammed
with a correction and felt too embarrassed to spam once more.... Thanks
for giving me some additional rope :)
 
M

maaxiim

Actually, the problem you described is accidental assignment, rather
than anything about NULL.
That particular problem is partially solved in java because java
requires a boolean inside conditionals, where as C/C++ (and possibly
others) allow any numeric value, and treat 0 as false, and not 0 as
true.

I say Java has partially solved, because if(aBoolean = anotherBoolean)
is a valid expression, even though the probably intention is aBoolean
== anotherBoolean.

True. I actually considered sending a quick post to clarify that I was
talking about the origin of the idiom
of placing literals on the LHS of an expression, not commenting on the
problem about nulls. I realize
I wasn't exactly clear about that and maybe was straying ever so
slightly off-topic. I had already spammed
with a correction and felt too embarrassed to spam once more.... Thanks
for giving me some additional rope :)
 
L

Lew

maaxiim said:
I had already spammed
with a correction and felt too embarrassed to spam once more.... Thanks
for giving me some additional rope :)

It's not spam, because you were discussing the topic and providing relevant
technical analysis. Verbose, at worst, but certainly not spam.

Please keep contributing to the group.

- Lew
 
T

trippy

harryajh took the hamburger meat, threw it on the grill, and I said "Oh
Wow"...
Which is best?

String str = "hello";

if("hello".equals(str))

or

if(str.equals("hello")

does it make any difference

No.



--
trippy
mhm31x9 Smeeter#29 WSD#30
sTaRShInE_mOOnBeAm aT HoTmAil dOt CoM

NP: "Heart And Soul" -- T'Pau

"Now, technology's getting better all the time and that's fine,
but most of the time all you need is a stick of gum, a pocketknife,
and a smile."

-- Robert Redford "Spy Game"
 
T

trippy

Daniel Pitts took the hamburger meat, threw it on the grill, and I said
"Oh Wow"...
It does make a difference if str might be null.

Not that you won't get an NPE from either of these statements but we'll
play hypothetical coder just to look cool.

if ("hello".equals(str)) --> "hello" != null so it'll be false.
if (str.equals("hello"))--> null != "hello" so it'll be false.

And if you think you might be getting null, then you should either test
for it first or rewrite the code so that that possibility is eliminated.

IMO, anyway.

--
trippy
mhm31x9 Smeeter#29 WSD#30
sTaRShInE_mOOnBeAm aT HoTmAil dOt CoM

NP: "Heart And Soul" -- T'Pau

"Now, technology's getting better all the time and that's fine,
but most of the time all you need is a stick of gum, a pocketknife,
and a smile."

-- Robert Redford "Spy Game"
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,772
Messages
2,569,593
Members
45,111
Latest member
VetaMcRae
Top