Коллекции в Java — одна из наиболее часто используемых концепций в нашем повседневном программировании.

Учитывая этот сценарий ниже:

Есть класс Сотрудник.

Наша постановка проблемы заключается в том, что у нас есть список объектов Employee, и мы будем фильтровать сотрудников, возраст которых больше 25 лет, а затем сохранять их зарплаты в другом списке.

Мы будем использовать список с итератором

До Java 8, когда мы используем для работы с коллекциями, нам обычно приходится выполнять следующие шаги:

Пожалуйста, обратитесь к комментариям, приведенным внутри /**/ фрагмента кода выше.

  1. Сначала нам нужно создать объект итератора.
  2. Затем проверьте, может ли итератор перемещаться (проверьте, не является ли коллекция нулевой) и извлеките конкретный элемент.
  3. Как только мы получим true на шаге 2, мы можем использовать next(), чтобы продолжить и извлечь элемент.
  4. После получения значения на шаге 3 мы можем выполнить только ту операцию, которую нам нужно выполнить со значением из коллекции.

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

Это мы также можем назвать императивным стилем программирования, т.е. мы говорим, как выполнить ту или иную операцию.

  • Для одной коллекции это минимальные шаги, которые мы должны выполнить.

Если мы работаем с несколькими коллекциями, эти шаги необходимо выполнить и для всех этих коллекций. Это приведет к повторению логики.

  • Когда мы работаем с коллекцией с помощью итератора, мы можем выполнять операции с элементами только последовательно.

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

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

  • Когда мы выполняем операции над коллекциями, мы используем Iterator, hasNext(), next(), затем используем некоторые циклические операции if или while, после чего, при необходимости, фильтруем значения или выполняем требуемые операции над значениями и сохраняем желаемое результатом является локальная переменная.

В логике программирования мы можем заключить приведенный выше набор операций с этими наблюдениями ниже.

  • Параллельные операции не поддерживаются, что приведет к проблемам с производительностью при обработке больших коллекций.
  • Код относительно менее лаконичен, или для достижения определенного результата необходимо написать несколько логических операций.
  • Может потребоваться объявить несколько локальных переменных, чтобы сохранить некоторое значение для следующей операции или сохранить результат, который действительно требуется от коллекции.
  • Читабельность относительно меньше

[Это зависит от программиста. Вам необходимо понять основы функционального программирования и концепции Java 8 и начать ее использовать. Если вы сочтете это полезным, вы продолжите его использовать, при условии, что это лучший вариант для любого конкретного сценария. Ну, есть исключения]

Потоки в Java позволили нам преодолеть эти ограничения с помощью лучшего решения.

Что такое потоки?

Потоки — это последовательность элементов или элементов данных, созданных из источника данных, которые позволяют нам выполнять операции обработки данных как последовательно, так и параллельно

  • Потоки позволяют нам выполнять вычисления или обрабатывать данные, присутствующие в потоке, путем фильтрации данных или сортировки элементов данных, сопоставления элементов данных или суммирования значений.
  • Для создания или генерации потока мы можем сделать это только из источника данных, такого как коллекции или массивы или ресурсы ввода-вывода.
  • Мы можем выполнять операции над потоком посредством последовательных или параллельных операций.
  • Различные операции, которые мы можем использовать с потоками, представлены в интерфейсе Stream.

java.util.stream.Stream

Есть 2 категории операций:

Промежуточные операции:

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

Терминальные операции:

Производит конечный результат из потоков

  • Внутренняя итерация поддерживается в потоке. Нам не нужно объявлять шаги для итерации при использовании потоков.

Что такое потоковый конвейер?

Когда промежуточные операции работают с потоком, они берут элементы из входного потока и создают выходной поток.

Это одна цепочка операций с двумя потоками.

Когда две или более таких цепочек соединены, они образуют потоковый конвейер. Потоки соединяются через эту цепочку операций и образуют потоковый конвейер.

Пример использования потока

Есть класс Сотрудник. Наша постановка проблемы заключается в том, что у нас есть список объектов Employee, и мы будем фильтровать сотрудников, возраст которых больше 25 лет, а затем сохранять их зарплаты в другом списке.

Последовательность элементов данных. . . тогда это не коллекция?

  • Потоки используются для операций обработки данных, тогда как коллекции предназначены для хранения элементов, что позволяет нам находить определенные элементы на основе позиции индекса.
  • Как только мы создадим итератор из коллекций, мы сможем использовать его повторно, тогда как для потока, когда мы вызываем метод потока для коллекции, мы можем пройти через него только один раз. Будет неверным сказать, что мы не можем повторно использовать поток. Что мы можем сделать, так это всякий раз, когда нам требуется обработать поток, мы можем вызвать метод потока для коллекции и использовать его.
  • В потоках мы сообщаем, что нам нужно, и кодируем соответственно. Это своего рода объявление деталей, которые необходимо сделать, и об этом позаботятся без прямого кодирования логики того, как это сделать.

В основном поток поддерживает декларативное программирование, тогда как в коллекциях мы напрямую кодируем, как получить нужные нам детали, включая объявление итератора, вызовы hasNext() и next(), а затем выполнение необходимых операций, если это необходимо, и затем получение желаемого результата. В основном коллекция поддерживает императивное программирование.

  • Потоки, особенно параллельные потоки, полезны, когда набор данных большой. Для сравнения, временной интервал для работы с потоками больше, чем для работы с циклами.

Сравнение производительности цикла, последовательного потока и параллельного потока

Общее количество элементов = 10 миллионов

Общее количество элементов = 100 миллионов

Спасибо, что прочитали!!

Если вы найдете это интересным и информативным. Пожалуйста, нажмите на аплодисменты 👏 в этом посте и поделитесь им для большего охвата.

Поделитесь своим опытом, идеями и отзывами, комментируя этот пост.

Не стесняйтесь подписываться на меня на Subhodip Basu, чтобы не пропустить новые интересные статьи.

Не стесняйтесь связаться со мной на LinkedIn