Объединять потоки для создания чередующейся последовательности с использованием лямбда-выражения или Stream API

У меня есть код, который возвращает Stream, как и предполагалось, но, возможно, его можно заменить каким-либо типом операции лямбда или stream () вместо того, чтобы исчерпывать итераторы в цикле while?

Это просто метод, который чередует элементы из потоков first и second и останавливается, когда в одном из них заканчиваются элементы.

public static <T>Stream<T> alternatingSequence(Stream<T> first, Stream<T> second){
        Iterator<T> iteratorFirst = first.iterator();
        Iterator<T> iteratorSecond = second.iterator();
        Stream<T> resultStream = Stream.empty();
        while (iteratorFirst.hasNext() && iteratorSecond.hasNext()){
            resultStream = Stream.concat(resultStream, Stream.of(iteratorFirst.next(), iteratorSecond.next()));
        }
        return resultStream;
    }
}

Может быть, вы также включите то, что должен делать этот код, вместо того, чтобы оставлять читателю самим понять это.

GhostCat 16.07.2018 16:05

Вы меняете два итератора?

user9455968 16.07.2018 16:05

Использование Java Stream API. Может, этот код нельзя заменить лямбда-выражением?

Serhii 16.07.2018 16:05

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

Serhii 16.07.2018 16:08

ах, значит, вы собираетесь объединить два потока (a1, a2 ...) и (b1, b2 ...) и вернуть чередование (a1, b1, a2, b2 ...)? и, по-видимому, вы хотите ленивую оценку следующих элементов, я прав?

Patrick Parker 16.07.2018 16:08

@PatrickParker Изменил это давно.

user9455968 16.07.2018 16:15

Что-то вроде Stream.generate(() -> null).takewhile(iteratorFirst.hasNext() && iteratorSecond.hasNext()).flatMap(ignored -> Stream.of(iteratorFirst.next(), iteratorSecond.next())) могло бы сделать, но я не думаю, что это более читабельно, чем ваше существующее решение.

Jaroslaw Pawlak 16.07.2018 16:19

Или StreamSupport.stream(iteratorFirst.spliterator(), false).filter(element -> iteratorSecond.hasNext()).flatMap(element -> Stream.of(element, iteratorSecond.next())), но это снова нарушает договор, так как Predicate должен быть без гражданства.

Jaroslaw Pawlak 16.07.2018 16:23

Я должен использовать только Java8, поэтому takeWhile не подходит для меня. Как его заменить на Java8?

Serhii 17.07.2018 11:39

@ Сергей Какой именно выход вам нужен?

Pankaj Singhal 17.07.2018 18:04

Первый поток [«A», «B», «C», «D»], второй поток [«1», «2», «3»], вывод потока [«A», «1», «B» , «2», «C», «3»], например.

Serhii 17.07.2018 21:30

@ Сергей был ли на ваш вопрос успешно дан ответ?

Patrick Parker 28.07.2018 16:15
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
13
649
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Используя Streams.zip Гуавы, вы можете объединить два потока в поток из двухэлементных потоков, который затем вы можете просто сгладить для создания чередующейся последовательности:

return Streams.zip(first, second, (arg1, arg2) -> Stream.of(arg1, arg2))
    .flatMap(Function.identity());

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

Примечание:

Если у вас нет доступа к Guava, вы можете реализовать свой собственный zip(a, b, bifunc), как показано здесь.

Другие вопросы по теме