Stream

Stream

I.Alfer

Такой метод перебора, не всегда удобен.

List<String> list = new ArrayList<>();
list.add("one");
list.add("two");
list.add("one");
list.add("two");
list.add("one");
list.add("two");

for(String s : list){
    System.out.println(s);
}

Т.к. нам нужно всё время писать

for(String s : list){
    System.out.println(s);
}

Но по сути у нас выполняется вот этот код

Iterator<String> iterator = list.iterator();
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}


Сейчас у всех коллекций есть stream() который возвращает Stream

Stream<String> stream = list.stream();


Stream - превращает все значения которые есть в коллекции в поток значений

list.stream().forEach(x -> System.out.println(x));


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

Все методы stream принимают ФИ.

Есть Lazy и Eager операторы

list.stream().filter(x -> {
    System.out.println(x);
    return "two".equals(x);
});//lazy

Ничего не будет выведено

Примеро eager метода является метод caunt()

list.stream().filter(x -> {
    System.out.println(x);
    return "two".equals(x);
}).count();//eager

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


Stream есть возможность преобразовать обратно в коллекцию через collect()

List<String> list1 = list.stream()
        .filter(x -> "one".equals(x))
        .collect(Collectors.toList());


Метод map позволяет преобразовывать один тип объектов в другие

list.stream().map(x -> x.toCharArray());


flatMap

Принцип похож как и у map. Превращает наши значения в одну последовательность.

Т.е. если у нас был вот такой массив массивов

{ {1,2}, {3,4}, {5,6} }

то flatMap сделает из него вот такой

{1,2,3,4,5,6}

В нашем случае будет удобно после flatMap вызвать еще раз stream для преобразования его в один поток и потом уже совершать над ним действия

Stream.of(Arrays.asList("1", "2"), Arrays.asList("3", "4"))
        .flatMap(x -> x.stream())
        .forEach(x-> System.out.println(x));


min max

Возвращают минимальное/максимальное значение из объектов, но в них нужно передать Comparator

int value = Stream.of(123,52, 22)
        .min(Comparator.comparing(x -> x))
        .get();


reduce

позволяет пройти по массиву и произвести какие-то действия(допустим сложить)

Что-то типо

int accomulator = 0;
for(int element: new int[]{1, 2, 3}){
    accomulator += element;
}

В reduce есть начальное значение которое мы задаём и лямбда которая встраивает логику

int count = Stream.of(12, 41, 32)
        .reduce(0,(acc, element) -> acc + element);


sorted

Есть 2 имплементации - одна по умолчанию вторая, если нужно сортировать свои объекты принимает Comparator

list.stream().sorted().collect(Collectors.toList());


limit

задаёт лимит

Stream.of(123,52, 22).limit(2).collect(Collectors.toList());


distinct

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

Stream.of(22,52, 22).distinct().collect(Collectors.toList());


skip

Если есть необходимость пропустить элементы и начать с n-ого

Stream.of(123,52, 22).skip(2).collect(Collectors.toList());

Report Page