Стримы в Java

  • Стримы в Java

    Нахождение первого элемента в стриме

    Нахождение первого элемента в стриме[Нахождение первого элемента в стриме]

    Если у вас есть стрим каких-то элементов и вам нужно найти первый элемент, это легко сделать с помощью метода findFirst.

    Поиск первого элемента в стриме

    Для нахождения первого элемента в стриме воспользуемся методом findFirst. Он вернёт объект типа Optional, на котором мы вызовем метод orElse(null) для того, чтобы извлечь хранящийся внутри его элемент (или значение null, если элемент отсутствует):

    public static <T> T getFirstElementInStream(Stream<T> stream) {
        return stream
                .findFirst()
                .orElse(null);
    }

    Проверим это на тестовых данных:

    []

    Исходный код

    import java.util.Arrays; import java.util.List; import java.util.stream.Stream; public class GetFirstElementInStream { public static void main(String[] args) { List<String> ids = Arrays.asList("111", "222", "333", "444", "555", "666", "777"); System.out.println("Все элементы: " + ids); String firstElement = getFirstElementInStream(ids.stream()); System.out.println("Первый элемент: " + firstElement); } public static <T> T getFirstElementInStream(Stream<T> stream) { return stream .findFirst() .orElse(null); } } Подробнее ...

  • Стримы в Java

    Нахождение последнего элемента в стриме

    Нахождение последнего элемента в стриме[Нахождение последнего элемента в стриме]

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

    Поиск последнего элемента

    Для нахождения последнего элемента можно воспользоваться оператором reduce, который принимает на вход два элемента стрима и возвращает один:

    public static <T> T getLastElement(Stream<T> stream) {
        return stream
                .reduce((e1, e2) -> e2)
                .orElse(null);
    }

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

    []

    Исходный код

    import java.util.Arrays; import java.util.List; import java.util.stream.Stream; public class GetLastElementInStream { public static void main(String[] args) { List<String> ids = Arrays.asList("111", "222", "333", "444", "555", "666", "777"); System.out.println("Все элементы: " + ids); String lastElement = getLastElement(ids.stream()); System.out.println("Последний элемент: " + lastElement); } public static <T> T getLastElement(Stream<T> stream) { return stream .reduce((e1, e2) -> e2) .orElse(null); } } Подробнее ...

  • Стримы в Java

    Конвертация Iterator в Stream

    Конвертация Iterator в Stream[Конвертация Iterator в Stream]

    Иногда требуется преобразовать объект типа Iterator в Stream. Для этих целей в Java есть вспомогательный метод StreamSupport.stream:

    public static <T> Stream<T> stream(Spliterator<T> spliterator, boolean parallel)

    Первый аргумент это объект типа Spliterator. Мы его получим из Iterator/Iterable. Второй аргумент включает параллельную обработку Stream.

    Преобразование Iterator в Stream

    public static <T> Stream<T> asStream(Iterator<T> sourceIterator) {
        Iterable<T> iterable = () -> sourceIterator;
        return StreamSupport.stream(iterable.spliterator(), false);
    }

    Проверка:

    List<String> list = Arrays.asList("Alice", "Bob", "Carl"); Iterator<String> iterator = list.iterator(); asStream(iterator) .map(name -> "Hello, " + name + "!") .forEach(System.out::println); Подробнее ...

  • Стримы в Java

    Как объединить два стрима

    Как объединить два стрима[Как объединить два стрима]

    Иногда возникает необходимость объединить два различных стрима. В это статье мы расскажем вам, как это сделать несколькими способами.

    Объединение с помощью Stream.concat

    Это наиболее популярный и удобный способ объединения двух стримов.

    Допустим, у вас есть два стрима:

    Stream<String> s1 = Arrays.stream(new String[]{"A", "B", "C"});
    Stream<String> s2 = Arrays.stream(new String[]{"D", "E", "F"});

    Их можно объединить с помощью метода Stream.concat:

    Stream.concat(s1, s2).forEach(System.out::println);

    Stream.concat объединит элементы из двух стримов в один стрим.

    Объединение стримов IntStream, LongStream, DoubleStream

    Если вам требуется объединить элементы из стримов типа IntStream, LongStream или DoubleStream, можно воспользоваться тем же методом concat:

    IntStream i1 = IntStream.range(1, 5);
    IntStream i2 = IntStream.range(5, 11);
    IntStream.concat(i1, i2).forEach(System.out::println);

    Аналогичным образом объединяются элементы в стримах LongStream и DoubleStream.

    Исходный код

    import java.util.Arrays; import java.util.stream.IntStream; import java.util.stream.Stream; public class MergeTwoStreamsExample { public static void main(String[] args) { Stream<String> s1 = Arrays.stream(new String[]{"A", "B", "C"}); Stream<String> s2 = Arrays.stream(new String[]{"D", "E", "F"}); Stream.concat(s1, s2).forEach(System.out::println); IntStream i1 = IntStream.range(1, 5); IntStream i2 = IntStream.range(5, 11); IntStream.concat(i1, i2).forEach(System.out::println); // LongStream.concat(...) // DoubleStream.concat(...) } } Подробнее ...

  • Стримы в Java

    Как суммировать BigDecimal с помощью Stream

    Как суммировать BigDecimal с помощью Stream[Как суммировать BigDecimal с помощью Stream]

    Начиная с Java 8, мы можем суммировать BigDecimal с помощью метода Stream.reduce().

    Как суммировать BigDecimal

    Сначала создадим список, состоящий из элементов BigDecimal:

    List<BigDecimal> numbers  = new ArrayList<>();
    numbers.add(BigDecimal.valueOf(10.1));
    numbers.add(BigDecimal.valueOf(89.9));
    numbers.add(BigDecimal.valueOf(50.5));

    Затем получим из списка стрим его элементов и воспользуемся методом Stream.reduce для того, чтобы суммировать все элементы стрима:

    BigDecimal total = numbers.stream().reduce(BigDecimal.ZERO, BigDecimal::add);
    System.out.println(total); // 150.5

    Метод Stream.reduce принимает два аргумента – начальное значение и функцию-аккумулятор, которая складывает два числа (предыдущее значение аккумулятора и следующий элемент в стриме).

    Исходный код

    import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; public class SumBigDecimalStream { public static void main(String[] args) { List<BigDecimal> numbers = new ArrayList<>(); numbers.add(BigDecimal.valueOf(10.1)); numbers.add(BigDecimal.valueOf(89.9)); numbers.add(BigDecimal.valueOf(50.5)); BigDecimal total = numbers.stream().reduce(BigDecimal.ZERO, BigDecimal::add); System.out.println(total); // 150.5 } } Подробнее ...

  • Стримы в Java

    Поиск дубликатов в Stream

    Поиск дубликатов в Stream[Поиск дубликатов в Stream]

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

    Варианты решения задачи

    Есть несколько вариантов найти дубликаты в стриме:

    • С помощью дополнительного объекта Set
    • С помощью метода Collectors.groupingBy
    • С помощью утилитного метода Collections.frequency

    Поиск дубликатов с помощью Set

    Сначала инициализируем вспомогательный Set, с помощью которого мы будем проверять, является ли следующий элемент стрима дубликатом:

    Set<T> elements = new HashSet<>();

    Затем в стриме будем добавлять каждый элемент из коллекции в Set с помощью метода add(). Этот метод возвращает true в том случае, если этот элемент ранее не был добавлен в Set:

    collection.stream()
        .filter(e -> !elements.add(e))
        .collect(Collectors.toSet());

    Таким образом, мы отфильтруем те элементы, которые встречаются в коллекции более одного раза.

    Таким образом, полный код нашего метода может выглядеть следующим образом:

    public static <T> Set<T> findDuplicates(Collection<T> collection) {
        Set<T> elements = new HashSet<>();
        return collection.stream()
                .filter(e -> !elements.add(e))
                .collect(Collectors.toSet());
    }

    Проверим его с помощью тестовых данных:

    public static void main(String[] args) { List<String> names = Arrays.asList("Alice", "Bob", "Alice", "Carl", "Don", "Eugene", "Carl"); System.out.println("Все элементы: " + names); Set<String> duplicates = findDuplicates(names); System.out.println("Дубликаты: " + duplicates); } Подробнее ...