Посчитать пары носков по цвету — и не промахнуться мимо остатка

Задача простая по условию и неприятная по краевым случаям. Дан список цветов носков, нужно вывести число пар каждого цвета. Непарные носки просто не учитываются в ответе.

Первый шаг — посчитать количество каждого цвета, это тривиально через Map:

public static Map countPairs(List socks) { Map counts = new HashMap<>(); for (String color : socks) { counts.merge(color, 1, Integer::sum); } Map pairs = new LinkedHashMap<>(); for (Map.Entry entry : counts.entrySet()) { pairs.put(entry.getKey(), entry.getValue() / 2); } return pairs; }

Два прохода вместо одного — осознанный выбор, а не лишний код. Деление на 2 по ходу первого же подсчёта потребовало бы отдельно обрабатывать случай, когда текущий цвет ещё не встречался. Разделение на «посчитать» и «поделить» проще читать и проще тестировать по отдельности.

На входе Red — 4, Yellow — 3, Black — 3 ответ — Black: 1, Red: 2, Yellow: 1. Непарные носки (по одному от Yellow и Black) просто не попадают в вывод, и это нормальное поведение, а не баг.

Следом почти всегда спрашивают: как изменится решение, если нужно отдельно вывести количество непарных носков по каждому цвету. Ответ — остаток от деления на 2 (count % 2) даёт именно это число, и считается той же формулой без дополнительного прохода по коллекции.

Задача на базовый уровень, но на ней хорошо видно, умеет ли кандидат разделять подсчёт и агрегацию вместо того, чтобы смешивать всё в одном цикле с условиями.

senior·base — что спрашивают на самом деле


В этом посте были ссылки, но мы их удалили по правилам Сетки