Интересно, почему java.util.ArrayList
позволяет добавить null
. Есть ли какой-либо случай, когда я хотел бы добавить null
к ArrayList
?
Я задаю этот вопрос , потому что в проекте мы имели ошибку , когда некоторый код добавлял null
к , ArrayList
и это было трудно определить , где ошибка была. Очевидно, что NullPointerException
был брошен, но только когда другой код попытался получить доступ к элементу. Проблема заключалась в том, как найти код, который добавил null
объект. Было бы проще, если ArrayList
бы в коде было исключение, где добавлялись элементы.
java
api-design
collections
Альфредо Осорио
источник
источник
null
в большинстве их коллекций).null
способ представления отсутствующих данных в Java по умолчанию, нравится вам это или нет. На самом деле многим это не нравится, и они делают это аргументом в пользу функционального стиля программирования. Ответ с наибольшим количеством голосов не имеет смысла / не отражает суть проблемы.null
есть. «Отсутствует» - это лишь одна из нескольких возможных интерпретацийnull
. Другими действительными интерпретациями могут быть «Неизвестно», «Не применимо» или «Неинициализировано». Чтоnull
представляет, зависит от приложения. Как сказал бы сообщество Python: «Перед лицом двусмысленности откажитесь от соблазна гадать». Отказ удерживать значение NULL в контейнере, который вполне способен на это, был бы только предположением.Ответы:
Это дизайнерское решение в основном определяется именами.
Имя ArrayList предлагает читателю функциональность, аналогичную массивам, и для разработчиков Java Collections Framework вполне естественно ожидать, что подавляющее большинство пользователей API будет полагаться на его функционирование, подобное массивам.
В частности, это связано с обработкой нулевых элементов. Пользователь API, зная, что ниже работает нормально:
Я был бы очень удивлен , если выяснил, что подобный код для ArrayList будет генерировать NPE:
Рассуждения, как указано выше, представлены в учебном материале JCF, который подчеркивает сходство между ArrayList и простыми массивами:
Если вы хотите, чтобы реализация List не допускала пустые значения, ее лучше называть как-
NonNullableArrayList
то так или иначе, чтобы не запутывать пользователей API.Дополнительное примечание: в комментариях ниже приводится дополнительное обсуждение, а также дополнительные соображения, подтверждающие изложенные здесь аргументы.
источник
LinkedList
также поддерживаетnull
записи в списке.null
записей полезно во многих случаях.Null может быть допустимым значением для элемента списка. Скажем, ваш список содержит элементы, которые представляют некоторые дополнительные данные о списке пользователей и хранятся в том же порядке, что и пользователи. Если дополнительные данные заполнены, то ваш список будет содержать дополнительные данные, иначе слот, соответствующий пользователю, будет нулевым. (Я уверен, что есть лучшие примеры, но вы поняли)
если вы не хотите разрешать добавление нулей, то вы можете обернуть список массивов своей собственной оберткой, которая выбрасывается при добавлении нуля.
источник
ArrayList
позволяет нулевой дизайн. Это намеренно. От Javadoc :Ответ на вопрос «почему» заключается в том, что в противном случае ArrayList не будет использоваться в тех случаях, когда необходимо добавить его
null
в список. Напротив, вы можете запретить ArrayList содержать нули, либо проверяя значения перед их добавлением, либо используя оболочку, которая предотвращает это.Очевидно, любой случай, когда
null
имеет особое значение. Например, это может означать, что значение в данной позиции в списке не было инициализировано или предоставлено.Вы можете легко реализовать это поведение, создав класс-оболочку. Однако такое поведение не требуется большинству программистов / приложений.
источник
Есть ли случай, когда я хотел бы добавить ноль в ArrayList?
Конечно, как насчет предварительного распределения? Вам нужны
ArrayList
вещи, которые вы еще не можете создать, потому что у вас недостаточно информации. Просто потому, что вы не можете придумать причину, по которой кто-то может захотеть что-то сделать, не делает это плохой идеей. Без разницы. (Теперь я уверен, что кто-то придет и скажет, что вместо этого у вас должны быть пустые объекты, которые соответствуют некоторому шаблону, о котором они читают в каком-то непонятном блоге, и что программисты действительно должны писать программы, даже не используяif
утверждений, бла-бла.)Если у вас, ребята, есть контракт, которого никогда не должно быть
null
в контейнере, тогда вам решать , что контракт будет соблюден, вероятно, наиболее уместно, утверждая. Вероятно, это заняло бы максимум 10 строк кода. Java невероятно облегчает вам подобные вещи. JDK не может читать ваши мысли.источник
ensureCapacity(int minCapacity)
методом иArrayList(int initialCapacity)
конструктором.null
в предварительно выделенные (но пока неиспользованные ) записи вArrayList
; но мы можем позволитьensureCapacity
это сделать, но не позволять другим функциям, например,set
делать это. Причины, приведенные в другом месте, кажутся сильнее.set
элемента должно быть возможно любое значение, которое может быть возвращеноget
. Даже если обычная попыткаget
элемента, для которого пространство было выделено, но никогда не записано, должнаnull
вызывать исключение, а не возвращаться , все равно было бы полезно иметь пару методов, которые позволят,list1.setOrEraseIfNull(index, list2.getOrReturnNull(index))
а неif (list2.valueSet(index)) list1.set(index, list2.get(index)); else list1.unset(index);
Похоже, это скорее философский (программный) вопрос.
ArrayList
поскольку служебный класс предназначен для того, чтобы быть полезным в широком контексте возможных вариантов использования.Вопреки вашему скрытому утверждению, что принятие значения NULL в качестве допустимого значения не рекомендуется, существует множество примеров, когда значение NULL является абсолютно допустимым.
Единственной наиболее важной причиной является то, что
null
этоdo not know
эквивалент любого ссылочного типа, включая типы каркаса. Это подразумевает, что нуль не может быть заменен в любом случае более беглой версиейnothing
значения.Итак, допустим, что вы храните целые числа 1, 3, 7 в вашем массиве по соответствующему индексу: из-за некоторых вычислений вы хотите получить элемент с индексом 5, поэтому ваш массив должен возвращать: «значение не сохранено». Этого можно достичь, возвращая null или NullObject . В большинстве случаев возврат встроенного нулевого значения достаточно выразителен. После вызова метода, который может вернуть значение null, и использования его возвращаемого значения, проверка возвращаемого значения в отношении null довольно распространена в современном коде.
источник
Заявление
является действительным и полезным (я не думаю, что мне нужно объяснять, почему). Также полезно иметь коллекцию файлов, некоторые из которых могут быть нулевыми.
Полезность коллекций, которые могут содержать нулевые объекты, напрямую зависит от полезности объектов, которые могут быть нулевыми. Это действительно так просто.
источник
Проще принять все, чем быть ограничительным, а затем попытаться раскрыть свой дизайн после свершившегося факта.
Например, что если они oracle / sun предоставили только NonNullableArrayList, но вы хотели бы иметь возможность добавить значение Null в свой список. Как бы вы это сделали? Вам, вероятно, придется создать совершенно другой объект, вы не можете использовать extension NonNullableArrayList. Вместо этого, если у вас есть ArrayList, который принимает все, вы можете легко расширить его и переопределить добавление, когда оно не принимает нулевые значения.
источник
Полезность нуля?
Очень сильно, когда вы идете со списком списков, чтобы смоделировать двухмерную реальную пластину с разными позициями. Половина из этих позиций может быть пустой (в случайных координатах), в то время как заполненные позиции не представляют простое int или String, а представлены сложным объектом. Если вы хотите сохранить информацию о местоположении, вам нужно заполнить пустые места нулем, чтобы ваш list.get (x) .get (y)не приводит к неприятным сюрпризам. Чтобы противостоять нулевым исключениям, вы можете проверить на нулевое (очень популярное) или использовать опциональное (которое я считаю удобным в этом случае). Альтернативой было бы заполнить пустые места «мусорными» объектами, которые могут привести к всевозможным беспорядкам в будущем. Если ваша нулевая проверка не пройдена или где-то забыта, Java сообщит вам. С другой стороны, «ненужный» объект-заполнитель, который не проверен должным образом, может пройти незамеченным.
источник