2012-09-07 24 views
48

Sự khác nhau giữa hai khai báo này là gì?ArrayList hoặc khai báo danh sách trong Java

Tuyên bố 1:

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

Tuyên bố 2:

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

trùng lặp có thể xảy ra [Tại sao mã hóa nên được "để giao diện" đặc biệt là cho datatypes nguyên thủy?] (http://stackoverflow.com/questions/9392813/why-the-coding-should-be-to-the-interface-especially-for-primitive- datatypes) – assylias

+0

Th cũng là một: http://stackoverflow.com/questions/1413543/what-does-it-mean-to-program-to-a-interface – assylias

+0

Hãy xem http://stackoverflow.com/questions/3383726/ java-declarationing-from-interface-type-instead-of-class – Maciej

Trả lời

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

là generic nơi bạn muốn ẩn chi tiết thực hiện trong khi trả lại cho khách hàng, vào thời điểm sau này của thời gian bạn có thể thay đổi triển khai từ ArrayList thành LinkedList minh bạch.

Cơ chế này hữu ích trong trường hợp bạn thiết kế thư viện, v.v., có thể thay đổi chi tiết triển khai của họ tại một số thời điểm với những thay đổi tối thiểu ở phía máy khách.

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

Nhiệm vụ này bạn luôn cần trả lại ArrayList. Tại một số thời điểm nếu bạn muốn thay đổi chi tiết triển khai thành LinkedList, cũng sẽ có những thay đổi ở phía khách hàng cũng để sử dụng LinkedList thay vì ArrayList.

+2

Và đừng quên lớp Collections hoạt động hoàn toàn với giao diện List, vì vậy những thứ như Collections.emptyList, Collections.synchronizedList Collections.unmodifiableList tất cả danh sách trả về. Vì vậy, nếu một API mong đợi ArrayList, bạn sẽ không may nếu bạn muốn bọc một danh sách hiện có với các phương thức này. – Matt

+0

Đối với các tham số _input_, chắc chắn, tôi đồng ý, nhưng điều này là về đối diện; cụ thể là, object _instantiation_. Trong trường hợp này, điều _only_ nó làm là xóa tất cả các hàm cụ thể của ArrayList mà _should_ có sẵn cho bạn. – Nyerguds

+0

"Điều này yêu cầu bạn luôn luôn cần phải trả lại ArrayList" là hoàn toàn sai, bằng cách này. Bạn hoàn toàn có thể làm cho kiểu trả về của bạn 'List', dù bạn sử dụng nội bộ gì đi chăng nữa. – Nyerguds

1

Danh sách là giao diện và ArrayList được triển khai lớp bê tông. Nó luôn được khuyến nghị sử dụng.

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

Vì đây là danh sách tham chiếu linh hoạt. Nó cũng có thể giữ đối tượng LinkedList or Vector.

6

Sự khác biệt là biến thể 1 buộc bạn sử dụng ArrayList trong khi biến thể 2 chỉ đảm bảo bạn có bất kỳ thứ gì triển khai List<String>.

Sau đó, bạn có thể thay đổi điều đó thành List<String> arrayList = new LinkedList<String>(); mà không gặp nhiều rắc rối. Biến thể 1 có thể yêu cầu bạn thay đổi không chỉ dòng đó mà còn các phần khác nếu họ dựa vào làm việc với ArrayList<String>.

Vì vậy, tôi muốn sử dụng List<String> trong hầu hết mọi trường hợp, trừ khi tôi cần phải gọi các phương thức bổ sung mà ArrayList cung cấp (chưa bao giờ là trường hợp): ensureCapacity(int)trimToSize().

2

Khai báo đầu tiên phải là một ArrayList, thứ hai có thể dễ dàng thay đổi thành kiểu danh sách khác. Như vậy, thứ hai được ưa thích vì nó làm cho nó rõ ràng bạn không yêu cầu thực hiện cụ thể. (Đôi khi bạn thực sự cần một triển khai, nhưng điều đó hiếm)

+0

Vâng, thứ hai không được ưu tiên khi tốc độ là tiêu điểm: -p 'invokeinterface' có thể chậm hơn một chút so với 'invokevirtual', có thể có ý nghĩa trong một số ngữ cảnh. – oldrinb

+1

Nếu hiệu suất là rất quan trọng, tôi sẽ sử dụng một mảng. ;) –

1

Có một vài tình huống mà bạn có thể thích hiệu suất đầu tiên (hơi) cải thiện hiệu suất, ví dụ trên một số JVMs without a JIT compiler.

Ngoài loại ngữ cảnh rất cụ thể đó, bạn nên sử dụng ngữ cảnh đầu tiên.

1

Có thể bạn có thể tham khảo link này http://docs.oracle.com/javase/6/docs/api/java/util/List.html

Danh sách là một interface.ArrayList, LinkedList vv là lớp mà thực hiện danh sách.Khi bạn đang sử dụng giao diện danh sách, bạn phải itearte các yếu tố bằng cách sử dụng ListIterator và có thể di chuyển về phía trước và lạc hậu, trong danh sách nơi như trong ArrayList Iterate sử dụng Iterator và các yếu tố của nó có thể được truy cập một chiều.

2

Nó rất dễ dàng để thay đổi việc thực hiện để 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 
2

Về cơ bản nó cho phép Java để lưu trữ một số loại đối tượng trong một thực hiện cơ cấu, bởi khai báo kiểu chung chung (như class MyStructure<T extends TT>), đó là một trong các tính năng chính của Javas.

Phương pháp hướng đối tượng dựa trên tính mô đun và khả năng sử dụng lại bằng cách tách mối quan tâm - khả năng sử dụng cấu trúc với bất kỳ loại đối tượng nào (miễn là tuân theo một vài quy tắc).

Bạn chỉ có thể nhanh chóng điều như sau:

ArrayList list = new ArrayList(); 

thay vì

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

Bằng cách khai báo và sử dụng các loại generic bạn đang thông báo một cấu trúc của các loại đối tượng nó sẽ quản lý và trình biên dịch sẽ có thể thông báo cho bạn nếu bạn đang chèn một loại bất hợp pháp vào cấu trúc đó, ví dụ. Hãy nói rằng:

// 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"); 

Nếu bạn muốn xem một số ví dụ kiểm tra tài liệu documentation:

/** 
* 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; } 
} 

Sau đó, bạn có thể nhanh chóng những thứ như:

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

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

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

Điều quan trọng để vẽ từ này là bạn đang xác định loại đối tượng bạn muốn hộp.

Để sử dụng Object l = new ArrayList<>();, bạn không truy cập vào việc triển khai List hoặc ArrayList để bạn sẽ không thể làm được gì nhiều với bộ sưu tập.

9

List là giao diện và ArrayList là triển khai giao diện Danh sách. Lớp ArrayList chỉ có một vài phương thức (i.e clone(), trimToSize(), removeRange() and ensureCapacity()) ngoài các phương thức có sẵn trong giao diện Danh sách. Không có nhiều khác biệt trong điều này.

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

Nếu bạn sử dụng đầu tiên, bạn sẽ có thể gọi các phương pháp có sẵn trong giao diện Danh sách và bạn không thể thực hiện cuộc gọi đến các phương pháp mới có sẵn trong lớp ArrayList. Khi nào, bạn được tự do sử dụng tất cả các phương thức có sẵn trong ArrayList nếu bạn sử dụng phương thức thứ hai.

Tôi cho rằng cách tiếp cận đầu tiên là tốt hơn vì khi bạn đang phát triển các ứng dụng java, khi bạn phải truyền các đối tượng khung làm đối số cho các phương thức, thì tốt hơn là tiếp cận với phương pháp đầu tiên.

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

Trong tương lai do hạn chế về hiệu suất, nếu bạn đang thay đổi việc thực hiện sử dụng LinkedList hoặc someother lớp mà thực hiện giao diện List, thay vì ArrayList, bạn cần thay đổi tại một thời điểm chỉ (phần instantiation).

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

Khác bạn sẽ được phép thay đổi ở mọi nơi, ở bất cứ đâu, bạn đã sử dụng triển khai lớp cụ thể làm đối số phương thức.

+0

Bạn có thể giải thích lý do tại sao sử dụng tùy chọn đầu tiên làm cho chúng tôi thay đổi nhiều hơn dòng khai báo? – TheLogicGuy

+0

Tại sao mọi người tiếp tục tuyên truyền câm "bạn có thể thay đổi nó sau này"? Nếu bạn thiết kế tốt, thì _always_ sẽ là ngoại lệ thay vì quy tắc. Hiệu ứng thực sự duy nhất ở đây là bạn mất tất cả các chức năng có sẵn trên 'ArrayList' của bạn ngoại trừ những điều cơ bản' List'. – Nyerguds

0

Bất cứ khi nào bạn đã thấy mã hóa từ cộng đồng mã nguồn mở như ổi và từ Google Developer (Android Library) họ đã sử dụng phương pháp này

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

vì nó ẩn các chi tiết thực hiện từ người dùng. Bạn chính xác

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

đó là cách tiếp cận chung và phương pháp này chuyên

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

Đối với tham chiếu: Effective Java 2nd Edition: Mục 52: Tham khảo đối tượng bởi giao diện của họ

Các vấn đề liên quan