CodeGym /Courses /JAVA 25 SELF /Filtering collection elements

Filtering collection elements

JAVA 25 SELF
Level 28 , Lesson 0
Available

1. Introduction

In programming, we constantly encounter situations where you need to select only the required elements from a large data set — that is filtering. Want to keep only even numbers, find strings containing the word "Java", or select users older than 18 — all of these are filtering tasks.

In Java, such operations appear at every step, so it is important to be confident with the different ways to perform them and to understand their specifics.

2. Filtering with a loop

Let’s start with the most basic approach — a plain for loop. This approach is called imperative because you explicitly specify what to do and how. It reads well and is easy to understand.

Example: keep only even numbers

import java.util.*;

public class FilterExample {
    public static void main(String[] args) {
        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        List<Integer> evenNumbers = new ArrayList<>(); // Create a new list for the result

        for (Integer n : numbers) {
            if (n % 2 == 0) { // Check the condition: even number
                evenNumbers.add(n);
            }
        }

        System.out.println("Even numbers: " + evenNumbers);
    }
}

Output:

Even numbers: [2, 4, 6, 8, 10]

It’s important to remember: the original collection (numbers) does not change. We build a new result list.

Example: filter strings by substring

List<String> words = Arrays.asList("java", "python", "javascript", "kotlin", "c++");
List<String> javaWords = new ArrayList<>();

for (String word : words) {
    if (word.contains("java")) {
        javaWords.add(word);
    }
}
System.out.println(javaWords); // [java, javascript]

Same principle: iterate over the list of strings and check for the substring using the contains method.

3. Removing elements from a collection: why isn’t it that simple?

What’s the catch?

Sometimes you want to remove all unnecessary elements from the original collection. But if you try to do this while iterating with a for-each loop, you will get a ConcurrentModificationException.

List<Integer> numbers = new ArrayList<>(Arrays.asList(1, -2, 3, -4, 5));

for (Integer n : numbers) {
    if (n < 0) {
        numbers.remove(n); // DANGEROUS! ConcurrentModificationException!
    }
}

Output:

Exception in thread "main" java.util.ConcurrentModificationException

Collections don’t like being modified during this kind of traversal — the iteration breaks.

How to remove elements from a collection correctly?

Method 1: use Iterator.remove()

List<Integer> numbers = new ArrayList<>(Arrays.asList(1, -2, 3, -4, 5));

Iterator<Integer> it = numbers.iterator();
while (it.hasNext()) {
    Integer n = it.next();
    if (n < 0) {
        it.remove(); // Remove safely!
    }
}
System.out.println(numbers); // [1, 3, 5]

Here we create an iterator with iterator(), walk the collection using hasNext() and next(), and remove unwanted elements by calling it.remove().

Method 2: build a new list with only the needed elements

List<Integer> numbers = Arrays.asList(1, -2, 3, -4, 5);
List<Integer> positive = new ArrayList<>();

for (Integer n : numbers) {
    if (n >= 0) {
        positive.add(n);
    }
}
System.out.println(positive); // [1, 3, 5]

We don’t touch the original collection and collect a new list. The approach is safe, readable, and easy to extend as conditions get more complex.

Method 3: use removeIf (Java 8+)

List<Integer> numbers = new ArrayList<>(Arrays.asList(1, -2, 3, -4, 5));
numbers.removeIf(n -> n < 0);
System.out.println(numbers); // [1, 3, 5]

In a single line you pass a condition: “delete everything less than zero.” The collection takes care of the internal details of safe modification.

Bottom line: do not use for-each for removing elements. Choose between Iterator.remove(), creating a new list, or the concise removeIf.

4. When to use which approach for filtering?

The imperative approach using a plain loop is convenient when you need not only to select elements but also to immediately do something with them (for example, print or transform). It is simple and transparent.

If it’s specifically about removing from the original collection, avoid removing in for-each. Use Iterator.remove() for step-by-step control or the modern removeIf() — the shortest and most expressive option.

Example: there’s a list of words; delete all words shorter than four characters:

List<String> words = new ArrayList<>(Arrays.asList("Java", "is", "fun", "awesome", "code"));
words.removeIf(word -> word.length() < 4);
System.out.println(words); // [Java, awesome, code]

The removeIf method takes a predicate — a filtering rule — and removes everything that matches it.

5. Common mistakes when filtering collections

Mistake #1: trying to remove elements from a collection inside a for-each loop.
Such code will lead to a ConcurrentModificationException:

for (Integer n : numbers) {
    if (n < 0) {
        numbers.remove(n); // BOOM! ConcurrentModificationException
    }
}

Correct options: use Iterator.remove() or removeIf.

Mistake #2: an incorrectly formulated filter condition.
You need to remove only negative numbers:

List<Integer> numbers = new ArrayList<>(Arrays.asList(-3, -1, 0, 2, 4));
numbers.removeIf(n -> n < 0);
System.out.println(numbers); // [0, 2, 4]

But if by mistake you write “non‑positive” and use <=, zero will also disappear:

numbers.removeIf(n -> n <= 0); // Result: [2, 4] — zero removed by mistake

Be precise with conditions: a single incorrect comparison completely changes the result.

1
Task
JAVA 25 SELF, level 28, lesson 0
Locked
Cleaning agent dossiers of "negative" information 🕵️‍♀️
Cleaning agent dossiers of "negative" information 🕵️‍♀️
1
Task
JAVA 25 SELF, level 28, lesson 0
Locked
Organizing animal names for the new encyclopedia 🦒
Organizing animal names for the new encyclopedia 🦒
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION