3.2 Comparing Strings
The relational operators used to compare primitive types should not be
used to compare strings. The reason for this is based on the way that
string objects are stored in Java. Suppose that we have written String s1 = "Hello";
String s2 = "Hello";
We can represent the result of executing these statements with a diagram.

     Because both sl and s2 refer to strings with identical values, the Java
compiler tries to save space by only allocating memory for one copy of the
string "Hello" and having both sl and s2 refer to this location.
     On the other hand, if we were to write
String sl = "Hello";
String s2 = "He";
s2 += "llo";
then both sl and s2 will still refer to a string with the value "Hello" but
now, because we have constructed the two strings in different ways, the
Java compiler will probably not realize that they are the same2 and will
create two distinct copies of the string. The next diagram illustrates the
resulting situation.

     If we write the expression sl == s2, Java evaluates this by comparing
the values stored in s1 and s2, not the strings to which s1 and s2 refer.
If sl and s2 refer to the same copy of a string (as in our first case), then
sl == s2 will have the value true but if they refer to different copies of
the same string (as in our second case), then s1 == s2 will have the value
false because sl and s2 contain different memory references.
     If we want to compare values of strings rather than the values of references
to those strings, we should use methods. Java provides a number of
methods for comparing strings. In this section, we will examine only two.
In Chapter 9, we examine strings in more detail.

     To test whether or not two string variables are referring to equal string
objects, we can use the method equals from the String class. The method
tests two strings for equality and returns the value true if the strings are
identical and false otherwise. This method is used in a manner that is somewhat different from that used for the methods of the Math class that
we saw in Chapter 2. If s1 and s2 are both references to strings, then the
expression
s1.equals(s2)
will have the value true if and only if the values of the two strings are identical.
2We say "probably" because some Java compilers are better than others at detecting
this sort of thing.
Example 1Given the declaration
String s = "Same";
then
(a) s.equals("Same") will return true
(b) s.equals("same") will return false because 'S' ≠ 's'
(c) s.equals("Same ")will return false because of the blank in the string "Same "
|
|

The lexicographic order of two strings is, essentially, their dictionary
order; it is based on the collating sequence of the characters in the strings.
To determine the lexicographic order of a pair of strings, we can use
the method compareTo from the String class. In comparing strings, the
method proceeds from left to right, character by character, as long as corresponding
characters are identical. This process can terminate in one of
three ways:
• The end of both strings is reached with all characters equal; the
strings are identical.
• The end of one string is reached but the other is not; the shorter
string precedes the longer string.
• A character in one string differs from the corresponding character
in the other string; the string having the character earlier in Java's
collating sequence precedes the other string.
The method compareTo returns an integer value that indicates the lexicographic
ordering of two strings. If s1 and s2 are both references to strings,
then the expression
s1.compareTo(s2)
has the value zero if s1 is identical to s2, a negative value if s1 precedes
s2, and a positive value if s1 follows s2.
Example 2
(a) "cab".compareTo("car") < 0 because 'b' < 'r'
(b) "Car".compareTo("car") < 0 because 'C' < 'c'
(c) "27".compareTo("186") > 0 because '2' > '1'
(d) "car".compareTo ("cart") < 0 because "car" is only the first part
of "cart"
|
|
The compareTo method can be used to implement any of the six relational
operators (<, <=, >, >=, ==, or !=) by writing expressions of the form
<string1>.compareTo(<string2>) <op> 0
where <op> is one of the six relational operators. For example, if s1 and
s2 are both references to strings, then the expression
s1.compareTo(s2) <= 0
has the value true if and only if the string s1 precedes or is identical to
the string s2.
Exercises 3.2
- For each of the following pairs of strings, state, with reasons, which
string precedes the other.
- "cat" and "dog"
- "cat" and "Cathy"
- "X " and " X"
- "cab" and "CAR"
- "XX" and "X X"
- "XY" and "XY "
- "375" and "84"
- "" and " "
- State the value of each expression.
- "one".equals("one ")
- "two".equa1s("2")
- "Three".equa1s("Three")
- "four".equa1s("for")
- State whether the value of the expression is negative, zero, or positive.
- "for".compareTo("fore")
- "fore".compareTo("force")
- "force".compareTo("Force")
- "Force".compareTo("Farce")
- "Farce".compareTo("Fare")
- "Fare".compareTo ("far")
- "far".compareTo("far")
- "far".compareTo("far ")
- Suppose that s1 and s2 are variables of type String. Write an expression
of the form s1.compareTo(s2) <op> 0 that will have the
value true if and only if the stated condition is true.
- s1 is identical to s2
- s1 precedes s2
- s1 is identical to or follows s2
- s1does not follow s2
| |