Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / August 2006

Tip: Looking for answers? Try searching our database.

noob question: string comparing

Thread view: 
user - 31 Jul 2006 07:18 GMT
if i want to compare a string str to something like... the letter f,
what do i do?
(str == "f") seems to return false everytime.
Lars Enderin - 31 Jul 2006 09:22 GMT
user skrev:
> if i want to compare a string str to something like... the letter f,
> what do i do?
> (str == "f") seems to return false everytime.

The == operator compares String pointers, not values. Use
"f".equals(str). The comparison order avoids null references.
Tim Ward - 31 Jul 2006 09:48 GMT
> user skrev:
> > if i want to compare a string str to something like... the letter f,
[quoted text clipped - 3 lines]
> The == operator compares String pointers, not values. Use
> "f".equals(str). The comparison order avoids null references.

And ... for an encore ... the "byte" data type is signed!!

(There are a number of completely mad design decisions in the Java language
but these two have got to be the worst ... unless anyone can come up with
any even more ludicrous examples? There's constructors calling virtual
methods on partially-constructed objects, of course, but that one tends to
bite people later on.)

--
Tim Ward
Brett Ward Limited - www.brettward.co.uk
Eric Sosman - 31 Jul 2006 13:13 GMT
>>user skrev:
>>
[quoted text clipped - 9 lines]
> (There are a number of completely mad design decisions in the Java language
> but these two have got to be the worst ...

    The signedness of `byte' is unfortunate, and is possibly
a product of the hobgoblin of little minds.  But keeping the
notions of `==' and `.equals()' separate is another matter; if
you consider it "mad" I suspect you haven't thought about it
enough.  ("People go mad if they think too much.")

Signature

Eric Sosman
esosman@acm-dot-org.invalid

Ian Wilson - 15 Aug 2006 09:55 GMT
>>> user skrev:
>>>
[quoted text clipped - 16 lines]
> you consider it "mad" I suspect you haven't thought about it
> enough.  ("People go mad if they think too much.")

Keeping the notions of "equal value" and "refer to same object" separate
is good. But I sometimes wonder if the operators could have been
allocated in such a way as to cause least confusion to learners.

e.g. == for the extremely commonly meant 'has same string value as' and
.sameObject() for the far less used 'are both references to the same thing'.
Eric Sosman - 15 Aug 2006 15:33 GMT
Ian Wilson wrote On 08/15/06 04:55,:

>>    The signedness of `byte' is unfortunate, and is possibly
>>a product of the hobgoblin of little minds.  But keeping the
[quoted text clipped - 8 lines]
> e.g. == for the extremely commonly meant 'has same string value as' and
> .sameObject() for the far less used 'are both references to the same thing'.

   How would you test for a null reference in this scheme?

    someString.equals(null) // NPE if someString is null
    null.equals(someString) // doesn't compile
    ((String)null).equals(someString) // NPE always

I guess the test *could* be made:

    static boolean isReferenceNull(Object ref) {
       try {
           ref.getClass(); // NPE if ref is null
           return false;   // no NPE -> not null
       }
       catch (NullPointerException ex) {
           return true;    // only one way to get here
       }
    }

... but this is vile.

Signature

Eric.Sosman@sun.com

Oliver Wong - 15 Aug 2006 15:36 GMT
> Ian Wilson wrote On 08/15/06 04:55,:
>>>
[quoted text clipped - 31 lines]
>
> ... but this is vile.

   Also the compiler cannot determine whether two objects have semantically
"equal value", and so the programmer would have to provide code, which would
force the addition of operator overloading (to overload the == operator).

   - Oliver
David Segall - 31 Jul 2006 15:36 GMT
>if i want to compare a string str to something like... the letter f,
>what do i do?
>(str == "f") seems to return false everytime.
I have found it a very difficult lesson to learn but == in Java does
not have the same meaning as equals in other languages. If you want to
test for equality you need to use the equals method of the object str
so you need to test as follows:
if (str.equals"f") {...
or, God forbid,
if ("f".equals(str)) {...

It seems that origin of this is that it is much easier, when writing
an interpreter that is meant to work in a tiny "set top box" computer,
to test for equality between two pointers to an object than to test if
a human interpretation of the two objects are equal. Consequently,
unless the arguments are primitive types, == just checks to see if the
two arguments are the same object.
Eric Sosman - 31 Jul 2006 16:07 GMT
David Segall wrote On 07/31/06 10:36,:

>>if i want to compare a string str to something like... the letter f,
>>what do i do?
[quoted text clipped - 14 lines]
> unless the arguments are primitive types, == just checks to see if the
> two arguments are the same object.

   It's not a matter of easier or harder, but of modelling
the real world satisfactorily.  The real world presents us
with multiple different notions of "equality," two of which
are supported by Java:

  - Identity: Two objects A and B are "equal" if they are
    in fact the same object under different names.  "David"
    and "Mr. Segall" refer to the same object (granting a
    suitable universe of discourse), so they are equal.
    This is the "equality" Java's == operator tests.

  - Equivalence: Two objects A and B are "equal" if they
    are of the same class and have the same "value."  This
    bottle of Pirelli's Miracle Elixir contains 100 ml. of
    that efficacious fluid, that other bottle holds the
    same amount of the same stuff, so the two bottles are
    "equal" in the sense of being equivalent.  This is the
    notion the equals() method tests (depending, of course,
    on how the class defines the method).

   If you are having trouble separating these two notions,
consider your wallet for a moment.  By pure coincidence, it
happens to contain the same amount of money as my wallet.
The two wallets are therefore equal in purchasing power; does
that mean they are the same wallet?  If so, hand over your
wallet immediately: it's mine!

Signature

Eric.Sosman@sun.com

David Segall - 31 Jul 2006 17:17 GMT
>David Segall wrote On 07/31/06 10:36,:
>>
[quoted text clipped - 29 lines]
>that mean they are the same wallet?  If so, hand over your
>wallet immediately: it's mine!
I don't dispute your two concepts of equality but you have used
sleight of hand to claim my wallet. I have no objection to being
forced to explicitly compare wallet.colour, wallet.size etc in
addition to wallet.value to protect my wallet. Java confuses beginners
because it assigns a default property (.value) to a String object in
the equals() method but omits that property and insists on using the
unfamiliar concept of "identity" with the == operator. This contrasts
with most (all?) other languages which is why I concluded that it was
done for the benefit of the interpreter programmer rather than the
application programmer.
Oliver Wong - 31 Jul 2006 18:00 GMT
>> The real world presents us
>>with multiple different notions of "equality," two of which
[quoted text clipped - 26 lines]
> forced to explicitly compare wallet.colour, wallet.size etc in
> addition to wallet.value to protect my wallet.

   I don't think the wallet is the greatest example, but you could imagine
that your wallet and Eric's wallet are identical in every respect (colour,
number of protons, electrons and neutrons that compose it, etc.), but the
two wallets are still distinct.

   Maybe this example will be better:

   Alice and Bob are speaking:

Alice: "I'm thinking of a specific friend."
Bob: "I too am thinking of a specific friend."
Alice: "My friend is 28 years old."
Bob: "My friend is also 28 years old."
Alice: "My friend has brown eyes, blond hair."
Bob: "Mine too."
Alice: "My friend's name is Charlie."
Bob: "So is mine!"
[etc. This goes on, Alice listing a whole bunch of attributes about her
friend, and Bob saying those same attributes apply to his friend.]

   So, are Alice and Bob thinking about the same person? It might be, or it
might not be. It's possible that they are speaking about two completely
different people who are remarkably similar, or it might be that they are in
fact speaking about the exact same person, not knowing that they had a
common friend.

Alice: "Well, my friend Charlie's cell phone number is 12345678901."
Bob: "Oh, well I don't know what my Charlie's cell phone number is. However,
his house number is 19876543210."
Alice: "Hmm, I don't know what my friend's Charlie's home number is."

   Just like a person can have multiple phone numbers, so can objects in
Java have multiple references pointing to them. The fact that you have two
different references doesn't nescessarily mean you have two different
objects!

Alice: "Well, my friend Charlie lives alone at 22 Baker Street."
Bob: "Ah, so does mine. So we must be talking about the same person."

   One way to think of it is that references are sort of like pointers
which hold the address of the objects they are refering to. When you use the
== operator on two reference, it's comparing the addresses that each
reference points to, to see if they are identical. When you invoke the
.equals() method, you're invoking it on a specific object, and that method
is free to do anything the programmer designed it to do. In fact, it can
even "lie" to you and return false when you check if an object is equal to
itself, or it can be programmed to erase all the files on your haddrive,
etc.

   Usually, you assume that the programmer who wrote the equals is not
malicious, and you can just read the documentation for the equals() method
to find out exactly how it determines equality between two objects, or
failing that, read the source code itself.

> Java confuses beginners
> because it assigns a default property (.value) to a String object in
> the equals() method but omits that property and insists on using the
> unfamiliar concept of "identity" with the == operator.

   I think this "assigning a default property (.value) to a String object"
explanation may be very misleading. The JVM never creates fields out of
nowhere. If a object has a field, it's because the class that defines that
object declared the field. If you look at the source code for the String
class, it actually has 4 fields:

   private final char value[];
   private final int offset;
   private final int count;
   private int hash;

If you check the source code for the equals() method in String, you'll see
it essentially does a character-by-character scan from value[offset] to
value[offset + count - 1] to check if two string objects are equal. So it's
possible that two String object have completely different field values, but
are evaluated to be equal! For example if the two String's field values are:

StringOne {
 value[] = {'A', 'B', 'C', '1', '2', '3'}
 offset = 3;
 count = 3;
 hash = 42;
}

and

StringTwo {
 value[] {'1', '2', '3', 'X', 'Y', 'Z'}
 offset = 0;
 count = 3;
 hash = 69;
}

StringOne.equals(StringTwo) would return true, because of the way it's
programmed.

> This contrasts
> with most (all?) other languages which is why I concluded that it was
> done for the benefit of the interpreter programmer rather than the
> application programmer.

   I think what you were missing was the fact that the .equals() method can
be programmed to do anything the programmer wishes.

   - Oliver
Eric Sosman - 31 Jul 2006 18:28 GMT
David Segall wrote On 07/31/06 12:20,:
> [...]
> I don't dispute your two concepts of equality but you have used
> sleight of hand to claim my wallet.

   Sleight of hand, prestidigitation, trickery and ruses,
scams and frauds -- if I can grab other peoples' wallets,
it's all worth while! ;-)

> I have no objection to being
> forced to explicitly compare wallet.colour, wallet.size etc in
> addition to wallet.value to protect my wallet. Java confuses beginners
> because it assigns a default property (.value) to a String object in
> the equals() method but omits that property and insists on using the
> unfamiliar concept of "identity" with the == operator.

   I'm not at all sure what you mean by a "default" property.
The String.equals() method makes a computation, just as other
equals() methods -- other anything() methods -- make their
computations.  String.equals() takes one set of things into
account; BigInteger.equals() computes things differently;
neither seems (to me) to "default" to anything.

> This contrasts
> with most (all?) other languages

   Here I must disagree, although it's risky: I've used only
a couple dozen programming languages, well short of "most."
But among those I've used that support the notion of "reference"
as a first-class value, I cannot think of any that make Java
seem at all unusual in this regard.  All of them made a clear
distinction between the reference and the thing referred to.

   In C, consider

    char *p = "Hello, world!";
    char *q = malloc(strlen(p) + 1);  /* assume success */
    strcpy (q, p);

This fragment points p at a character string, then points q
at an exact copy of that string.  At this point p and q are
not == because they point to different string instances, yet
strcmp(p, q) reports that the strings compare equal.  This
should seem eerily similar to Java's behavior with

    String p = "Hello, world!";
    String q = new String(p);

   And if you find two notions of "equality" confusing, it's
a good thing you never encountered Lisp!  My Lisp days are far
behind me and my memory of them has gone a bit foggy, but I
recall that Common Lisp supports at least four different notions
of equality, maybe five.

> which is why I concluded that it was
> done for the benefit of the interpreter programmer rather than the
> application programmer.

   I don't think the conclusion follows from the premise.

Signature

Eric.Sosman@sun.com

dsjoblom@abo.fi - 31 Jul 2006 18:11 GMT
> It seems that origin of this is that it is much easier, when writing
> an interpreter that is meant to work in a tiny "set top box" computer,
> to test for equality between two pointers to an object than to test if
> a human interpretation of the two objects are equal. Consequently,
> unless the arguments are primitive types, == just checks to see if the
> two arguments are the same object.

Which also happens to be the case with pointers in C. And since java
borrows heavily on syntax (and some semantics) from C, and java
references are essentially pointers, the function of == is not that
surprising, and has nothing to do with ease of implementation. I might
also add that if the == operator didn't do what it currently does, we
would need some other way of checking reference equality.

Regards,
Daniel Sjöblom


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.