Добавление значений в 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 для более короткого кода