Добавление значений в Arraylist
Код 1:
ArrayList arr = new ArrayList();
arr.add(3);
arr.add("ss");
Код 2:
ArrayList<Object> arr = new ArrayList<Object>();
arr.add(3);
arr.add("ss");
Код 3:
ArrayList<Object> arr = new ArrayList<Object>();
arr.add(new Integer(3));
arr.add(new String("ss"));
все вышеперечисленные три кода работают нормально.. может кто-нибудь сказать мне, что предпочтительнее и почему.. и почему компилятор eclipse всегда дает предупреждение, когда тип аргументов не упоминается в Arraylist.. спасибо заранее..
Ответы
Ответ 1
Первое простое правило: никогда не используйте конструктор String(String)
, он абсолютно бесполезен (*).
Итак, arr.add("ss")
отлично.
С 3
он немного отличается: 3
- это литерал int
, который не является объектом. Только объекты могут быть помещены в List
. Таким образом, int
необходимо преобразовать в объект Integer
. В большинстве случаев это будет сделано автоматически для вас (этот процесс называется autoboxing). Он фактически делает то же самое, что и Integer.valueOf(3)
, который может (и будет) избегать создания нового экземпляра Integer
в некоторых случаях.
Так что на самом деле писать arr.add(3)
обычно лучше, чем использовать arr.add(new Integer(3))
, потому что он может избежать создания нового объекта Integer
и вместо этого использовать повторно и существующий.
Отказ от ответственности: я фокусируюсь на различии между вторым и третьим блоками кода здесь и в значительной степени игнорирую часть дженериков. Дополнительные сведения о дженериках см. В других ответах.
(*) есть некоторые неясные угловые случаи, когда это полезно, но как только вы подходите к тем, вы будете знать, что никогда не принимать абсолютные утверждения как абсолюты; -)
Ответ 2
Второй вариант был бы предпочтительным:
- он избегает ненужных/неэффективных вызовов конструктора
- он позволяет указать тип элемента для списка (если это отсутствует, вы получите предупреждение)
Однако наличие двух разных типов объектов в одном списке имеет немного плохой дизайн-запах. Нам нужно больше контекста, чтобы говорить об этом.
Ответ 3
Предпочтительна вторая форма:
ArrayList<Object> arr = new ArrayList<Object>();
arr.add(3);
arr.add("ss");
Всегда указывайте общие аргументы при использовании общих типов (например, ArrayList<T>
). Это исключает первую форму.
Что касается последней формы, она более подробна и делает дополнительную работу без пользы.
Ответ 4
Хорошо, делая это, вы открываете себя, чтобы запускать ошибки времени, если только вы не согласны с тем, что ваши арраисты могут содержать как строки, так и целые числа и слоны.
Eclipse возвращает ошибку, потому что не хочет, чтобы вы не знали о том, что, указав тип типа для общего параметра, вы открываете себя для ошибок времени выполнения. По крайней мере, с двумя другими примерами вы знаете, что у вас могут быть объекты в вашем Arraylist, и поскольку Inetegers и Strings являются обоими объектами, Eclipse не предупреждает вас.
Любой код 2 или 3 в порядке. Но если вы знаете, что у вас будут либо только ints, либо только строки в вашем arraylist, я бы сделал
ArrayList<Integer> arr = new ArrayList<Integer>();
или
ArrayList<String> arr = new ArrayList<String>();
соответственно.
Ответ 5
Собственно, третья предпочтительна:
ArrayList<Object> array = new ArrayList<Object>();
array.add(Integer.valueOf(3));
array.add("ss");
Это позволяет избежать автобоксинга (Integer.valueOf(3)
по сравнению с 3
) и не создает ненужный объект String.
Eclipse жалуется, когда вы не используете аргументы типа с таким общим типом, как ArrayList, потому что вы используете что-то, называемое необработанным типом, которое не рекомендуется. Если класс является общим (т.е. Имеет параметры типа), тогда вы всегда должны использовать аргументы типа с этим классом.
Автобоксинг, с другой стороны, является личным предпочтением. Некоторые люди в порядке с этим, а некоторые нет. Мне это не нравится, и я включаю предупреждение для autoboxing/autounboxing.
Ответ 6
Вы получаете предупреждение, потому что ArrayList
является частью дженериков java. По сути, это способ уловить ошибки вашего типа во время компиляции. Например, если вы объявляете список массивов с типами Integer (ArrrayList<Integer>
), а затем пытаетесь добавить к нему строки, вы получите сообщение об ошибке во время компиляции - избегая неприятных сбоев во время выполнения.
Первый синтаксис существует для обратной совместимости и его следует избегать, когда это возможно (обратите внимание, что в старых версиях Java нет дженериков).
Второй и третий примеры в значительной степени эквивалентны. Поскольку вам нужно передать объект, а не примитивный тип в метод add
, ваш 3
будет внутренне преобразован в Integer(3)
. При написании строки в двойных кавычках вы фактически создаете объект String
. При вызове String("ss")
вы создаете новый объект String
со значением, равным параметру ( "ss" ).
Если вам действительно не нужно хранить разные типы в своем списке, я бы предложил на самом деле использовать правильное объявление типа, например. ArrayList<Integer> = new ArrayList<Integer>()
- это сэкономит вам много головной боли в долгосрочной перспективе.
Если вам нужно несколько типов данных в списке, то второй пример лучше.
Ответ 7
Два последних варианта одинаковы, int
автоматически привязывается к Integer
, где вам нужен Object
. Если вы не пишете какой-либо класс в < > , он будет Object
по умолчанию. Поэтому нет никакой разницы, но лучше понять, напишите ли вы Object
.
Ответ 8
в первом случае вы не определяете тип, который будет удерживаться и привязан к вашей конструкции arraylist
это предпочтительный метод для этого, вы определяете тип списка, а ide будет обрабатывать остальные
в третьем вы лучше просто определите List для более короткого кода