2013-08-28 5 views
6

Ниже приведены два способа, как создать ArrayList:Как правильно создать ArrayList?

List<String/*or other object*/> arrList = new ArrayList();//Imports List, ArrayList 
ArrayList<String/*or other object*/> arrList = new ArrayList();//Imports just ArrayList 

В чем разница? Какой метод следует использовать?

+3

Прежний позволяет вам использовать _abstraction_. – rocketboy

+2

Помимо очевидного ответа, вы не должны беспокоиться об импорте. Они не влияют на производительность во время выполнения. –

+1

Взгляните на [what-does-it-mean-to-program-to-an-interface] (http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to -an-interface) – Pshemo

ответ

6

Первый вид рекомендуется для открытого интерфейса класса (скажем, объявление атрибутов в классе). Это известный совет, который вы должны запрограммировать для интерфейса, а не для конкретной реализации (это указано в Design Patterns). Количество классов, которые вы должны импортировать, мало связано с качеством кода и хорошим дизайном.

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

Бывают случаи, когда можно объявить и использовать конкретные классы, хотя (например, для небольшого снижения производительности). Но публичный интерфейс класса должен по возможности использовать интерфейсы, это облегчит реализацию будущих изменений.

+0

Когда я прочитал вопрос, я был уверен, что в течение нескольких секунд будет много людей, дающих этот или аналогичный ответ (если бы никто не имел, я бы хотел;)). Однако в 15 лет, как программист, никогда не возникала настоящая живая проблема, игнорируя описанное вами правило, и у меня не было никакой прибыли, следуя за ней. Итак, есть ли у вас пример из вашего живого программирования, который действительно побуждает всех никогда, никогда, НИКОГДА не программировать против конкретных классов? –

+0

@KaiHuppmann по соображениям производительности вполне нормально объявлять и использовать конкретные классы (скажем, как локальные переменные в методе). Но публичный интерфейс класса должен быть раскрыт с точки зрения интерфейсов. Это хорошо послужило мне :) –

+0

@KaiHuppmann хорошо, они все не так :) – ZhongYu

1

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

Это добавляет flexibility к вашей программе, потому что вы можете легко изменить реализацию.

2

Первые способы кодирования называется интерфейс

Второй называется кодированием для реализации.

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

0

Список - это интерфейс. ArrayList - это класс, реализующий интерфейс List.

0

Разница заключается в том, что он скрывает конкретную реализацию от вызывающих методов, возвращающих List. Это, как правило, хорошая практика. Если вы вернетесь List, то у вас есть свобода позже изменить базовую реализацию, не беспокоясь о влиянии пульсации на изменение кучи другого кода. Если вам не нужны конкретные для списка вещи, такие как List.get(index), вы можете сделать еще один шаг и просто указать Collection<String> col = new ArrayList<String();

1

Первый из вас оставляет желать изменить конкретный класс (ArrayList), если позже вы поймете, что другая реализация Список лучше подходит для вашей задачи. Вам нужно будет только изменить эту строку, так как другие места, использующие arrList, ожидают чего-либо, что реализует List, а не ArrayList.

Во второй версии, если вы решите сделать это изменение, вам придется изменить каждое место, которое ожидает ArrayList.

Как упоминалось выше, это называется кодированием к интерфейсу.

0

Если вы хотите создать ArrayList, учитывается только вторая.Первый создает List, который реализуется классом ArrayList, но во многих случаях они не взаимозаменяемы. This question имеет довольно хороший ответ.

+1

Возможно создание «ArrayList» с использованием первого варианта. – RaptorDotCpp

0

Вопреки распространенному мнению, я говорю, что мы должны использовать 2-ю форму

ArrayList<X> list = new ArrayList<>(); 

Эта линия является деталью реализации; мы должны быть как можно более конкретными в наших деталях реализации.

Это не часть публичного API, который должен быть абстрагирован; аргументы для «кода против интерфейса» здесь не применяются.

0

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

  • Если вы думаете, что человек, использующий код действительно нужно знать детали реализации, которую вы используете, используйте конкретный класс. Например, если вы пишете библиотеку с высокой производительностью, которая имеет методы, возвращающие конкретную реализацию, такую ​​как LinkedList, которая требует особой осторожности при обращении).

  • В большинстве других случаев, когда вы можете избежать чрезмерной детализации, используйте интерфейсы.

Смежные вопросы