Check if a value exists in ArrayList
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
To check whether an ArrayList contains a value, the normal answer in Java is contains(). That method is simple and readable, but it is only as correct as the equals() implementation used for comparison. For small lists and occasional checks, contains() is exactly the right tool. For repeated lookups or custom objects, you need to understand what it is really doing.
Use contains() For Normal Cases
ArrayList.contains(value) returns true if any element in the list is equal to the given value.
Under the hood, contains() scans the list from beginning to end and compares elements using equals(). That means the time complexity is linear, or O(n).
For many applications, that is completely fine. If the list has a few dozen elements, clarity matters more than micro-optimization.
What Happens With Custom Objects
The important detail is that contains() depends on equals(). If you store custom objects and do not define equality properly, a logically identical value may not be found.
Because equals() and hashCode() are defined, the lookup behaves as expected. Without that override, the comparison would use object identity and return false.
When A Manual Search Is Better
Sometimes you do not want exact object equality. You may want to search by one field or perform a case-insensitive match. In that case, a loop or a stream can be clearer than contains().
That expresses the real comparison rule directly instead of pretending the list contains the exact same object or string form.
A traditional loop is equally valid and sometimes easier to debug.
When ArrayList Is The Wrong Data Structure
If you need to check membership many times, an ArrayList may not be the right collection. A HashSet provides average O(1) membership checks.
This matters when the collection is large or membership checks happen frequently in performance-sensitive code.
Use ArrayList when order and indexed access matter. Use Set when fast existence checks matter more.
Common Pitfalls
The biggest mistake is forgetting that contains() uses equals(). For custom classes, default object identity is usually not what you want.
Another common issue is expecting contains() to be fast on very large lists. It scans linearly, so repeated lookups can become expensive.
Developers also sometimes use contains() when the real rule is more specific, such as case-insensitive matching or matching one property of an object. In those cases, use a loop or stream().anyMatch(...).
Finally, do not switch to a HashSet blindly. Sets improve membership lookup, but they do not preserve the same indexed semantics as ArrayList.
Summary
- Use
contains()for simple membership checks on anArrayList. - '
contains()relies onequals(), so custom object equality must be defined correctly.' - Use
stream().anyMatch(...)or a loop for custom comparison rules. - Membership checks on
ArrayListareO(n). - For repeated lookups, consider
HashSetinstead. - Choose the collection based on both lookup needs and the semantics your code actually requires.

