В JDK 8 с лямбдой b93 в b93 был класс java.util.stream.Streams.zip, который можно использовать для архивирования потоков (это показано в учебном пособии Dhananjay Nene, посвященном изучению Java8-лямбд. Часть 1 ). Эта функция:
Создает ленивый и последовательный объединенный поток, элементы которого являются результатом объединения элементов двух потоков.
Однако в b98 это исчезло. Infact Streams
класс даже не доступен в java.util.stream в b98 .
Была ли эта функциональность перемещена, и если да, то как мне сжать потоки сжато, используя b98?
Приложение, которое я имею в виду, находится в Java-реализации Shen , где я заменил функциональность zip в
static <T> boolean every(Collection<T> c1, Collection<T> c2, BiPredicate<T, T> pred)
static <T> T find(Collection<T> c1, Collection<T> c2, BiPredicate<T, T> pred)
функции с довольно подробным кодом (который не использует функциональность из b98).
Ответы:
Мне это тоже нужно было, поэтому я просто взял исходный код из b93 и поместил его в класс «util». Мне пришлось немного изменить его для работы с текущим API.
Для справки вот рабочий код (принимайте его на свой страх и риск ...):
источник
SIZED
если какой-либо потокSIZED
, а не оба?SIZED
для этой реализации, чтобы работать. Это на самом деле зависит от того, как вы определяете молнию. Например, сможете ли вы сжать два потока разного размера? Как будет выглядеть результирующий поток? Я считаю, что именно поэтому эта функция была фактически исключена из API. Есть много способов сделать это, и пользователь должен решить, какое поведение должно быть «правильным». Вы бы отбросили элементы из более длинного потока или добавили более короткий список? Если да, то с какими значениями?Spliterator<A>
).zip - одна из функций, предоставляемых библиотекой protonpack .
источник
Если у вас есть Guava в вашем проекте, вы можете использовать метод Streams.zip (был добавлен в Guava 21):
источник
Архивирование два потока с использованием JDK8 с лямбда ( сутью ).
источник
import java.util.function.*;
иimport java.util.stream.*;
в верхней части вашего файла.() -> iterator
и здесь сноваiterable.spliterator()
. Почему бы не реализовать непосредственно,Spliterator
а неIterator
? Проверьте @Doradus ответ stackoverflow.com/a/46230233/1140754Поскольку я не могу представить себе какое-либо использование архивирования на коллекциях, кроме индексированных (списков), и я большой поклонник простоты, это было бы моим решением:
источник
mapToObject
должно бытьmapToObj
.RandomAccess
(например, в связанных списках), это будет очень медленноМетоды упомянутого вами класса были перенесены в сам
Stream
интерфейс в пользу методов по умолчанию. Но похоже, чтоzip
метод был удален. Возможно, потому что не ясно, как должно быть поведение по умолчанию для потоков разных размеров. Но реализация желаемого поведения проста:источник
predicate
вы не передали фильтр с состоянием ? Это нарушает контракт метода и особенно не будет работать при параллельной обработке потока.Я смиренно предлагаю эту реализацию. Результирующий поток усекается до более короткого из двух входных потоков.
источник
.., leftStream.isParallel() || rightStream.isParallel()
. Я думаю, что это не имеет никакого эффекта, потому чтоAbstractSpliterator
предлагает ограниченный параллелизм по умолчанию. Поэтому я думаю, что окончательный результат будет таким же, как и при прохожденииfalse
.Библиотека Lazy-Seq обеспечивает функциональность zip.
https://github.com/nurkiewicz/LazySeq
Эта библиотека вдохновлена
scala.collection.immutable.Stream
и нацелена на обеспечение неизменной, поточно-ориентированной и простой в использовании реализации отложенных последовательностей, возможно, бесконечной.источник
Используя последнюю версию библиотеки Guava (для
Streams
класса), вы должны уметьисточник
Будет ли это работать для вас? Это короткая функция, которая лениво оценивает потоки, которые она упаковывает, так что вы можете снабдить ее бесконечными потоками (ей не нужно брать размер потоков, которые будут сжаты).
Если потоки конечны, он останавливается, как только в одном из потоков заканчиваются элементы.
Вот некоторый код модульного теста (намного длиннее, чем сам код!)
источник
takeWhile
конце я должен был опустить то, чего нет в java8, но это не проблема, так как вызываемый абонент может отфильтровывать любые нули, возникающие, когда сжатые потоки имеют разный размер. я думаю, что этот ответ должен быть ответом номер 1, так как он состоит и понятен. отличная работа, спасибо еще раз.источник
Циклоп-реакция AOL , в которую я участвую, также обеспечивает функциональность архивирования, как с помощью расширенной реализации Stream , которая также реализует интерфейс реактивных потоков ReactiveSeq, так и с помощью StreamUtils, которая предлагает большую часть тех же функций через статические методы для стандартных потоков Java.
Он также предлагает более обобщенную молнию на основе Applicative. Например
И даже возможность сопряжения каждого элемента в одном потоке с каждым элементом в другом
источник
Если это кому-то еще нужно,
StreamEx.zipWith
в библиотеке streamex есть функция :источник
Это круто. Я должен был сжать два потока в карту с одним потоком является ключом, а другой является значением
Выход: {A = яблоко, B = банан, C = морковь}
источник