обзор

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

одной из этих функций является Stream. Stream предоставляет нам больший контроль над нашими данными внутри приложения с помощью API.

поэтому давайте посмотрим, как работают Stream API, и поймем, что мы можем сделать с помощью Stream.

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

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

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

Поток имеет множество массовых операций, таких как foreach(), filter(), map(), flatMap() и другие операции. и пусть метод сбора преобразует ваши данные во многие типы структур данных, такие как List , Set , LinkedList , используя

Какие бывают типы потоков?

у нас есть два типа потоков, у всех типов есть свои задания.

  • Терминальная промежуточная операция: производит результат или побочный эффект, например, count() или forEach(Consumer)

Terminal Operation : Stream --> Result

forEach(), toArray(), reduce(), collect(), min(), max(), count(), anyMatch(), allMatch(), noneMatch(), findFirst(), findAny() все эти операции являются терминальными.

  • Нетерминальная/промежуточная операция: трансформирует поток в другой поток, например filter(Predicate).

Non-Terminal Operation : Stream --> Stream.

map() , filter() , flatMap() ,distinct(), sorted(), limit(), skip() все эти операции являются нетерминальными операциями.

Поток формат

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

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

Например:

  • преобразовать коллекцию: ourcollection.stream()
  • прямой путь : Stream.of(1,12,3,5,56)

Потоковая операция

Итак, как я уже сказал, у нас есть много операций в потоке, и в этой статье я объясню общие терминальные и нетерминальные промежуточные операции.

У меня есть следующий код, и я объясню его, поэтому прочитайте его и продолжите, когда будете готовы.

List<Integer> numbers = Arrays.asList(-1, 3, 5, 7, 9, 2, 4, 6, 8);

List<Integer> filterNumberList = numbers
       .stream()
       .filter(number -> number >= 10)
       .collect(Collectors.toList());

List<String> programmingLanguage = Arrays
       .asList("JAVA", "PHP", "PYTHON", "GO");

List<String> programmingLanguageAfterMap = programmingLanguage
       .stream()
       .map(lang -> lang.lowerCase())
       .forEach(lang ->{

         System.out.println("programmingLanguageAfterMap : ".concat(lang));
       });

List<Integer> sortedListNumber = numbers
       .stream()
       .sorted()
       .collect(Collectors.toList());

Predicate<Integer> predicateToGetOddNumbers = integer -> integer % 2 != 0;
List<Integer> oddNumbersUsingPredicate = numbers
       .stream()
       .filter(predicateToGetOddNumbers)
       .collect(Collectors.toList());


List<Integer> distinctOddNumbersUsingPredicate = numbers
       .stream()
       .filter(predicateToGetOddNumbers)
       .distinct()
       .collect(Collectors.toList());

▶️ Операция сбора

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

▶️ Работа с картой

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

▶️ Отсортированная операция

Я использовал sorted функцию для сортировки целых чисел. По умолчанию он использует базовое целочисленное и строковое сравнение. Но мы можем изменить реализацию этого метода. В коде для примера я определил sortedListNumber числа сортировки в списке.

▶️ Операция фильтра

Это очень полезная функция, которую можно использовать для выбора нужных нам элементов. Метод filter принимает в качестве параметра Predicate. Что это такое? Предикат — это функциональный интерфейс в Java. (Я думаю, у вас есть базовые представления о лямбда-выражениях!) Просто у него есть только один метод, который возвращает логическое значение. Итак, мы можем передать лямбда-выражение, которое возвращает логическое значение, в качестве параметра для метода filter. Я определил переменную predicateToGetOddNumbers как предикат, чтобы возвращать true, если элемент нечетный.

▶️ Для каждой операции

Этот метод также полезен для циклического перебора коллекции. Просто он принимает Consumer в качестве аргумента. Его можно реализовать отдельно и включить в цикл forEach. В противном случае мы можем реализовать логику в виде лямбда-выражения в цикле forEach.

Stream Loop и for Loop

Поток очень приятный, и его стоит сравнить с кодом пуэра java, и в этом разделе я хочу сравнить между forEach в потоке и for loop,и нам нужно отфильтровать данные с помощью filter по streamи простой if statment.

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

public List<people> oldestThanAge(List<Pepole> people, Integer age) {

return people
     .filter( p -> p.age() < 19)
     .collect(toList());
vs

List<People> filtered = new ArrayList<>();
 for(People p : people) {
     if(p.age() < 19) {
         filtered.add(p);
     }
 }

return filtered;
}

Потоки Роли

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

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