How can I properly compare two Integers in Java?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Comparing integers in Java is easy when you are working with primitive int values, but wrapper objects change the rules. The main distinction is that == compares numeric value for primitives and object identity for Integer, which is why wrapper comparisons sometimes look correct and then fail unexpectedly.
Compare primitive values with operators
For primitive int, normal comparison operators are the right tool.
There is no reference identity involved here. Java compares the actual numeric values directly.
If your variables are already primitive, stay in the primitive world. That is usually the simplest and safest path.
Compare Integer objects by value
For wrapper objects, use equals when you want equality and compareTo or Integer.compare when you want ordering.
These methods compare numeric content, not whether the two variables refer to the same object.
Integer.compare is especially useful in comparators and sorting code because it works cleanly with primitive int values too.
Why == is dangerous with Integer
When you write x == y for two Integer objects, Java checks whether both references point to the same object instance.
Autoboxing makes this more confusing because Java caches some small Integer objects. That means == may appear to work for some values:
This is exactly why == is the wrong comparison for wrapper value equality. The result depends on object identity and caching behavior, not just the number.
Handle nulls deliberately
Integer exists partly because it can be null, unlike primitive int. That means null safety matters when comparing values that came from a database row, request parameter, or optional field.
Objects.equals is a strong default when wrapper values may be absent. It avoids NullPointerException and still performs value comparison when both values are non-null.
For ordering with possible nulls, decide the business rule first. Should null sort first, last, or be rejected entirely. That policy matters more than the method call.
Choose comparison style by intent
A simple rule set works well in practice:
- use operators for primitive
int - use
equalsorObjects.equalsfor wrapper equality - use
compareToorInteger.comparefor ordering
If null is not meaningful, unboxing to int can simplify the code:
Just be careful. Unboxing a null Integer throws NullPointerException, so only do this when null has already been ruled out.
Common Pitfalls
The most common mistake is using == with Integer and assuming it compares numeric value. It only compares references.
Another common issue is being fooled by the small-integer cache, where == appears to work for one value and fails for another.
Developers also forget that calling equals on a null reference throws. If either side may be null, use Objects.equals or validate earlier.
Finally, avoid mixing primitives and wrappers carelessly. Autoboxing and unboxing are convenient, but they can hide whether the code is doing value comparison, reference comparison, or null-sensitive conversion.
Summary
- Compare primitive
intvalues with normal operators. - Compare
Integervalues withequals,Objects.equals,compareTo, orInteger.compare. - Do not use
==for wrapper value equality. - Remember that integer caching makes incorrect
==code look correct sometimes. - Unbox only when null is impossible or already handled.

