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>();
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>();
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
.
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
Đố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
"Đ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
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
.
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)
và trimToSize()
.
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)
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
Nếu hiệu suất là rất quan trọng, tôi sẽ sử dụng một mảng. ;) –
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.
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.
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
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.
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.
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
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
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ọ
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
Th cũng là một: http://stackoverflow.com/questions/1413543/what-does-it-mean-to-program-to-a-interface – assylias
Hãy xem http://stackoverflow.com/questions/3383726/ java-declarationing-from-interface-type-instead-of-class – Maciej