ArrayList
Java
Comparison
Coding Techniques
Algorithms

Compare every item to every other item in ArrayList

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

If you need to compare every item in an ArrayList with every other item, the usual solution is a nested loop. The important detail is where the inner loop starts, because that determines whether you compare each pair once, compare items with themselves, or compare the same pair twice.

Most of the time, you want unique unordered pairs. In that case, start the inner loop at i + 1. That avoids self-comparisons and duplicate work.

Compare Each Pair Exactly Once

Here is the standard pattern:

java
1import java.util.ArrayList;
2import java.util.List;
3
4public class PairComparisonDemo {
5    public static void main(String[] args) {
6        List<String> names = new ArrayList<>(List.of("Ana", "Bo", "Cy", "Di"));
7
8        for (int i = 0; i < names.size(); i++) {
9            for (int j = i + 1; j < names.size(); j++) {
10                String left = names.get(i);
11                String right = names.get(j);
12
13                System.out.println(left + " vs " + right);
14            }
15        }
16    }
17}

Output:

text
1Ana vs Bo
2Ana vs Cy
3Ana vs Di
4Bo vs Cy
5Bo vs Di
6Cy vs Di

That is the cleanest version when order does not matter. You see each pair once and never compare an item with itself.

Why j = i + 1 Matters

Suppose the inner loop started at 0 instead:

java
1for (int i = 0; i < list.size(); i++) {
2    for (int j = 0; j < list.size(); j++) {
3        // compare list.get(i) and list.get(j)
4    }
5}

Now you get:

  • self-comparisons such as A versus A
  • duplicate comparisons such as A versus B and later B versus A

That may be correct if direction matters, but it is wasteful for symmetric comparisons like equality checks or distance calculations.

A Reusable Generic Method

If you do this often, wrap the pattern in a helper method:

java
1import java.util.List;
2import java.util.function.BiConsumer;
3
4public class PairUtils {
5    public static <T> void forEachUniquePair(List<T> items, BiConsumer<T, T> action) {
6        for (int i = 0; i < items.size(); i++) {
7            for (int j = i + 1; j < items.size(); j++) {
8                action.accept(items.get(i), items.get(j));
9            }
10        }
11    }
12}

Usage:

java
1List<Integer> values = List.of(4, 7, 9, 12);
2
3PairUtils.forEachUniquePair(values, (a, b) -> {
4    System.out.println("Difference: " + Math.abs(a - b));
5});

This makes the comparison logic reusable without repeating nested loops everywhere in your codebase.

Complexity and When It Becomes Expensive

Comparing every item to every other item takes O(n²) time. That cost grows quickly:

  • 10 items gives 45 unique pairs
  • 100 items gives 4,950 unique pairs
  • 10,000 items gives almost 50 million unique pairs

So while the nested-loop solution is correct, it may be too slow for large lists. If your real goal is something narrower such as finding duplicates or nearest values, there may be better algorithms using hashing, sorting, or indexing.

When You Actually Need All Ordered Pairs

Sometimes order matters. For example, if you are comparing "source" to "target" and A -> B is different from B -> A, then starting from 0 may be appropriate. In that case, explicitly skip self-comparisons:

java
1for (int i = 0; i < items.size(); i++) {
2    for (int j = 0; j < items.size(); j++) {
3        if (i == j) {
4            continue;
5        }
6        System.out.println(items.get(i) + " -> " + items.get(j));
7    }
8}

The right loop structure depends on what "compare" means in your problem.

Common Pitfalls

  • Starting the inner loop at 0 when you only need unique unordered pairs.
  • Forgetting that the algorithm is O(n²) and then using it on very large lists.
  • Modifying the ArrayList while iterating through it, which can lead to logic bugs or concurrent modification problems elsewhere.
  • Using equals when the real comparison rule is custom and should be written explicitly.
  • Assuming ArrayList is the issue. The pairwise pattern itself is what makes the algorithm expensive.

Summary

  • Use nested loops to compare every item in an ArrayList with every other item.
  • Start the inner loop at i + 1 when you want each unique pair exactly once.
  • Start at 0 only if ordered pairs matter, and skip i == j if needed.
  • Expect quadratic runtime for full pairwise comparison.
  • If performance matters, step back and ask whether you truly need all pairs or only a more specific result.

Course illustration
Course illustration

All Rights Reserved.