Объявление ArrayList или List в Java

В чем разница между этими двумя объявлениями?

Декларация 1:

ArrayList<String> arrayList = new ArrayList<String>();

Декларация 2:

List<String> arrayList = new ArrayList<String>();

Ответ 1

List<String> arrayList = new ArrayList<String>();

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

Этот механизм полезен в тех случаях, когда вы разрабатываете библиотеки и т.д., которые могут в какой-то момент изменить детали реализации с минимальными изменениями на стороне клиента.

ArrayList<String> arrayList = new ArrayList<String>();

Это означает, что вам всегда нужно вернуть ArrayList. В некоторый момент времени, если вы хотите изменить детали реализации до LinkedList, на стороне клиента также должны быть изменения LinkedList вместо ArrayList.

Ответ 2

List - это интерфейс, а ArrayList - реализация интерфейса List. Класс ArrayList имеет только несколько методов (i.e clone(), trimToSize(), removeRange() and ensureCapacity()) в дополнение к методам, доступным в интерфейсе List. В этом нет большой разницы.

   1. List<String> l = new ArrayList<>();
   2. ArrayList<String> l = new ArrayList<>();

Если вы используете первый, вы сможете вызвать методы, доступные в интерфейсе List, и вы не можете делать вызовы для новых методов, доступных в классе ArrayList. Где, как, вы можете использовать все методы, доступные в ArrayList, если вы используете второй.

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

List<String> l = new ArrayList<>();
doSomething(l);

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

List<String> l = new LinkedList<>();

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

Ответ 3

Разница в том, что вариант 1 заставляет вас использовать ArrayList, в то время как вариант 2 гарантирует только то, что реализует List<String>.

Позже вы можете изменить это на List<String> arrayList = new LinkedList<String>(); без особых хлопот. Вариант 1 может потребовать изменения не только этой строки, но и других частей, если они полагаются на работу с ArrayList<String>.

Таким образом, я бы использовал List<String> практически в любом случае, за исключением случаев, когда мне нужно было бы вызвать дополнительные методы, которые ArrayList предоставляет (что никогда не было до сих пор): ensureCapacity(int) и trimToSize().

Ответ 4

Первое объявление должно быть ArrayList, второе может быть легко изменено на другой тип List. Таким образом, второй предпочтительнее, поскольку он дает понять, что вам не требуется конкретная реализация. (Иногда вам действительно нужна одна реализация, но это редко)

Ответ 5

Легко изменить реализацию на List на Set:

Collection<String> stringList = new ArrayList<String>();
//Client side
stringList = new LinkedList<String>();

stringList = new HashSet<String>();
//stringList = new HashSet<>(); java 1.7 and 1.8

Ответ 6

В основном это позволяет Java хранить несколько типов объектов в одной реализации структуры, посредством объявления типа универсального типа (например, class MyStructure<T extends TT>), который является одной из основных функций Javas.

Объектно-ориентированные подходы основаны на модульности и повторном использовании путем разделения проблем - способности использовать структуру с любыми типами объектов (при условии соблюдения нескольких правил).

Вы можете просто создать экземпляр следующих вещей:

ArrayList list = new ArrayList();

вместо

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

Объявляя и использующие общие типы, вы сообщаете структуру того типа объектов, которым она будет управлять, и компилятор сможет сообщить вам, если вы вставляете нелегальный тип в эту структуру, например. Пусть говорят:

// this works
List list1 = new ArrayList();
list1.add(1);
list1.add("one");

// does not work
List<String> list2 = new ArrayList<>();
list2.add(1); // compiler error here
list2.add("one");

Если вы хотите увидеть несколько примеров, посмотрите документацию :

/**
 * Generic version of the Box class.
 * @param <T> the type of the value being boxed
 */
public class Box<T> {
    // T stands for "Type"
    private T t;

    public void set(T t) { this.t = t; }
    public T get() { return t; }
}

Затем вы можете создавать такие вещи, как:

class Paper  { ... }
class Tissue { ... }

// ...
Box<Paper> boxOfPaper = new Box<>();
boxOfPaper.set(new Paper(...));

Box<Tissue> boxOfTissues = new Box<>();
boxOfTissues.set(new Tissue(...));

Главное, чтобы извлечь из этого, вы указываете, какой тип объекта вы хотите вставить.

Что касается использования Object l = new ArrayList<>();, вы не получаете доступ к реализации List или ArrayList, поэтому вы не сможете многое сделать с коллекцией.

Ответ 7

Список - это интерфейс, а ArrayList - конкретный класс. Рекомендуется всегда использовать.

List<String> arrayList = new ArrayList<String>();

Потому что здесь список ссылок является гибким. Он также может содержать объект LinkedList or Vector.

Ответ 8

Есть несколько ситуаций, когда вы можете предпочесть первый (немного) повысить производительность, например, на некоторых JVM без JIT-компилятора.

Из этого очень специфического контекста вы должны использовать первый.

Ответ 9

Возможно, вы можете ссылаться на эту ссылку http://docs.oracle.com/javase/6/docs/api/java/util/List.html

Список - это интерфейс .RrayList, LinkedList и т.д. - это классы, которые реализуют list.Whenyou используют интерфейс List, вы должны использовать элементы с помощью ListIterator и можете перемещаться вперед и назад в списке, где, как в ArrayList Iterate, используя Iterator и его элементы могут быть доступны однонаправленно.

Ответ 10

Всякий раз, когда вы видели кодировку из сообщества с открытым исходным кодом, такого как Guava и из Google Developer (Android Library), они использовали этот подход

List<String> strings = new ArrayList<String>();

поскольку он скрывает детали реализации от пользователя. Вы точно

List<String> strings = new ArrayList<String>(); 

общий подход и этот специализированный подход

ArrayList<String> strings = new ArrayList<String>();

Для справки: Эффективное Java 2nd Edition: Пункт 52: Обратитесь к объектам по их интерфейсам.