Skip to content
Ameen Abozaid
PublishedBEG-010-L02

Comparison and logical operators

  • Lesson 2 of 6
  • 12 min read
  • Beginner
On This Lesson 11 topics

Lesson Overview

Arithmetic operators produce numbers. Comparison and logical operators produce a different kind of value: true or false, the boolean type you met in BEG-009. These are the operators that let a program ask questions: "Is the user an adult?", "Is the cart empty?", "Is the number between 1 and 10?"

In this lesson you will build yes/no expressions from small pieces. First you compare two values (age >= 18), then you combine several answers (age >= 13 && age <= 19). Using the calculator picture from the last lesson: arithmetic buttons give you a number on the display, and these buttons give you a light that is either on or off.

Why this matters: every decision a backend makes starts as a boolean expression. Is the password correct? Is the token still valid? Is the stock level positive? In a later module you will use these expressions to choose which code to run. Here you learn to write and evaluate them correctly, because a slightly wrong condition is a bug that compiles.

This lesson builds on Lesson 1 (operators and expressions) and on boolean variables from BEG-009.

Learning Objectives

By the end of this lesson you will be able to:

  • Use the six comparison operators ==, !=, <, >, <=, >= and state that each gives a boolean.
  • Explain the difference between = (assignment) and == (comparison).
  • Combine boolean values with &&, ||, and !, and use a truth table to evaluate them.
  • Write "x is between a and b" correctly, and explain why 1 < x < 10 does not compile.
  • Predict mixed expressions that use both && and ||, including the order in which Java groups them.
  • Compare text with .equals and not with ==.

Written Explanation

Comparison operators

A comparison looks at two values and answers with a boolean.

OperatorMeaningExample (a is 5)Result
==equal toa == 5true
!=not equal toa != 5false
<less thana < 8true
>greater thana > 8false
<=less than or equala <= 5true
>=greater than or equala >= 6false

You can store the answer like any other value: boolean adult = age >= 18;. The right side is calculated first and its true or false is stored in adult.

Numbers of different types can be compared; Java converts to the wider type first, so 5 == 5.0 is true.

= is not ==

These two symbols look alike and do completely different jobs:

  • = is assignment: "store the value on the right into the variable on the left." It changes the program's state.
  • == is comparison: "are these two values equal?" It only produces true or false.

In Java the mix-up is usually caught for you. Writing boolean same = x = 5; fails to compile, because the assignment x = 5 produces an int, not a boolean:

text
error: incompatible types: int cannot be converted to boolean

Do not rely on this alone, though. Some languages let = in a condition slip through. A good habit: read = aloud as "becomes" and == as "equals".

Logical operators

Logical operators take boolean values and produce a boolean.

OperatorNameResult is true when
&&andboth sides are true
||orat least one side is true
!notthe single operand is false

The complete truth table for two values:

aba && ba || b
truetruetruetrue
truefalsefalsetrue
falsetruefalsetrue
falsefalsefalsefalse

! flips one value: !true is false and !(3 > 5) is true. || is the inclusive or: it is true also when both sides are true, unlike the everyday "tea or coffee" that often means one of them.

Between two limits

In mathematics you write 1 < x < 10. In Java that does not compile. Java reads it left to right: 1 < x is a boolean, and then it tries boolean < 10, which makes no sense:

text
error: bad operand types for binary operator '<'
  first type:  boolean
  second type: int

Write the two comparisons separately and join them with &&:

java
x > 1 && x < 10

The opposite, "x is outside the range", uses ||: x < 1 || x > 10. A frequent slip is to write || where && is needed. x > 1 || x < 10 is true for every number, because every number is either above 1 or below 10.

Which one is evaluated first

When && and || appear together, Java follows precedence, just like * before +. The order from highest to lowest is: !, then comparisons (<, >, <=, >=), then == and !=, then &&, then ||. The Java Tutorials' precedence table gives this order.

So true || false && false is true || (false && false), which is true || false, which is true. With parentheses the meaning changes: (true || false) && false is false. Parentheses cost nothing and tell the reader what you meant, so use them whenever && and || are mixed.

Comparing text

== on numbers asks "are the values the same?" On String it asks something different (whether two variables point at the very same object), and that is not what you usually want. To compare the text, use the .equals method that you saw in BEG-009:

java
String name = "Ana";
name.equals("Ana")   // true
name.equals("ana")   // false: case matters

The full explanation of why == is wrong here belongs to a later module. For now: numbers with ==, strings with .equals.

Floating-point caution

Because double stores approximations (BEG-009), 0.1 + 0.2 == 0.3 is false. Avoid == on decimals that came out of calculations. Use whole numbers, such as cents, when you need exact comparisons.

Examples

Example 1: simple comparisons (simple)

java
public class Cmp {
    public static void main(String[] args) {
        int a = 5;
        int b = 8;
        System.out.println(a == b);
        System.out.println(a != b);
        System.out.println(a < b);
        System.out.println(a >= 5);
        System.out.println(5 == 5.0);
        System.out.println(0.1 + 0.2 == 0.3);
        String s1 = "Ana";
        System.out.println(s1.equals("Ana"));
        System.out.println(s1.equals("ana"));
    }
}

Output (JDK 21):

text
false
true
true
true
true
false
true
false

Lines 5 and 6 are the two surprises: 5 == 5.0 is true because the int is widened, but the decimal sum is not exactly 0.3.

Example 2: building conditions (practical)

java
public class Logic {
    public static void main(String[] args) {
        int age = 20;
        boolean adult = age >= 18;
        boolean teen = age >= 13 && age <= 19;
        boolean student = true;
        boolean discount = age < 12 || age >= 65 || student;
        System.out.println(adult + " " + teen + " " + discount);
        System.out.println(!adult);
        System.out.println(true || false && false);
        System.out.println((true || false) && false);
        int x = 7;
        System.out.println(x > 1 && x < 10);
        System.out.println(x < 1 || x > 10);
        int day = 6;
        boolean weekend = day == 6 || day == 7;
        System.out.println(weekend);
    }
}
text
true false true
false
true
false
true
false
true

Read the first line: 20 is an adult, is not a teen (the range ends at 19), and gets a discount because student is true. Lines 3 and 4 show how parentheses change the meaning of the same four symbols. In weekend, notice that you must write day == 6 || day == 7; you cannot write day == 6 || 7.

Example 3: a checkout rule (realistic)

A shop lets a user check out only if they are logged in, have at least one item, and are not suspended. A product needs reordering when stock is zero or lower than what is in the cart.

java
public class Shop {
    public static void main(String[] args) {
        boolean loggedIn = true;
        int cartItems = 3;
        boolean suspended = false;
        int stock = 0;
        boolean canCheckout = loggedIn && cartItems > 0 && !suspended;
        boolean needsReorder = stock == 0 || stock < cartItems;
        System.out.println("canCheckout: " + canCheckout);
        System.out.println("needsReorder: " + needsReorder);
    }
}
text
canCheckout: true
needsReorder: true

canCheckout chains three conditions with &&, so any one false makes the whole thing false. Each variable name states a business rule, which is far easier to review than a long inline expression. This habit pays off in real services, where rules are changed and tested often.

Backend Insight

Boolean expressions are the language of business rules in a backend: "may this user see this record?", "is this coupon still valid?", "has the request exceeded the limit?". They also appear in filters, such as the WHERE clause of a database query in the SQL modules, which uses the same ideas (AND, OR, NOT) with slightly different spelling.

Two professional habits start here:

  • Name your conditions. boolean canCheckout = ... beats a 90-character expression in the middle of other code, and it can be unit tested.
  • Test the boundaries. Rules such as age >= 18 and age > 18 differ only at one value, 18, and that is where bugs live. Testers spend much of their time exactly there, which is why this reappears in the later testing modules.

Common Mistakes

Mistake 1: = where == was meant

  • Incorrect: boolean same = x = 5; (does not compile, as shown above)
  • Correct: boolean same = x == 5;

Mistake 2: Chaining comparisons

  • Incorrect: 1 < x < 10
  • Correct: x > 1 && x < 10

Mistake 3: Incomplete comparison with ||

  • Incorrect: day == 6 || 7 (does not compile: 7 is not a boolean)
  • Correct: day == 6 || day == 7

Mistake 4: || where && is needed

x > 1 || x < 10 is true for every number. For "between", both limits must hold, so use &&.

Mistake 5: Using == on text or on calculated decimals

Use .equals for strings, and avoid exact == on decimals produced by arithmetic.

Mistake 6: Off-by-one boundary

age > 18 leaves out 18-year-olds, age >= 18 includes them. Decide which one the rule means, and test the value 18 itself.

Exercises

Try each exercise yourself before opening the solutions. Predict before you run anything.

Level A: Foundation

A1. With int n = 12; evaluate: n > 10, n == 12, n != 12, n <= 11.

Show solution A1

A1. true, true, false, false.

A2. Evaluate: true && true, true && false, false || true, !false.

Show solution A2

A2. true, false, true, true.

A3. Which of these is a correct way to write "score is at least 50 and below 100"? (a) 50 <= score < 100 (b) score >= 50 && score < 100 (c) score >= 50 || score < 100

Show solution A3

A3. (b). Option (a) does not compile, and (c) is true for every number.

Level B: Application

B1. Write a boolean expression that is true when a number m is a valid month number (from 1 to 12). Then write one that is true when it is not valid.

Show solution B1

B1. Valid: m >= 1 && m <= 12. Not valid: m < 1 || m > 12 (or !(m >= 1 && m <= 12)).

B2. Write an expression for "a password is acceptable": its length len is at least 8, and it has not been used before (boolean reused).

Show solution B2

B2. len >= 8 && !reused.

B3. Evaluate by hand, using precedence, then add parentheses that show how Java groups it: false && true || true, and true || true && false.

Show solution B3

B3. false && true || true groups as (false && true) || true, which is false || true, which is true. true || true && false groups as true || (true && false), which is true || false, which is true.

Level C: Challenge

C1. A café sells a "student or senior" discount: the price drops if age >= 65 or the person is a student, but only if the shop is open (boolean open). Write the expression. Then rewrite it with a deliberately wrong grouping (missing parentheses) and give one set of values where the two versions disagree.

Show solution C1

C1. open && (age >= 65 || student). Without the parentheses, open && age >= 65 || student groups as (open && age >= 65) || student, so a student gets the discount even when the shop is closed. With open false, age 20, and student true, the correct version is false and the wrong one is true.

C2. Does !(a && b) always give the same result as !a || !b? Check all four combinations of a and b with a truth table.

Show solution C2

C2. Yes. For (true, true): !(true) is false, and false || false is false. For (true, false): !(false) is true, and false || true is true. For (false, true): both sides are true. For (false, false): both sides are true. All four rows match. (This rule is called De Morgan's law, a handy way to simplify negated conditions.)

Mini Challenge

Write a program Rules with these fixed variables: int age = 16; boolean hasTicket = true; boolean banned = false; int seatsLeft = 0;.

  1. Create a boolean canEnter: the person is at least 12, has a ticket, and is not banned.
  2. Create a boolean soldOut: no seats are left.
  3. Create a boolean needsAdult: age is under 18.
  4. Print all three with labels. Predict each on paper first.

Then change age to 12 and then to 11 and see which results flip. Check your work: you used &&, ||, and ! at least once, and wrote no chained comparisons.

Summary & Next Lesson

Key takeaways

  • Comparison operators == != < > <= >= produce a boolean.
  • = assigns; == compares. Read them aloud as "becomes" and "equals".
  • && needs both sides true, || needs at least one, ! flips a value.
  • "Between" is written with two comparisons joined by &&: x > 1 && x < 10.
  • && is grouped before ||; add parentheses when mixing them. Use .equals for text.

Next lesson

Next is "Assignment and compound assignment": how = really works, and shortcuts such as += that update a variable using its own value.

Self-check

  1. What kind of value does a >= b produce?
  2. What is the difference between = and ==?
  3. How do you write "x is between 1 and 10" in Java?
  4. What is false || true && false?
  5. How should you check whether two strings have the same text?
Show answers
  1. A boolean: true or false.
  2. = stores a value into a variable. == compares two values and produces true or false.
  3. x > 1 && x < 10 (or with >= and <= if the limits are included).
  4. false. It groups as false || (true && false), which is false || false.
  5. With .equals, for example name.equals("Ana").

References

  • Oracle, The Java Tutorials: Operators. It lists the relational, equality, and conditional operators and the precedence table (! and relational above equality, && above ||).
  • Oracle, The Java Language Specification, Java SE 21, Chapter 15: Expressions. Sections 15.23 and 15.24 describe && and || on boolean operands.
  • The two compiler messages and all outputs above were produced by compiling and running the code with JDK 21. The statement that == on String compares object identity is a standard Java fact that I did not re-verify on a page here; the course explains it fully in a later module.
  • The 0.1 + 0.2 behavior is covered in BEG-009 and was confirmed by running the code.

Practice

Apply this lesson with the module's lab, exercises and quiz.

Lab and exercises Quiz

Marking a lesson complete is optional and you can undo it any time. Your progress stays in this browser.

Continue to next lesson

Type to search levels, phases, modules and lessons.