Каков идиоматический способ исчерпать очередь в Java 8?

Допустим, у меня очередь, и я хочу ее исчерпать. Я бы сделал что-то вроде

void emptyQueue(Queue<T> q) {
  T i;
  while ((i = q.poll()) != null)
    consume(i);
}

но это кажется архаичным методом.

Хотелось бы чего-то более похожего на метод forEach. Он, конечно, присутствует - Queue является Collection - но он перебирает элементы, а не потребляет их.

В идеале мне бы понравился метод pollEach на Queue, но я не могу найти ничего подходящего.

Как написать такой код?

Вы действительно добавляете потребителя к forEach ... q.forEach(this::consume); должен быть эквивалентен вашему коду.

daniu 04.06.2018 09:40

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

Didier L 04.06.2018 09:44

вы можете изменить while на: for(T ti= null; (i = queue.poll()) != null; ){...}, что может быть немного лучше, потому что переменная i доступна только внутри области видимости for

Lino 04.06.2018 09:46

Если ваша очередь наследуется от AbstractQueue, вы можете просто использовать метод clear().

RealSkeptic 04.06.2018 09:47
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
5
4
378
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы можете использовать собственный генератор, который вызывает poll() в очереди:

Stream.generate( () -> q.poll() )
    .takeWhile(Objects::nonNull) //Note that this is only available in java 9
    .forEach(i -> consume(i));

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

Мне очень нравится это решение, вы можете сократить () -> q.poll() до q::poll, а также i -> consume(i) до this::consume (при условии, что consume является членом экземпляра класса`)

Lino 04.06.2018 09:59

Обратите внимание, что Stream.generate создает поток неупорядоченный, поэтому семантически это неправильное решение (или, по крайней мере, не идентичное исходному коду), даже если происходит обработка элементов в правильном порядке при последовательном выполнении. И все равно преимущества перед «архаичной» петлей нет…

Holger 04.06.2018 11:56

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