Java
Programming
Integer Comparison
Coding Tips
Java Methods

How can I properly compare two Integers in Java?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

For primitive int values, use == and other comparison operators directly. For Integer wrapper objects, use .equals() for equality and Integer.compare() or .compareTo() for ordering. The critical rule is to never use == to compare Integer objects for value equality, because == checks reference identity, not numeric value. This distinction catches even experienced Java developers due to the Integer cache, which makes == appear to work for small values before failing on larger ones.

Comparing Primitive int Values

Primitive int comparisons are straightforward. The operators ==, !=, <, >, <=, and >= all compare numeric values directly:

java
1int a = 1000;
2int b = 1000;
3
4System.out.println(a == b);  // true
5System.out.println(a < b);   // false
6System.out.println(a != b);  // false

No reference semantics are involved. The JVM compares the actual bit patterns on the stack. If your variables are primitive int, stay in the primitive world. It is simpler, faster, and free of null-related surprises.

Comparing Integer Wrapper Objects

When working with Integer objects (from collections, database results, JSON parsing, or method signatures that require objects), use these methods:

equals() for Value Equality

java
1Integer x = 200;
2Integer y = 200;
3
4System.out.println(x.equals(y));  // true

equals() compares the numeric value inside both objects. It returns false if the argument is null, so calling x.equals(null) is safe and returns false. However, calling null.equals(y) throws NullPointerException.

compareTo() for Ordering

java
1Integer x = 100;
2Integer y = 200;
3
4System.out.println(x.compareTo(y));  // negative (x < y)
5System.out.println(y.compareTo(x));  // positive (y > x)
6System.out.println(x.compareTo(x));  // 0 (equal)

compareTo() returns a negative integer, zero, or positive integer. It is the natural comparison method required by Comparable<Integer> and used by sorted collections like TreeSet and TreeMap.

Integer.compare() for Static Comparison

java
int result = Integer.compare(100, 200);  // negative

Integer.compare(int a, int b) takes primitive int parameters, avoiding autoboxing overhead. It is the preferred choice in comparator lambdas:

java
List<Integer> numbers = Arrays.asList(5, 2, 8, 1, 9);
numbers.sort(Integer::compare);
// Result: [1, 2, 5, 8, 9]

Why == Fails with Integer Objects

When applied to objects, == checks whether both references point to the same object in memory, not whether they hold the same numeric value:

java
1Integer a = new Integer(5);
2Integer b = new Integer(5);
3
4System.out.println(a == b);      // false (different objects)
5System.out.println(a.equals(b)); // true  (same value)

The Integer Cache Trap

Java caches Integer objects for values between -128 and 127 (by default). When autoboxing produces a value in that range, it returns the cached instance. This makes == appear to work correctly for small values:

java
1Integer small1 = 100;   // cached
2Integer small2 = 100;   // same cached instance
3Integer large1 = 200;   // not cached, new object
4Integer large2 = 200;   // not cached, different new object
5
6System.out.println(small1 == small2);  // true  (same cached object)
7System.out.println(large1 == large2);  // false (different objects)

This is exactly why == with Integer is dangerous. Code that tests fine with small test values silently breaks when production data exceeds 127. The cache range can be extended with the JVM flag -XX:AutoBoxCacheMax=N, but relying on cache behavior for correctness is fundamentally wrong.

Complete Comparison Behavior Table

ExpressionPrimitive intInteger (cached range)Integer (outside cache)
a == bCompares valuestrue (same object)false (different objects)
a.equals(b)N/A (primitives)truetrue
Integer.compare(a, b)Compares values00
a.compareTo(b)N/A (primitives)00
Objects.equals(a, b)N/A (primitives)truetrue

Handling Null Safely

Integer can be null, unlike primitive int. Null handling is critical when values come from database queries, API responses, or optional fields:

java
1import java.util.Objects;
2
3Integer left = null;
4Integer right = 42;
5
6// Safe: Objects.equals handles null on either side
7System.out.println(Objects.equals(left, right));  // false
8System.out.println(Objects.equals(left, null));   // true
9System.out.println(Objects.equals(right, right)); // true
10
11// Unsafe: throws NullPointerException
12// left.equals(right);  // NPE
13// left.compareTo(right);  // NPE
14// left == right;  // false, but for wrong reason (reference check)

Objects.equals() is null-safe on both sides. Use it as the default when either argument might be null.

For ordering with potential nulls, use Comparator.nullsFirst or Comparator.nullsLast:

java
1import java.util.Comparator;
2import java.util.Arrays;
3import java.util.List;
4
5List<Integer> values = Arrays.asList(3, null, 1, null, 2);
6values.sort(Comparator.nullsLast(Integer::compare));
7// Result: [1, 2, 3, null, null]

Unboxing: Converting Back to Primitives

If null is impossible (or has already been validated), unboxing to int simplifies comparison:

java
Integer boxed = 42;
int value = boxed;  // auto-unboxing
System.out.println(value == 42);  // true, primitive comparison

But unboxing a null reference throws NullPointerException:

java
Integer maybeNull = null;
int value = maybeNull;  // throws NullPointerException at runtime

A safe unboxing pattern:

java
1public static int safeUnbox(Integer value, int defaultValue) {
2    return value != null ? value : defaultValue;
3}
4
5int timeout = safeUnbox(config.getTimeout(), 30);

Choosing the Right Comparison Method

ScenarioMethodWhy
Two primitive int values==, <, >Direct value comparison, no overhead
Two Integer objects, no nulls.equals()Value equality without cache dependency
Either might be nullObjects.equals()Null-safe on both sides
Ordering / sortingInteger.compare() or .compareTo()Returns negative/zero/positive
Sorting with nullsComparator.nullsFirst(Integer::compare)Explicit null placement policy
Comparator lambdaInteger::compareAvoids autoboxing, clean syntax

Common Pitfalls

  • Using == with Integer objects. This is the most common Java integer comparison bug. It compares object references, not values. The Integer cache makes it appear correct during testing with small numbers, then fail in production.
  • Being fooled by the Integer cache. Values -128 to 127 share cached instances, so == works coincidentally. Values outside this range create new objects, and == returns false even for equal values.
  • Calling .equals() on a potentially null reference. null.equals(something) throws NullPointerException. Use Objects.equals() when either side may be null.
  • Unboxing without null checks. int x = nullableInteger compiles cleanly but throws at runtime. Always validate or provide defaults before unboxing.
  • Mixing primitives and wrappers in conditionals. Expressions like someInteger == 5 trigger auto-unboxing of someInteger, which throws if it is null. The compiler does not warn about this.
  • Using Integer.valueOf() expecting unique objects. Integer.valueOf(127) == Integer.valueOf(127) is true due to caching, but this is an implementation detail, not a contract. Do not rely on it.

Summary

  • Use == and comparison operators for primitive int values only.
  • Use .equals() or Objects.equals() for Integer value equality.
  • Use Integer.compare() or .compareTo() for ordering and sorting.
  • Never rely on == for Integer objects. The Integer cache makes it appear correct for small values but fail for larger ones.
  • Always handle null explicitly when working with Integer. Use Objects.equals() for null-safe equality and Comparator.nullsFirst/nullsLast for null-safe ordering.
  • When null is impossible, unbox to int early to simplify the rest of the code.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.