Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Collection helper methods

For typical collection tasks you do not need to write loops: find the maximum, reverse a list, count repeats. Ready-made static methods are gathered in the Collections class — with an "s" at the end, unlike the Collection interface.

Maximum, minimum and counting

Collections.max() and Collections.min() find the largest and smallest element, and Collections.frequency() counts how many times a value occurs:

void main() {
    List<Integer> grades = List.of(4, 5, 3, 5, 4, 5);
    IO.println(Collections.max(grades));
    IO.println(Collections.min(grades));
    IO.println(Collections.frequency(grades, 5));
}

Output:

5
3
3

max() and min() also accept a comparator as the second argument — to find the longest word, for example.

Rearranging

reverse() reverses a list, swap() swaps two elements, and shuffle() mixes them in random order. All of them change the list itself:

void main() {
    List<String> steps = new ArrayList<>(List.of("one", "two", "three"));
    Collections.reverse(steps);
    IO.println(steps);
    Collections.swap(steps, 0, 2);
    IO.println(steps);
}

Output:

[three, two, one]
[one, two, three]

The result of shuffle() is different on every run — that is how you shuffle a deck of cards or quiz questions.

Filling

Collections.nCopies() creates a list of identical elements, and Collections.addAll() adds several values to a collection at once:

void main() {
    List<String> seats = new ArrayList<>(Collections.nCopies(4, "free"));
    seats.set(1, "taken");
    IO.println(seats);
 
    Set<String> colors = new TreeSet<>();
    Collections.addAll(colors, "blue", "white", "blue");
    IO.println(colors);
}

Output:

[free, taken, free, free]
[blue, white]

A copy or a view

List.copyOf() makes an unmodifiable copy: later changes to the original do not affect it. Collections.unmodifiableList() returns a view — a read-only "window" onto the same list. You cannot make changes through the window, but changes to the original are visible in it:

void main() {
    List<String> team = new ArrayList<>(List.of("Anna"));
    List<String> copy = List.copyOf(team);
    List<String> view = Collections.unmodifiableList(team);
 
    team.add("Oleg");
    IO.println(copy);
    IO.println(view);
}

Output:

[Anna]
[Anna, Oleg]

A view suits a getter that must hand out up-to-date data without the right to change it.

Empty collections

A method that has nothing to return should return an empty collection, not null — then the calling code needs no extra checks. For this there is List.of() without arguments, as well as Map.of() and Set.of():

List<String> findByTag(String tag) {
    if (tag.equals("java")) {
        return List.of("Lesson 1", "Lesson 2");
    }
    return List.of();
}
 
void main() {
    IO.println(findByTag("java").size());
    IO.println(findByTag("php").size());
}

Output:

2
0

Common mistake

Arrays.asList() turns an array into a list, but that list has a fixed size: you can replace elements, but you cannot add them:

void main() {
    String[] array = { "a", "b" };
    List<String> list = Arrays.asList(array);
    list.set(0, "z");
    IO.println(list);
    list.add("c");
}

Output:

[z, b]
Exception in thread "main" java.lang.UnsupportedOperationException

If the list is going to grow, create a full one: new ArrayList<>(Arrays.asList(array)).

Thanks for reading!

Donate to the site — we work hard for you.