Java объединение двух stream

Слияние потоков в Java

В этой быстрой статье мы объясним различные способы слияния потоков Java , что не очень интуитивно понятно.

2. Использование простой Java

Класс JDK 8 Stream имеет несколько полезных статических служебных методов. Давайте подробнее рассмотрим метод concat() .

2.1. Слияние двух потоков

Самый простой способ объединить 2 Stream — использовать статический метод Stream.concat() :

 @Test   public void whenMergingStreams_thenResultStreamContainsElementsFromBoth()    StreamInteger> stream1 = Stream.of(1, 3, 5);   StreamInteger> stream2 = Stream.of(2, 4, 6);    StreamInteger> resultingStream = Stream.concat(stream1, stream2);    assertEquals(   Arrays.asList(1, 3, 5, 2, 4, 6),   resultingStream.collect(Collectors.toList()));   > 

2.2. Объединение нескольких потоков

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

Следующий фрагмент кода показывает это в действии:

 @Test   public void given3Streams_whenMerged_thenResultStreamContainsAllElements()    StreamInteger> stream1 = Stream.of(1, 3, 5);   StreamInteger> stream2 = Stream.of(2, 4, 6);   StreamInteger> stream3 = Stream.of(18, 15, 36);    StreamInteger> resultingStream = Stream.concat(   Stream.concat(stream1, stream2), stream3);    assertEquals(   Arrays.asList(1, 3, 5, 2, 4, 6, 18, 15, 36),   resultingStream.collect(Collectors.toList()));   > 

Как мы видим, этот подход становится невозможным для большего количества потоков. Конечно, мы можем создать промежуточные переменные или вспомогательные методы, чтобы сделать его более читабельным, но вот вариант получше:

 @Test   public void given4Streams_whenMerged_thenResultStreamContainsAllElements()    StreamInteger> stream1 = Stream.of(1, 3, 5);   StreamInteger> stream2 = Stream.of(2, 4, 6);   StreamInteger> stream3 = Stream.of(18, 15, 36);   StreamInteger> stream4 = Stream.of(99);    StreamInteger> resultingStream = Stream.of(   stream1, stream2, stream3, stream4)   .flatMap(i -> i);    assertEquals(   Arrays.asList(1, 3, 5, 2, 4, 6, 18, 15, 36, 99),   resultingStream.collect(Collectors.toList()));   > 

Здесь происходит следующее:

  • Сначала мы создаем новый поток , содержащий 4 потока , в результате чего получается Stream> .
  • Затем мы flatMap() преобразуем это в Stream , используя функцию идентификации.

3. Использование StreamEx

StreamEx — это библиотека Java с открытым исходным кодом, которая расширяет возможности Java 8 Streams. Он использует класс StreamEx в качестве расширения интерфейса JDK Stream .

3.1. Объединение потоков _

Библиотека StreamEx позволяет нам объединять потоки, используя метод экземпляра append() :

 @Test   public void given4Streams_whenMerged_thenResultStreamContainsAllElements()    StreamInteger> stream1 = Stream.of(1, 3, 5);   StreamInteger> stream2 = Stream.of(2, 4, 6);   StreamInteger> stream3 = Stream.of(18, 15, 36);   StreamInteger> stream4 = Stream.of(99);    StreamInteger> resultingStream = StreamEx.of(stream1)   .append(stream2)   .append(stream3)   .append(stream4);    assertEquals(   Arrays.asList(1, 3, 5, 2, 4, 6, 18, 15, 36, 99),   resultingStream.collect(Collectors.toList()));   > 

Поскольку это метод экземпляра, мы можем легко связать его и добавить несколько потоков.

Обратите внимание, что мы также можем создать список из потока с помощью toList() , если мы приведем результирующую переменную Stream к типу StreamEx .

3.2. Слияние потоков с помощью prepend()

StreamEx также содержит метод prepend() , который добавляет элементы один перед другим :

 @Test   public void given3Streams_whenPrepended_thenResultStreamContainsAllElements()    StreamString> stream1 = Stream.of("foo", "bar");   StreamString> openingBracketStream = Stream.of("[");   StreamString> closingBracketStream = Stream.of("]");    StreamString> resultingStream = StreamEx.of(stream1)   .append(closingBracketStream)   .prepend(openingBracketStream);    assertEquals(   Arrays.asList("[", "foo", "bar", "]"),   resultingStream.collect(Collectors.toList()));   > 

4. Использование Jooλ

jOOλ — это библиотека, совместимая с JDK 8, которая предоставляет полезные расширения для JDK. Самая важная абстракция потока здесь называется Seq . Обратите внимание, что это последовательный и упорядоченный поток, поэтому вызов parallel() не будет иметь никакого эффекта.

4.1. Объединение потоков

Как и в библиотеке StreamEx, в jOOλ есть метод append() :

 @Test   public void given2Streams_whenMerged_thenResultStreamContainsAllElements()    StreamInteger> seq1 = Stream.of(1, 3, 5);   StreamInteger> seq2 = Stream.of(2, 4, 6);    StreamInteger> resultingSeq = Seq.ofType(seq1, Integer.class)   .append(seq2);    assertEquals(   Arrays.asList(1, 3, 5, 2, 4, 6),   resultingSeq.collect(Collectors.toList()));   > 

Также есть удобный метод toList() , если мы приводим результирующую переменную Seq к типу jOOλ Seq .

4.2. Слияние потоков с prepend()

Как и ожидалось, поскольку существует метод append() , в jOOλ есть и метод prepend() :

 @Test   public void given3Streams_whenPrepending_thenResultStreamContainsAllElements()    StreamString> seq = Stream.of("foo", "bar");   StreamString> openingBracketSeq = Stream.of("[");   StreamString> closingBracketSeq = Stream.of("]");    StreamString> resultingStream = Seq.ofType(seq, String.class)   .append(closingBracketSeq)   .prepend(openingBracketSeq);    Assert.assertEquals(   Arrays.asList("[", "foo", "bar", "]"),   resultingStream.collect(Collectors.toList()));   > 

5. Вывод

Мы видели, что слияние потоков с помощью JDK 8 относительно простое. Когда нам нужно выполнить много слияний, может быть полезно использовать библиотеку StreamEx или jOOλ для удобочитаемости.

Вы можете найти исходный код на GitHub .

Источник

Java объединение двух stream

Ряд методов Stream API возвращают подпотоки или объединенные потоки на основе уже имеющихся потоков. Рассмотрим эти методы.

takeWhile

Метод takeWhile() выбирает из потока элементы, пока они соответствуют условию. Если попадается элемент, который не соответствует условию, то метод завершает свою работу. Выбранные элементы возвращаются в виде потока.

import java.util.stream.Stream; public class Program < public static void main(String[] args) < Streamnumbers = Stream.of(-3, -2, -1, 0, 1, 2, 3, -4, -5); numbers.takeWhile(n -> n < 0) .forEach(n ->System.out.println(n)); > >

В данном случае программа выбирает из потока числа, пока они меньше нуля. Консольный вывод программы:

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

Чтобы в данном случае охватить все элементы, которые меньше нуля, поток следует предварительно отсортировать:

Stream numbers = Stream.of(-3, -2, -1, 0, 1, 2, 3, -4, -5); numbers.sorted().takeWhile(n -> n < 0) .forEach(n ->System.out.println(n));

Консольный вывод программы:

dropWhile

Метод dropWhile() выполняет обратную задачу — он пропускает элементы потока, которые соответствуют условию до тех пор, пока не встретит элемент, который НЕ соответствует условию:

Stream numbers = Stream.of(-3, -2, -1, 0, 1, 2, 3, -4, -5); numbers.sorted().dropWhile(n -> n < 0) .forEach(n ->System.out.println(n));

Консольный вывод программы:

concat

Статический метод concat() объединяет элементы двух потоков, возвращая объединенный поток:

import java.util.stream.Stream; public class Program < public static void main(String[] args) < Streampeople1 = Stream.of("Tom", "Bob", "Sam"); Stream people2 = Stream.of("Alice", "Kate", "Sam"); Stream.concat(people1, people2).forEach(n -> System.out.println(n)); > >
Tom Bob Sam Alice Kate Sam

distinct

Метод distinct() возвращает только ункальные элементы в виде потока:

Stream people = Stream.of("Tom", "Bob", "Sam", "Tom", "Alice", "Kate", "Sam"); people.distinct().forEach(p -> System.out.println(p));

Источник

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

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

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

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

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

Stream s1 = Arrays.stream(new String[]); Stream s2 = Arrays.stream(new String[]);

Их можно объединить с помощью метода 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) < Streams1 = Arrays.stream(new String[]); Stream s2 = Arrays.stream(new String[]); 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(. ) > >

Заключение

В данной статье мы рассмотрели, как объединить элементы двух стримов с помощью метода Stream.concat. Точно так же можно объединять стримы IntStream, LongStream и DoubleStream.

Источник

Stream.concat() in Java

Stream.concat() method creates a concatenated stream in which the elements are all the elements of the first stream followed by all the elements of the second stream. The resulting stream is ordered if both of the input streams are ordered, and parallel if either of the input streams is parallel.

static T> StreamT> concat(Stream? extends T> stream1, Stream? extends T> stream2) Where, T is the type of stream elements, stream1 represents the first stream, stream2 represents the second stream and the function returns the concatenation of the two input streams

The calls to Stream.concat(stream1, stream2) can be think of as forming a binary tree. The concatenation of all the input streams is at the root. The individual input streams are at the leaves. Below given are some examples of trees upto four input streams a, b, c and d.

For two streams a and b, the tree looks like :

For three streams a, b and c, the tree looks like :

For four streams a, b, c and d, the tree looks like :

Each additional input stream adds one layer of depth to the tree and one layer of indirection to reach all the other streams.

Note : The elements returned by Stream.concat() method is ordered. For example, the following two lines returns the same result:

Stream.concat(Stream.concat(stream1, stream2), stream3); Stream.concat(stream1, Stream.concat(stream2, stream3));

But the result for the following two are different.

Stream.concat(Stream.concat(stream1, stream2), stream3); Stream.concat(Stream.concat(stream2, stream1), stream3);

Below are some examples to understand the implementation of the function in a better way.
Example 1 :

Источник

Читайте также:  Theme name style css
Оцените статью