Перейти к основному содержимому

Отладка потоков Java 8 с помощью IntelliJ

· 4 мин. чтения

1. Введение

С момента появления Java 8 многие люди начали использовать (новую) функциональность потоков. Конечно, бывают моменты, когда наши потоковые операции не работают должным образом.

В IntelliJ помимо обычных параметров отладки есть специальная функция потоковой отладки. В этом коротком руководстве мы рассмотрим эту замечательную функцию.

2. Диалоговое окно трассировки потока

Начнем с того, что покажем, как открыть диалоговое окно Stream Trace. На панели инструментов окна отладки есть значок Trace Current Stream Chain, который активируется только тогда, когда наше приложение приостанавливается в точке останова внутри вызова потокового API :

./c3c48209f8fe0eb92730cbe4fc2b9867.png

При нажатии на значок откроется диалоговое окно Stream Trace.

Диалог имеет два режима. Мы рассмотрим Flat Mode в первом примере. А во втором примере мы покажем режим по умолчанию, то есть режим разделения.

3. Примеры

Теперь, когда мы представили функцию потоковой отладки в IntelliJ, пришло время поработать с некоторыми примерами кода.

3.1. Базовый пример с отсортированным потоком

Давайте начнем с простого фрагмента кода, чтобы привыкнуть к диалогу Stream Trace:

int[] listOutputSorted = IntStream.of(-3, 10, -4, 1, 3)
.sorted()
.toArray();

Изначально. у нас есть поток неупорядоченного int . Затем мы сортируем этот поток и преобразуем его в массив.

Когда мы просматриваем трассировку потока в плоском режиме , она показывает нам обзор выполняемых шагов:

./a9fd90a6fe5ead0a9801532cda2cec85.png

В крайнем левом углу мы видим начальный поток. Он содержит int в том порядке, в котором мы их написали.

Первый набор стрелок показывает нам новое расположение всех элементов после сортировки. И в крайнем правом углу мы видим наш вывод. Все элементы появляются там в отсортированном порядке.

Теперь, когда мы рассмотрели основы, пришло время для более сложного примера.

3.2. Пример использования flatMap и фильтра

В следующем примере используется flatMap . Stream.flatMap помогает нам, например, преобразовать список необязательных элементов в обычный список. В следующем примере мы начинаем со списка необязательных клиентов . Затем мы сопоставляем его со списком Customer и применяем некоторую фильтрацию:

List<Optional<Customer>> customers = Arrays.asList(
Optional.of(new Customer("John P.", 15)),
Optional.of(new Customer("Sarah M.", 78)),
Optional.empty(),
Optional.of(new Customer("Mary T.", 20)),
Optional.empty(),
Optional.of(new Customer("Florian G.", 89)),
Optional.empty()
);

long numberOf65PlusCustomers = customers
.stream()
.flatMap(c -> c
.map(Stream::of)
.orElseGet(Stream::empty))
.mapToInt(Customer::getAge)
.filter(c -> c > 65)
.count();

Далее, давайте просмотрим трассировку потока в режиме разделения, который дает нам лучший обзор этого потока.

Слева мы видим входной поток. Далее мы видим плоское сопоставление потока необязательных клиентов с потоком фактически существующих клиентов:

./5d3afd99c4456558c30826a3c71ae27c.png

После этого мы сопоставляем наш поток клиентов с их возрастом:

./ce4102e88da01361338daba066e014d7.png

Следующий шаг фильтрует наш поток возрастов до потока возрастов старше 65 лет:

./1a8b570958384a76b799e89c345aa833.png

Наконец, мы подсчитываем количество элементов в нашем потоке возрастов:

./82a23a33193c30e2842066c828550f46.png

4. Предостережения

В приведенных выше примерах мы видели некоторые возможности, предлагаемые диалоговым окном Stream Trace. Тем не менее, есть некоторые важные детали, о которых следует знать. Большинство из них являются прямым следствием того, как работают потоки.

Во- первых, потоки всегда требуют выполнения терминальных операций . Это ничем не отличается при использовании диалогового окна Stream Trace. Также мы должны знать об операциях, которые не потребляют весь поток — например, anyMatch . В этом случае будут отображаться не все элементы, а только обработанные.

Во- вторых, имейте в виду, что поток будет потребляться . Если мы объявим поток отдельно от его операций, мы можем столкнуться с ошибкой «Поток уже обработан или закрыт» . Мы можем предотвратить эту ошибку, объединив объявление потока с его использованием.

5. Вывод

В этом кратком руководстве мы увидели, как использовать диалоговое окно IntelliJ Stream Trace.

Сначала мы рассмотрели простой случай, демонстрирующий сортировку и сбор. Затем мы рассмотрели более сложный сценарий, включающий плоское сопоставление, сопоставление, фильтрацию и подсчет.

Наконец, мы рассмотрели некоторые предостережения, с которыми мы можем столкнуться при использовании функции потоковой отладки.

Как всегда, полный исходный код статьи доступен на GitHub .