Expressions and Boolean Values in Java
Java's relational operators are ==, !=, <, >, <=, and >=.
Why a Comparison Produces a Result
A comparison in Java is an expression. Like any expression, it produces a value, and the value it produces is a boolean: either true or false. Java's relational operators are ==, !=, <, >, <=, and >=. Each one takes two operands and asks a yes-or-no question about them, such as whether the left side is less than the right side, or whether the two sides are equal.
Because a comparison yields a boolean, you can use it directly in an if statement, store it in a boolean variable, or combine it with another comparison. This article traces what happens inside these expressions for four kinds of values: numbers, characters, boolean values, and Strings. It also covers one special floating-point value, Double.NaN, which behaves differently from ordinary numbers.
Two Variables, Two Objects
Before looking at operators, trace what two String variables hold. In the diagram below, each variable a and b refers to its own String object. Both objects contain the same text, but they are separate objects stored in different places. This is the situation that makes == misleading for Strings.
The source states that == checks object storage location rather than string content. Here, a and b refer to different objects, so a == b asks whether they refer to the same object, and the answer is false. The text inside the two objects is identical, but == does not look at that text. The equals() method compares the contents, so a.equals(b) is true.
Relational Operators on Numbers
Relational operators can compare values of any numeric type. The six operators divide into two families. The equality operators, == and !=, ask whether two values are the same or different. The ordering operators, <, >, <=, and >=, ask how two values relate in order: less than, greater than, less than or equal to, or greater than or equal to.
- == and != are the equality operators; each result is a boolean
- < and > are the ordering operators and test the direction of the difference
- <= and >= include the boundary value, so 17 <= 17 is true
Checking a Voting Condition
Write a boolean expression that is true when a person is 18 or older, and then evaluate it for age 17 and age 18.
- 1Choose the operator
We need the value to be at least 18, which means the ordering operator >= fits the question.
- 2Write the expression
The expression is age >= 18. Its result is a boolean.
- 3Evaluate for 17
17 >= 18 asks whether 17 is at least 18. That is false.
- 4Evaluate for 18
18 >= 18 is true, because >= includes equality.
age >= 18 is false for 17 and true for 18.
How Characters Are Ordered
Relational operators also compare char values. For characters, the operators < and > use the characters' numeric Unicode values. A char is compared through its number, so the ordering you get is the numeric ordering of those codes. That is why 'a' < 'b' is true: the code for 'a' is smaller than the code for 'b'.
The ordering is numeric, not alphabetical in the everyday sense. The source notes that all uppercase letters come before all lowercase letters. So 'Z' is less than 'a', even though a dictionary would list a before Z. The diagram shows why: every uppercase letter has a smaller code than every lowercase letter. A learner who expects alphabetical behavior should check the codes instead.
- 'a' is 97 and 'b' is 98, so p < q is true
- 'B' is 66, which is smaller than 'a' (97), so p < r is false
- Uppercase letters all come before lowercase letters in this ordering
Comparing Boolean Values
The operators == and != can also compare boolean values. This matters most when the operands are themselves comparison results. Each comparison inside the expression is evaluated first and becomes true or false, and then the outer operator compares those two boolean results. Read the expression in that order.
- score >= 60 evaluates to true, and score >= 90 evaluates to false
- The == test compares those two boolean results, not the original numbers
- != returns true whenever the two boolean results differ
What do you think happens?
Before reading the answer, predict the value of (5 > 3) == (2 < 1). Is it true or false?
Reveal answer
false
5 > 3 is true and 2 < 1 is false. The expression becomes true == false, which is false.
Comparing Strings Correctly
When you want to know whether two Strings contain the same text, the correct tool is equals(). When you want to know how two Strings order relative to each other, use compareTo(). The source is clear that String contents should be compared with these methods. The == operator checks object storage location rather than string content, so it answers a different question from the one most programs need answered.
- Each new
String(...)creates its own object, so == compares two different locations equals()checks whether the contents matchcompareTo()returns a negative number when the first String sorts before the second
Common mistake Using == to compare the text of two Strings
What it looks likeString a = new String("hi"); String b = new String("hi"); a == bWhy it fails== checks whether both variables refer to the same object, not whether the text matches, so this is false even though the text is equal.
Do this insteadUse a.equals(b), which compares the contents and returns true here.
Testing for Double.NaN
Double.NaN is a special floating-point value that means not a number. It is the result of some arithmetic, for example dividing zero by zero with doubles. Because NaN is special, you cannot detect it by comparing against it with ==. An expression like x == Double.NaN returns false even when x is NaN. The correct way to test is Double.isNaN(x), which returns true exactly when x is NaN.
- Dividing 0.0 by 0.0 produces NaN in Java floating-point arithmetic
- == against
Double.NaNis always false, so it cannot detect NaN Double.isNaN(x)is the test that works
Practice Tracing Comparisons
Given int n = 7; char c = 'M'; String s1 = new String("cat"); String s2 = new String("cat"); double d = 0.0 / 0.0;
For each expression below, decide whether it is true or false, then check your answer by reasoning about the operator and the value type: (a) n > 5, (b) c < 'a', (c) s1 == s2, (d) s1.equals(s2), (e) Double.isNaN(d), (f) (n > 5) != (c > 'N').
Hints
- For (b), compare the numeric codes: 'M' is 77 and 'a' is 97.
- For (c), remember that == checks whether both variables refer to the same object.
- For (f), first evaluate n > 5 and c > 'N' as booleans, then apply !=.
Key Takeaways
- Java's relational operators are ==, !=, <, >, <=, and >=, and each one produces a boolean value that can be used in a condition or stored in a variable.
- For char values, the ordering operators compare Unicode numeric codes, so all uppercase letters come before all lowercase letters.
- == and != can compare boolean values, and when the operands are comparison results, each comparison is evaluated first.
- Compare String contents with
equals()orcompareTo(), because == checks object storage location rather than the text. - Detect
Double.NaNwithDouble.isNaN(x), because comparing againstDouble.NaNwith == does not reliably detect it.