Thứ Hai, 15 tháng 4, 2024

List

 

A. List Interface

Là một phần của Java Collection Framework và đại diện cho một danh sách các phần tử có thứ tự, cho phép các phần tử trùng lặp và có thể truy cập thông qua chỉ mục.

Các đặc điểm của List
Các phần tử được sắp xếp theo thứ tự chúng được thêm vào.
Mỗi phần tử có một chỉ mục tương ứng, bắt đầu từ 0 cho phần tử đầu tiên và tăng dần theo thứ tự.
List cho phép các phần tử trùng lặp, nghĩa là một phần tử có thể xuất hiện nhiều lần trong List.
Java cung cấp nhiều triển khai của List interface, bao gồm ArrayList, LinkedList và Vector, trong đó ArrayList thường được sử dụng nhất.

B. ArrayList


Đặc điểm của ArrayList
Được lưu trữ dưới dạng một mảng động, có thể tăng hoặc giảm kích thước tuỳ thuộc vào nhu cầu của ứng dụng.
Duy trì thứ tự của các phần tử được thêm vào.
Cho phép các phần tử trùng lặp, tức là một phần tử có thể xuất hiện nhiều lần trong danh sách.
Cung cấp thời gian truy cập ngẫu nhiên (O(1)) vào các phần tử thông qua chỉ mục.
Thời gian thêm và loại bỏ một phần tử ở cuối danh sách là O(1), nhưng nếu thêm hoặc loại bỏ ở vị trí khác thì thời gian sẽ là O(n) do phải di chuyển các phần tử.
Không đồng bộ, điều này có nghĩa là không an toàn cho việc sử dụng đồng thời trong môi trường đa luồng mà không có các biện pháp đồng bộ hóa.

Dưới đây là một số phương thức quan trọng của lớp ArrayList trong Java:

Mục đích sử dụngPhương thứcMô tả
Thêm phần tửadd(E element)Thêm một phần tử vào cuối danh sách.
add(int index, E element)Thêm một phần tử vào vị trí đã chỉ định trong danh sách.
addAll(Collection<? extends E> c)Thêm tất cả các phần tử từ một Collection vào cuối danh sách.
addAll(int index, Collection<? extends E> c)Thêm tất cả các phần tử từ một Collection vào vị trí đã chỉ định trong danh sách.
Loại bỏ phần tửremove(Object o)Loại bỏ một phần tử cụ thể khỏi danh sách.
remove(int index)Loại bỏ phần tử ở vị trí đã chỉ định trong danh sách.
Xóa tất cả phần tửclear()Xóa tất cả các phần tử khỏi danh sách.
Kiểm tra và truy xuấtcontains(Object o)Kiểm tra xem danh sách có chứa một phần tử cụ thể hay không.
get(int index)Trả về phần tử ở vị trí chỉ định trong danh sách.
indexOf(Object o)Trả về chỉ mục đầu tiên của phần tử cụ thể trong danh sách, hoặc -1 nếu không tìm thấy.
isEmpty()Kiểm tra xem danh sách có rỗng hay không.
iterator()Trả về một iterator cho các phần tử trong danh sách.
size()Trả về số lượng phần tử trong danh sách.
toArray()Chuyển đổi danh sách thành một mảng.
Sao chép và xử lý mảngclone()Tạo một bản sao của ArrayList.
toArray(T[] a)Chuyển đổi danh sách thành một mảng, sử dụng mảng đã cho nếu có đủ kích thước.
Xử lý tập hợpremoveAll(Collection<?> c)Loại bỏ tất cả các phần tử trong danh sách mà cũng có trong Collection đã cho.
retainAll(Collection<?> c)Chỉ giữ lại các phần tử trong danh sách mà cũng có trong Collection đã cho.
subList(int fromIndex, int toIndex)Trả về một phần của danh sách từ chỉ mục từ fromIndex (bao gồm) đến toIndex (không bao gồm)

Dưới đây là một ví dụ minh họa về cách sử dụng ArrayList trong Java để lưu trữ và quản lý một danh sách các chuỗi:

import java.util.ArrayList; public class ArrayListExample { public static void main(String[] args) { // Khởi tạo một đối tượng ArrayList để lưu trữ chuỗi ArrayList<String> stringList = new ArrayList<>(); // Thêm các phần tử vào ArrayList stringList.add("Apple"); stringList.add("Banana"); stringList.add("Orange"); // Hiển thị số lượng phần tử trong ArrayList System.out.println("Số lượng phần tử trong ArrayList: " + stringList.size()); // Truy cập và hiển thị các phần tử trong ArrayList System.out.println("Các phần tử trong ArrayList:"); for (String fruit : stringList) { System.out.println(fruit); } // Xóa một phần tử từ ArrayList stringList.remove("Banana"); // Hiển thị số lượng phần tử sau khi xóa System.out.println("Số lượng phần tử trong ArrayList sau khi xóa: " + stringList.size()); } }

C. LinkedList

Điểm chínhMô tả
Lưu trữ và kết nối bằng liên kếtLinkedList lưu trữ các phần tử dưới dạng các nút liên kết với nhau bằng các tham chiếu. Mỗi nút chứa một phần tử và liên kết đến nút tiếp theo và trước đó.
Linh hoạt trong việc thay đổi kích thướcDo sử dụng cấu trúc danh sách liên kết, LinkedList có thể thay đổi kích thước một cách linh hoạt trong quá trình thực thi chương trình.
Thời gian thêm và loại bỏ phần tửThêm và loại bỏ phần tử ở đầu hoặc cuối danh sách có độ phức tạp là O(1), trong khi thêm và loại bỏ ở vị trí bất kỳ có độ phức tạp là O(n).
Không đồng bộLinkedList không đồng bộ, điều này có nghĩa là nó không an toàn cho việc sử dụng đồng thời trong môi trường đa luồng mà không có các biện pháp đồng bộ hóa.
Ưu điểm và hạn chếLinkedList thích hợp cho các thao tác thêm và loại bỏ phần tử thường xuyên ở đầu hoặc cuối danh sách, nhưng không phải là lựa chọn tốt cho truy cập ngẫu nhiên.

D.Sự khác nhau giữa ArrayList và LinkedList

Cả hai lớp ArrayList và LinkedList đều được implements từ giao tiếp List và duy trì thứ tự của phần tử được thêm vào. Cả hai lớp này đều là lớp không đồng bộ (non-synchronized).

Có vài sự khác nhau giữa ArrayList và LinkedList được đưa ra như trong bảng dưới đây:

ArrayListLinkedList
1) ArrayList nội bộ sử dụng mảng động để lưu trữ các phần tử.LinkedList nội bộ sử dụng danh sách liên kết doubly để lưu trữ các phần tử.
2) Thao tác với ArrayList là chậm bởi vì nó sử dụng nội bộ mảng. Nếu bất kỳ phần tử nào được xoá khỏi mảng, tất cả các bit được chuyển trong bộ nhớ.Thao tác với LinkedList là nhanh hơn so với ArrayList bởi vì nó sử dụng danh sách liên kết doubly do đó không cần chuyển đổi bit nào trong bộ nhớ.
3) Lớp ArrayList trong java chỉ có thể hoạt động như một list vì nó chỉ implements giao tiếp List.Lớp LinkedList trong java có thể hoạt động như một list và queue(hàng đợi) vì nó implements các giao tiếp List và Deque.
4) ArrayList là tốt hơn trong việc lưu trữ và truy cập dữ liệu.LinkedList là tốt hơn trong việc thao tác dữ liệu.

Vậy khi nào chúng ta sẽ sử dụng ArrayList và khi nào chúng ta sẽ sử dụng LinkedList? Chúng ta sẽ sử dụng ArrayList khi ứng dụng của chúng ta cần truy xuất phần tử nhiều hơn cập nhật và xóa phần tử và chúng ta sẽ sử dụng LinkedList khi ứng dụng của chúng ta cần cập nhật và xóa phần tử nhiều hơn là truy cập phần tử.


E. Lưu ý

  1. 1. Khai báo với Interface List:
java
List<String> myList = new ArrayList<>();
  1. 2. Khai báo với Lớp Cụ thể ArrayList:
java
ArrayList<String> myList = new ArrayList<>();

Điểm khác biệt chính giữa hai cách khai báo này là ở phần loại dữ liệu của biến myList:

  1. 1. Khai báo với Interface List: Trong trường hợp này, chúng ta khai báo biến myList với kiểu dữ liệu là List<String>. Điều này có nghĩa là biến myList chỉ được chứa đối tượng của lớp implement giao diện List, có thể là ArrayList, LinkedList, Vector, hoặc bất kỳ triển khai nào khác của List. Việc sử dụng interface List giúp chúng ta tạo ra một lớp trừu tượng và linh hoạt, cho phép chúng ta dễ dàng chuyển đổi giữa các triển khai của List mà không cần thay đổi quá nhiều mã nguồn.

  2. 2. Khai báo với Lớp Cụ thể ArrayList: Trong trường hợp này, chúng ta khai báo biến myList với kiểu dữ liệu là ArrayList<String>, nghĩa là biến myList chỉ có thể chứa đối tượng của lớp ArrayList. Sử dụng lớp cụ thể giới hạn biến myList chỉ có thể tham chiếu đến đối tượng của loại cụ thể mà chúng ta đã chỉ định.

Tóm lại, việc sử dụng interface List cho phép chúng ta tạo ra mã linh hoạt và dễ dàng mở rộng, trong khi việc sử dụng lớp cụ thể ArrayList giới hạn biến chỉ có thể tham chiếu đến ArrayList và không cho phép sử dụng các phương thức mở rộng của ArrayList.

Không có nhận xét nào:

Đăng nhận xét