Что выведет этот код?

Код выведет следующее:

Короткий ответ

Что ответить на собеседовании

Код выведет следующее:

Подробный разбор

Ответ с пояснениями

Условие

Что выведет этот код?

public class StreamApi {

@Data
@AllArgsConstructor
public static class Client {
    private String name;
    private String city;
}

public static Map<String, Long> countBy(Stream<Client> clients, Function<Client, String> clientParameterGetter) {
    return clients.collect(Collectors.groupingBy(clientParameterGetter, TreeMap::new, Collectors.counting()));
}

public static void main(String[] args) {

    List<Client> clients = List.of(
        new Client("Иванов", "Москва"),
        new Client("Михайлов", "Санкт-Петербург"),
        new Client("Сергеев", "Санкт-Петербург"),
        new Client("Иванов", null),
        new Client("Сергеев", null)
    );

    long count = clients.stream()
        .peek(client -> {
            if (client.getCity() == null) {
                client.setCity("Москва");
            }
        })
        .count();

    Predicate<Client> clientPredicate = client -> client.getCity() != null;
    Stream<Client> validClients = clients.stream().filter(clientPredicate);

    System.out.println(count);
    System.out.println(countBy(validClients, Client::getName));
    System.out.println(countBy(validClients, Client::getCity));
}

}

Ответ

Код выведет следующее:

  1. Переменная count — это количество элементов в списке clients. В списке 5 клиентов, значит count будет 5.
  2. Метод countBy группирует клиентов по заданному параметру и считает количество клиентов в каждой группе.
  3. Важно, что перед подсчетом count в стриме вызывается peek, который заменяет null в поле city на "Москва". Это изменяет объекты в исходном списке, так как объекты изменяемые.
  4. Далее создается стрим validClients, который фильтрует клиентов с непустым city. После peek у всех клиентов city не null (у двух, где было null, теперь "Москва"), значит фильтр пропустит всех 5 клиентов.
  5. Первый вызов countBy(validClients, Client::getName) сгруппирует клиентов по имени:
  • "Иванов" — 2 клиента
  • "Михайлов" — 1 клиент
  • "Сергеев" — 2 клиента
  1. Второй вызов countBy(validClients, Client::getCity) сгруппирует по городу:
  • "Москва" — 3 клиента (Иванов с null заменен на "Москва", Сергеев с null заменен на "Москва", и Иванов изначально с "Москва")
  • "Санкт-Петербург" — 2 клиента

Итоговый вывод:

5
{Иванов=2, Михайлов=1, Сергеев=2}
{Москва=3, Санкт-Петербург=2}

Ключевой момент — peek изменяет объекты в исходном списке, что влияет на последующую фильтрацию и группировку.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее