2016-12-22 9 views
16

Коллекционер partitioningBy применяет предикат к каждому элементу в потоке и создает карту из булевых элементов в списки элементов из потока, которые удовлетворяли или не удовлетворяли предикату. Например:Должно ли разбиениеБыть создать карту с записями для true и false?

Stream.of(1,2,3,4).collect(partitioningBy(x -> x >= 3)) 
// {false=[1, 2], true=[3, 4]} 

Как обсуждалось в What's the purpose of partitioningBy, то наблюдается поведение является то, что partitioningBy всегда возвращает карту с записями для обоих правда и ложной. Например:

Stream.empty().collect(partitioningBy(x -> false)); 
// {false=[], true=[]} 

Stream.of(1,2,3).collect(partitioningBy(x -> false)); 
// {false=[1, 2, 3], true=[]} 

Stream.of(1,2,3).collect(partitioningBy(x -> true)); 
// {false=[], true=[1, 2, 3]} 

Это поведение действительно указано где-то? Javadoc только говорит:

Возвращает коллектор, который разбивает входные элементы в соответствии с предиката, и организует их в Map<Boolean, List<T>>. Существует никаких гарантий по типу, изменчивости, сериализуемости или .

Может ли соответствующая реализация вернуть их вместо того, чтобы:

Stream.empty().collect(partitioningBy(x -> false)); 
// {}, or {false=[]}, or {true=[]} 

Stream.of(1,2,3).collect(partitioningBy(x -> false)); 
// {false=[1, 2, 3]} 

Stream.of(1,2,3).collect(partitioningBy(x -> true)); 
// {true=[1, 2, 3]} 

Соответствующее JSR 335 только кажется, включают в себя те же самые документы, но не дополнительное обсуждение о том, что статьи карта будет содержать.

+2

В Java 8 наличие обеих записей не указано, но в любой реализации на основе OpenJDK обе записи будут всегда присутствовать. Гипотетически реализация JDK в чистой комнате может иметь другое поведение, но это кажется мне маловероятным. Как отмечалось в ответе user140547, спецификация Java 9 была изменена, чтобы требовать, чтобы обе записи всегда присутствовали. –

+1

@StuartMarks Это было частью того, что мотивировало мой вопрос. Похоже, что самая быстрая реализация чистой комнаты, основанная только на документах Java 8, будет «partitioningBy (Predicate предикат) {return groupingBy (предикат :: тест); } ', который не предоставил бы пустые списки в результатах. –

+1

@JoshuaTaylor: Верно, но поскольку есть только два возможных и известных ключа (истинные и ложные), было бы неприятно, если бы вам нужно было выполнить нулевую проверку перед повторением списков ... – user140547

ответ

15

В Java 9 Javadoc of the method, есть уточнение, что делает его более явным:

Возвращенный Карта всегда содержит отображения для обоих ложных и истинных ключей.

+4

Может быть тихим свежим, поскольку у нас было [это обсуждение] (http://stackoverflow.com/questions/41036522/combine-allmatch-nonematch-and-anymatch-on-a-single-stream/41036977#comment69298278_41036977) только недавно ... – Holger

+5

@ Holger Yep, после этого я сразу же появился в спецификации, и сборка с изменением (b150) была опубликована только сегодня. –