Использование Stream в Java 8 позволяет писать код вдвое быстрее.

Транслировать

Одной из основных новых функций в Java 8 является введение функции Stream. Включите java.util.streamклассы для работы с последовательностями элементов. Среди них наиболее важным классом является Stream<T>. Давайте посмотрим, как создать поток, используя существующий источник данных.

Создать поток

Потоки можно создавать из разных источников данных (например, коллекций, массивов) с помощью методов stream()и :of()

String[] arr = new String[]{
    
    "万", "猫", "学", "社"};
Stream<String> stream = Arrays.stream(arr);
stream = Stream.of("万", "猫", "学", "社");

CollectionИнтерфейс имеет новый метод stream()по умолчанию , позволяющий использовать любую коллекцию в качестве источника данных для создания Stream<T>:

List<String> list = new ArrayList();
list.add("万");
list.add("猫");
list.add("学");
list.add("社");
Stream<String> stream = list.stream();

Использование Stream в многопоточности

Stream также упрощает многопоточные операции, предоставляя parallelStream()метод , который выполняет операции над элементами потока параллельно.

Следующий код может запускать doWork()метод :

List<String> list = new ArrayList();
list.add("万");
list.add("猫");
list.add("学");
list.add("社");
list.parallelStream().forEach(element -> doWork(element));

Далее мы рассмотрим некоторые основные операции Stream.

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

Над потоками можно выполнять множество полезных операций. Они делятся на промежуточные операции (возврат Stream<T>) и терминальные операции (возврат результата четко определенного типа), промежуточные операции допускают цепочку.

Я должен отметить, что операции над потоком не меняют источник данных.

Вот простой пример:

List<String> list = new ArrayList();
list.add("万");
list.add("猫");
list.add("学");
list.add("社");
long count = list.stream().distinct().count();

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

итерация

Потоки помогают нам заменить циклы for, for-each и while. Это позволяет нам сосредоточиться на логике операции вместо того, чтобы перебирать последовательность элементов.

Например следующий код:

for (String string : list) {
    
    
    if (string.contains("猫")) {
    
    
        return true;
    }
}

Этот код может быть реализован только одной строкой кода Stream:

boolean isExist = list.stream().anyMatch(element -> element.contains("猫"));

фильтр

filter()Метод позволяет выбрать поток элементов, удовлетворяющих предикатному условию.

Например следующий код:

List<String> list = new ArrayList();
list.add("万");
list.add("猫");
list.add("学");
list.add("社");
Stream<String> stream = list.stream().filter(element -> element.contains("猫"));

В приведенном выше примере создается List<String>a Stream<String>, все элементы в потоке, содержащие символ «кошка», находятся, и создается новый поток, содержащий только отфильтрованные элементы.

карта

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

Например следующий код:

List<String> list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
Stream<Integer> stream = list.stream().map(str -> Integer.valueOf(str));

В приведенном выше примере Stream<String>преобразуется Stream<Integer>.

Если у вас есть поток, в котором каждый элемент содержит свою последовательность элементов, и вы хотите создать поток из этих внутренних элементов, вам следует использовать flatMap()метод .

Например следующий код:

public class Writer {
    
    
	private String name;
	private List<String> books;
}
List<Writer> writers = new ArrayList<>();
writers.add(new Writer());
Stream<String> stream = writers.stream().flatMap(writer -> writer.getBooks().stream());

В приведенном выше примере у нас есть список элементов Writerтипа . WriterКласс содержит поле List<String>типа books. Используя метод flatMap(), каждый элемент booksв будет извлечен и добавлен в новый поток результатов. После этого исходный поток будет потерян.

соответствовать

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

  • anyMatch(): возвращает true, пока выполняется одно условие
  • allMatch(): все должно быть выполнено, чтобы вернуть true
  • noneMatch(): Вернуть true, только если все не удовлетворены

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

Например следующий код:

List<String> list = new ArrayList();
list.add("万");
list.add("猫");
list.add("学");
list.add("社");
list.stream().anyMatch(element -> element.contains("万")); // true
list.stream().allMatch(element -> element.contains("万")); // false
list.stream().noneMatch(element -> element.contains("万")); // false

Для пустого Stream метод allMatch() вернет true независимо от заданного предиката:

Stream.empty().anyMatch(Objects::nonNull); // false

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

Точно так же метод anyMatch() всегда возвращает false для пустого потока:

Stream.empty().anyMatch(Objects::nonNull); // false

Опять же, это разумно, так как мы не можем найти элемент, удовлетворяющий этому условию.

сливаться

Я могу использовать reduce()метод для объединения ряда элементов в некоторое значение в соответствии с заданной функцией. Этот метод принимает два параметра: первый — начальное значение, а второй — функция-аккумулятор.

Например следующий код:

List<Integer> integers = Arrays.asList(1, 2, 3);
Integer reduced = integers.stream().reduce(4, (a, b) -> a + b);

В приведенном выше примере есть один List<Integer>, и мы складываем элементы и добавляем начальное целое число (в данном случае 4). Итак, результат выполнения следующего кода равен 10 (4+1+2+3).

собирать

В типе Stream также можно собирать через collect()метод . Эта операция очень удобна, может преобразовать поток в Collectionили Map, а также может представить поток в виде одной строки. Collectors— это служебный класс, предоставляющий решения почти для всех типичных операций с коллекциями. Для некоторых менее распространенных задач можно создавать пользовательские коллекторы.

В приведенном ниже коде используется операция терминала collect()для Stream<String>преобразования в List<String>.

List<String> resultList 
  = list.stream().map(element -> element.toUpperCase()).collect(Collectors.toList());

наконец

Расширенные примеры Stream очень богаты. Цель этой статьи — дать нам возможность быстро понять использование функции Stream и вдохновить нас на дальнейшее изучение и углубленное изучение.

Stream — это очень мощный и полезный API в Java 8, который предоставляет разработчикам более простой способ обработки данных. Я надеюсь, что благодаря введению и примерам в этой статье мы сможем быстро приступить к работе с Stream и продолжить углубленное изучение и изучение.

Je suppose que tu aimes

Origine blog.csdn.net/heihaozi/article/details/130476602
conseillé
Classement