Интерфейс Set
не делает promises о том, позволяют ли реализации использовать элементы null
. Каждая реализация должна объявить об этом в своей документации.
Collectors.toSet()
promises, чтобы вернуть реализацию Set
, но явно не дает никаких гарантий относительно типа, изменчивости, сериализуемости, или безопасность потока Set
возвращена ". Нулевая безопасность не упоминается.
Текущая реализация Collectors.toSet()
в OpenJDK всегда использует HashSet
, которая допускает нулевые элементы, но это может измениться в будущем, а другие реализации могут по-другому.
Если реализация Set
запрещает элементы null
, она бросает NullPointerException
в разное время, в частности во время попытки add(null)
. Казалось бы, если Collectors.toSet()
решил использовать реалистичную реализацию Set
с нулевым нетерпимостью, вызов stream.collect(Collectors.toSet())
на Stream stream
бросить. Спецификация collect
не содержит никаких исключений, а также не спецификация любого из методов Collector
. Это может означать, что вызов collect
разрешает null в пределах stream
, но, с другой стороны, неясно, действительно ли это означает много, поскольку NullPointerException
является неконтролируемым исключением и не обязательно должен быть указан.
Является ли это более четким в любом другом месте? В частности, является ли следующий код гарантированным не бросать? Гарантируется ли возврат true
?
import java.util.stream.*;
class Test {
public static boolean setContainsNull() {
return Stream.of("A", "list", "of", null, "strings")
.collect(Collectors.toSet())
.contains(null);
}
}
Если нет, то я предполагаю, что мы всегда должны гарантировать, что поток не содержит нулей перед использованием Collectors.toSet()
или будет готов к обработке NullPointerException
. (Достаточно ли этого исключения?) Альтернативно, когда это неприемлемо или сложно, мы можем запросить конкретную реализацию набора с использованием кода типа Collectors.toCollection(HashSet::new)
.
Изменить: существует существующий вопрос, который кажется поверхностным схожим, и этот вопрос закрылся как предполагаемый дубликат этого. Однако связанный вопрос вообще не затрагивает Collectors.toSet()
. Более того, ответы на этот вопрос составляют основные предположения моего вопроса. Этот вопрос спрашивает: допустимы ли пустые значения в потоках? Да. Но что происходит, когда (полностью разрешенный) поток, содержащий нули, собирается через стандартный сборщик?