Да, прошло 8 лет с момента выпуска Java SE 8 с Stream API, функциональными интерфейсами, Time API и многими другими важными функциями, но Lambdas и Streams — это то, что познакомило Java-разработчиков с функциональным программированием.

Давайте разберемся с потоками и их использованием!

Некоторые основы:

  1. Функциональный интерфейс: интерфейс с одним абстрактным методом.
  2. Лямбда-выражение: реализует один абстрактный метод функционального интерфейса.
  3. Потоки. Лямбда-выражения передаются в качестве аргументов потоковым операциям для чтения/изменения данных.

1. Что такое поток?

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

2. Что НЕ является потоком?

  1. Stream — это не структура данных, такая как Collections, Stream просто знает, где искать элементы, когда это требуется в конвейере.
  2. Коллекции ориентированы на эффективную организацию данных.
  3. Потоки сосредоточены на эффективной организации вычислений.

3. Как создать поток?

Стрим состоит из трех частей

  1. Источник элементов
  2. Ноль или более промежуточных операций
  3. Одна терминальная операция, запускающая поток.

1. Источник

Источником элементов могут быть коллекции, массивы, функции-генераторы и каналы ввода/вывода. Вы можете создать последовательный или параллельный поток в источнике, используя различные методы. Ниже перечислены некоторые из них.

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

Вы будете знать, когда возникнет потребность в параллельных потоках, так что не усложняйте до тех пор!

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

  1. Поток может иметь ноль или более промежуточных операций.
  2. Это может быть операция с отслеживанием состояния или без него. Операции с состоянием, такие как sorted(), зависят от всех элементов в потоке, тогда как операции без сохранения состояния, такие как filter() и map(), могут выполняться. независимо от элемента потока. Операции без сохранения состояния можно оптимизировать внутренне, выполняя параллельные выполнения.

3. Работа терминала:

  1. Эта операция запускает потоковый конвейер для выполнения операций.
  2. Операция может быть короткой, как limit(), findFirst(), которая уменьшает длину потока, или без короткого замыкания, как collect(), forEach().

5. Как использовать поток?

6. Как Stream работает внутри?

Создание потока:

  1. Разделитель — это еще один итератор, представленный в Java SE 8, который поддерживает параллельное программирование путем разделения и повторения элементов потока.
  2. Поток также захватывает различные флаги состояния, которые описывают характеристики элементов, если источником является TreeSet, то захватывается флаг SORTED.

Такие флаги, как SIZED, DISTINCT, SORTED и ORDER, используются для фиксации состояния элементов потока.

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

  1. При каждой операции флаги состояния используются для оптимизации или модифицируются, если состояние потока изменяется или добавляется.
  2. Эти флаги используются для оптимизации на каждом этапе, например, если поток уже СОРТИРОВАЛСЯ на предыдущем этапе, то больше не будет сортироваться.

Операция терминала:

  1. Он определяет поток в зависимости от операций без сохранения состояния, таких как filter(),map() и flatMap(), и операций с состоянием, таких как sorted(), limit() и Different().
  2. Если конвейер выполняется последовательно или параллельно, но состоит из всех операций без сохранения состояния, его можно вычислить за один проход. В противном случае конвейер делится на секции на границах операций с отслеживанием состояния и вычисляется за несколько проходов.
  3. Операции с терминалом являются либо короткими, как limit(), findFirst(), либо без коротких замыканий, такими как reduce(), collect(). Если операция терминала не является короткозамкнутой, данные можно обрабатывать в пакетном режиме с помощью метода forEachRemaining() в разделителе. Если это короткое замыкание, он должен обрабатываться по одному элементу за раз с помощью tryAdvance().

7. Каковы преимущества потока?

  1. Краткий и чистый код.
  2. Вы можете легко читать и понимать код, содержащий ряд сложных операций.
  3. Для параллельной обработки не требуется переписывать код. После идентификации просто используйте параллельный поток в источнике.
  4. Представление потокового конвейера в виде последовательности операций позволяет использовать несколько полезных стратегий выполнения за счет использования флагов состояния.
  5. Мы можем возвращать потоки из методов API, где ранее вы могли вернуть массив или коллекцию. Это поможет клиентскому коду собирать потоки в соответствии с требованиями.

8. Что такое функциональное программирование?

Давайте быстро поймем это. Функциональное программирование — это подмножество декларативного стиля программирования.

Декларативный стиль или обычный императивный стиль?

В декларативном стиле вы определяете что делать, а не как это делать. Проверьте простой пример ниже.

Императивный стиль: мы определяем переменную total sum, повторяем 10 чисел и добавляем их к общей сумме. По сути, мы определяем, как добавить 10 чисел.

Декларативный стиль. Укажите сумму 10 чисел. Просто провозгласил Это.

Вот и все, спасибо!

Следите за дополнительным контентом! 🤝

Ознакомьтесь с другим моим рассказом о системном дизайне



Повышение уровня кодирования

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

  • 👏 Хлопайте за историю и подписывайтесь на автора 👉
  • 📰 Смотрите больше контента в публикации Level Up Coding
  • 🔔 Подписывайтесь на нас: Twitter | ЛинкедИн | "Новостная рассылка"

🚀👉 Присоединяйтесь к коллективу талантов Level Up и найдите прекрасную работу