Почему ImmutableList.of () и его друзья запрещают нулевые элементы?

Резюме в значительной степени говорит само за себя. Вот соответствующий фрагмент кода в ImmutableList.createFromIterable():

  if (element == null) {
    throw new NullPointerException("at index " + index);
  }

Я сталкивался с этим несколько раз и не понимаю, почему функция библиотеки общего назначения должна налагать это ограничение.

Редактировать 1: с точки зрения «общего назначения» я был бы доволен 95% случаев. Но я не думаю, что написал 100 звонков ImmutableList.of(), и меня это укусило не раз. Хотя, может быть, я особняк. :)

Изменить 2: я думаю, моя большая жалоба заключается в том, что это создает «икоту» при взаимодействии со стандартными коллекциями java.util. Как вы отметили в своем выступлении, проблемы с null в коллекциях могут проявляться далеко от того места, где были вставлены эти нули. Но если у меня есть длинная цепочка кода, которая помещает нули в стандартную коллекцию на одном конце и обрабатывает их должным образом на другом, тогда я не могу заменить класс коллекций Google на любом этапе пути, потому что он немедленно бросить NullPointerException.


person Matt McHenry    schedule 12.02.2010    source источник
comment
Вопрос: вы понимаете под общим назначением 100% целей или 95% целей?   -  person Kevin Bourrillion    schedule 12.02.2010
comment
Re: edit 2: Это утверждение, что все эти промежуточные точки на пути не должны зависеть от того, передают ли они нули или нет. Я с этим не согласен! Каждый из этих API должен либо явно разрешать null, либо явно запрещать его. Каждый может продолжать настаивать на этом вопросе сколько угодно, но, пожалуйста, поймите, что это чистая жалоба, а не конструктивность. Даже если бы вы убедили каждого из нас, что мы были неправы, неправы, неправы (маловероятно, конечно), это все равно не имело бы значения: мы все равно не можем это изменить.   -  person Kevin Bourrillion    schedule 13.02.2010
comment
универсальные средства, полезные для 100% целей. В противном случае это не общее решение, это просто 95% -ное общее решение. Даже если Google лично не любит нули (правда, мне они тоже не очень нравятся), иногда вам нужно хранить массив имен, где у некоторых вещей нет имен, а использование необязательной оболочки тратит пространство для хранения (точка ImmutableList должен быть эффективным. Предположительно.)   -  person Trejkaz    schedule 29.05.2013


Ответы (4)


Я объяснил это в 25-минутном пункте этого видео: https://youtu.be/ZeO_J2OcHYM?t=1495

Извините за ленивый ответ, но это, в конце концов, всего лишь вопрос, почему (возможно, не подходит для StackOverflow?).

РЕДАКТИРОВАТЬ: Вот еще один момент, который, я не уверен, что я прояснил в видео: общий (по всему Java-коду в мире), количество дополнительного кода, который должен быть написан для тех, кто не поддерживает null случаи использования старых резервных Collections.unmodifiableList(Arrays.asList(...)) и т. д. перегружены общим (по всему миру Java-кодом) количеством дополнительных checkArgument(!foos.contains(null)) вызовов, которые каждый должен был бы добавить, если бы наши коллекции не позаботились об этом за вас. Согласно FAR, в большинстве случаев использование коллекции не предполагает наличия каких-либо значений NULL и действительно должно быстро завершиться неудачей, если таковые имеются.

person Kevin Bourrillion    schedule 12.02.2010
comment
Думаю, мой послужной список вопросов о коллекциях Google на SO не ахти. : - / - person Matt McHenry; 13.02.2010
comment
-1. Не говорите мне, что я должен или не должен вкладывать в свои коллекции. В моих списках часто встречаются пустые значения. Мне редко нужны нули в наборе или карте, но есть много других инструментов, которые я могу использовать, если хочу защититься от нулевых элементов. - person finnw; 13.02.2010
comment
Во-первых, кто говорит вам не помещать null в коллекцию? Если вам нужно, а нам, гуглерам, требуется около 5% времени (мы внимательно это изучили), просто используйте коллекцию, которая поддерживает это. Во-вторых, выбор был сделан, и этот вопрос задает вопрос, почему он был сделан. Есть ли смысл понижать ответ, потому что вам не нравится этот выбор? Это все еще ответ на заданный вопрос. - person Kevin Bourrillion; 13.02.2010
comment
Collections.unmodifiableList () не действительно неизменяемый, потому что вы никогда не узнаете, хранит ли кто-то копию списка поддержки. Так что я считаю это неприемлемым решением. Итак, чтобы обойти это ограничение, мы бы написали класс BetterImmutableList, который работает точно так же, но допускает значения NULL. Я всегда могу использовать BetterImmutableList<@NotNull String>, если хочу утверждать, что он все равно не содержит нулей. Но это трагично, потому что Гуава хороша во многих других отношениях. - person Trejkaz; 18.11.2014
comment
Ваше беспокойство по поводу unmodifiableList не относится к моему примеру. И собираетесь ли вы также переписать EnumMap, ConcurrentHashMap, все очереди JDK и т. Д. И т. Д. По этой причине? - person Kevin Bourrillion; 05.02.2015
comment
Было бы полезно, если бы у конструктора был метод putIfNotNull. Это означало бы, что я мог бы использовать конструктор как конструктор без необходимости иметь блок if для тех случаев, когда значения могут быть нулевыми. - person yarrichar; 11.11.2017
comment
Я подозреваю, что если для объяснения нужно посмотреть видео, это должно быть чепухой. - person Mikhail Batcer; 16.11.2017
comment
Хотя вопрос «Почему» может не подходить для StackOverflow, посмотрите этот youtube, безусловно, не подходит и не должен быть принятым ответом. Да, в 95% случаев вам не нужны значения NULL в неизменяемом списке, и да, null - отстой - мы это понимаем. Основной вопрос (если вы не пишете академический код): - если вы поместите нуль в свой неизменяемый массив, вы хотите раньше взорвать свой космический шаттл за 50 миллиардов долларов или вы хотите рискнуть этим ... может быть все будет хорошо. Я надеялся на технический ответ на этот вопрос, а не на идеологический. - person GaspardP; 22.04.2021
comment
Вы должны проголосовать за ответ, который, по вашему мнению, лучше. Но я думаю, что знаю, почему был принят дерьмовый ответ. Это потому, что когда возникает вопрос, почему человек X сделал вещь Y? из-за этого кому-либо, кроме человека X, сложно ответить на этот вопрос, не так ли? Все, что они могли сделать, это указать на то, что сказал человек X, поэтому я решил (с некоторой поспешностью, я позволю), что могу сделать это сам. - person Kevin Bourrillion; 24.04.2021
comment
Но это не было идеологическим решением. Это было удобное решение. Мы устали постоянно проверять нули в наших коллекциях. Нам нужны были три полезных гарантии из этих коллекций - неизменяемость, детерминированная итерация и отклонение нуля - даже при том, что мы не собирались втиснуть все три в имена классов. Наше мышление было таким: когда это не то, что вам нужно, вы просто используете что-то другое. Я ни разу не пожалел об этом решении. - person Kevin Bourrillion; 24.04.2021

В целом в Google Collections разработчики относятся к группе, которая не считает, что значения NULL должны быть ожидаемым параметром общего назначения.

person Yishai    schedule 12.02.2010

С страницы Guava на Github

Неосторожное использование null может вызвать огромное количество ошибок. Изучая базу кода Google, мы обнаружили, что что-то вроде 95% коллекций не должно иметь в себе каких-либо нулевых значений, и если бы они быстро выходили из строя, а не молча принимали null, это было бы полезно для разработчиков.

Позиция Guava в основном заключается в том, что есть другие способы избежать null в коллекциях. Например, получение пакета элементов с определенным ключом. Например.

// If a widget for the given id does not exist, return `null` in the list
private List<Widget> getWidgets(List<String> widgetIds);

// Could be restructured to use a Map type like this and avoids nulls completely.

// If a widget for the given id does not exist, no entry in list
private Map<String, Widget> getWidgets(List<String> widgetIds);
person Jason    schedule 23.06.2021

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

person 0xfe    schedule 12.02.2010
comment
Нет, улучшения производительности, которые мы получили от этого, были ОЧЕНЬ маленькими по большому счету. - person Kevin Bourrillion; 12.02.2010
comment
Except Функция не аннотирует свой параметр как @Nullable, поэтому вам действительно нужно будет проверить это на null, чтобы выполнить проверку кода, несмотря на то, что список не может содержать нули. (ржу не могу) - person Trejkaz; 11.06.2013