Потоки Java для начинающих: введение в использование потоков в Java

Потоки Java для начинающих: введение в использование потоков в Java

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





До выпуска Java 8 использование термина «поток» в Java автоматически ассоциировалось с вводом-выводом. Однако в Java 8 появился поток, который можно назвать набором вычислительных шагов, объединенных в цепочку так, что обычно называют «потоковым конвейером».





Эта статья познакомит вас с потоками Java 8 и продемонстрирует, как они могут быть полезны в ваших проектах.





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

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

Как работают потоки

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



Чтобы преобразовать коллекцию в исходный поток, вам нужно добавить транслировать() функция к источнику. Это поместит источник в конвейер потока, где несколько различных промежуточных операций (например, фильтр() а также Сортировать() ) может работать на нем.

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





Жизнь без потоков

Java 8 была выпущена в 2014 году, но до этого разработчикам Java все еще требовалось извлекать специализированные данные из набора общих данных.

как изменить домашний экран на Android TV Box

Допустим, у вас есть список случайных символов, которые комбинируются со случайными числами для образования уникальных строковых значений, но вам нужны только значения, начинающиеся с символа C, и вы хотите расположить результат в порядке возрастания. Вот как вы извлекаете эти данные без потоков.





Связанный: Что нужно знать об использовании строк в Java

Пример фильтрации и сортировки значений без потоков


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
//declare and initialize the array list
List randomValues = Arrays.asList(
'E11', 'D12', 'A13', 'F14', 'C15', 'A16',
'B11', 'B12', 'C13', 'B14', 'B15', 'B16',
'F12', 'E13', 'C11', 'C14', 'A15', 'C16',
'F11', 'C12', 'D13', 'E14', 'D15', 'D16'
);
//declare the array list will store needed values
List requiredValues = new ArrayList();
//extracting the required values and storing them in reqquiredValues
randomValues.forEach(value -> {
if(value.startsWith('C')) {
requiredValues.add(value);
}
});
//sort the requiredValues in ascending order
requiredValues.sort((String value1, String value2) -> value1.compareTo(value2));
//print each value to the console
requiredValues.forEach((String value) -> System.out.println(value));
}
}

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

Связанный: Как создавать и выполнять операции с массивами в Java

Приведенный выше код дает в консоли следующий вывод:


C11
C12
C13
C14
C15
C16

Жизнь с потоками

В программировании эффективность означает получение того же результата при значительно меньшем количестве кода. Именно это и делает для программиста потоковый конвейер. Итак, в следующий раз, когда кто-то спросит: почему важно использовать потоки в вашем проекте? Проще говоря: потоки поддерживают эффективное программирование.

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

Фильтрация и сортировка значений на примере потока


import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
//declare and initialize the array list
List randomValues = Arrays.asList(
'E11', 'D12', 'A13', 'F14', 'C15', 'A16',
'B11', 'B12', 'C13', 'B14', 'B15', 'B16',
'F12', 'E13', 'C11', 'C14', 'A15', 'C16',
'F11', 'C12', 'D13', 'E14', 'D15', 'D16'
);
//retrieves only values that start with C, sort them, and print them to the console.
randomValues.stream().filter(value->value.startsWith('C')).sorted().forEach(System.out::println);
}
}

Приведенный выше код демонстрирует, насколько мощным является потоковый интерфейс. Он принимает список случайных значений массива и преобразует его в поток с помощью транслировать() функция. Затем поток сокращается до списка массивов, который содержит требуемые значения (это все значения, начинающиеся с C ), с помощью фильтр() функция.

Как вы можете видеть в приведенном выше примере, C значения располагаются в списке массивов случайным образом. Если бы вы должны были напечатать поток на этом этапе конвейера, значение C15 будет напечатан первым. Следовательно Сортировать() Функция вводится в конвейер потока, чтобы переставить новый массив в порядке возрастания.

Последняя функция в конвейере потока - это для каждого() функция. Это функция терминала, которая используется для остановки конвейера потока и дает следующие результаты в консоли:


C11
C12
C13
C14
C15
C16

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

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

Потоковый конвейер всегда начинается с одного источника и транслировать() функция, и всегда заканчивается одной операцией терминала (хотя есть несколько разных операций на выбор). Но между этими двумя разделами находится список из шести промежуточных операций, которые вы можете использовать.

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

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

Пример выполнения операций фильтрации и сортировки для значений в нижнем регистре


import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
//declare and initialize the array list
List randomValues = Arrays.asList(
'E11', 'D12', 'A13', 'F14', 'C15', 'A16',
'B11', 'B12', 'c13', 'B14', 'B15', 'B16',
'F12', 'E13', 'C11', 'C14', 'A15', 'c16',
'F11', 'C12', 'D13', 'E14', 'D15', 'D16'
);
//retrieves only values that start with C, sort them, and print them to the console.
randomValues.stream().filter(value->value.startsWith('C')).sorted().forEach(System.out::println);
}
}

Приведенный выше код выдаст в консоли следующие значения:


C11
C12
C14
C15

Единственная проблема с выходными данными выше заключается в том, что они не точно представляют все C значения в нашем списке массивов. Хороший способ исправить эту небольшую ошибку - ввести в конвейер потока еще одну промежуточную операцию; эта операция известна как карта() функция.

Использование примера функции карты


import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
//declare and initialize the array list
List randomValues = Arrays.asList(
'E11', 'D12', 'A13', 'F14', 'C15', 'A16',
'B11', 'B12', 'c13', 'B14', 'B15', 'B16',
'F12', 'E13', 'C11', 'C14', 'A15', 'c16',
'F11', 'C12', 'D13', 'E14', 'D15', 'D16'
);
//transforms all lower case characters to upper case,
//retrieves only values that start with C, sort them, and print them to the console.
randomValues.stream().map(String::toUpperCase).filter(value->value.startsWith('C')).sorted().forEach(System.out::println);
}
}

В карта() функция переводит объект из одного состояния в другое; в нашем примере выше он преобразует все символы нижнего регистра в списке массивов в символы верхнего регистра.

Размещение карта() функция непосредственно перед фильтр() функция извлекает все значения, которые начинаются с C из списка массивов.

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


C11
C12
C13
C14
C15
C16

Остальные три промежуточные операции, которые вы можете использовать в своих приложениях, включают:

  • заглянуть ()
  • предел ()
  • пропускать()

Потоки Java 8 упрощают создание эффективного кода

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

как включить уведомления на YouTube

Если вас интересует строка кода, заключенная в наш фильтр() функция; это известно как «лямбда-выражение». Лямбда-выражения - еще одна функция, представленная в Java 8, и в ней есть много самородков, которые могут оказаться полезными.

Делиться Делиться Твитнуть Эл. адрес Краткое введение в лямбды Java 8

Если вы программист на Java и хотите узнать больше о лямбда-выражениях Java 8, в этой статье мы более подробно рассмотрим синтаксис и использование лямбда-выражений.

Читать далее
Похожие темы
  • Программирование
  • Джава
  • Учебники по кодированию
Об авторе Кадейша Кин(Опубликовано 21 статья)

Кадейша Кин (Kadeisha Kean) - разработчик программного обеспечения полного стека и автор статей по техническим / технологическим вопросам. У нее отличная способность упрощать некоторые из самых сложных технологических концепций; производить материал, понятный любому новичку в технологии. Она увлечена писательством, разработкой интересного программного обеспечения и путешествиями по миру (с помощью документальных фильмов).

Ещё от Kadeisha Kean

Подписывайтесь на нашу новостную рассылку

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

Нажмите здесь, чтобы подписаться