1. Collections trong Java là gì?

Collections trong Java là một khuân mẫu đã được xây dựng sẵn trong Java, các khuân mẫu này tạo ra các kiến ​​trúc để lưu trữ và thao tác với nhóm các đối tượng. Collections trong Java có thể cung cấp tất cả các thao tác mà bạn cần thực hiện trên dữ liệu như tìm kiếm, sắp xếp, chèn, thao tác và xóa…..

Trong Java, chúng ta có thể sử dụng Framework Collections bởi những ưu điểm của chúng được liệt kê ở bên dưới đây:

  • Cung cấp sẵn các cấu trúc dữ liệu
  • Đại diện cho một tập hợp các lớp và interfaces
  • Có các giao diện và cách triển khai của nó tức là các lớp
  • Cung cấp các thuật toán đã được xây dựng sẵn

2. Hệ thống phân cấp của Framework Collections trong Java

Gói java.util chứa tất cả các lớp và interfaces Framework Collections trong Java, chúng ta hoàn toàn có thể sử dụng các lớp interface hoặc bên trong Framework Collections bằng cách thêm thư viện import java.util.Collections_Name;

Tuy nhiên, chúng ta cần phải biết rằng trong Framework Collections của Java sẽ cung cấp cho chúng ta những lớp hay những interface nào thì mới có thể gọi ra và sử dụng được chúng. Vì vậy mà tại ảnh dưới đây chúng tôi đã cung cấp cho bạn biểu đồ phân cấp các thành phần trong Framework Collections để bạn hiểu rõ hơn về Framework Collections cũng như các lớp hay những interface có trong đó để tiện lợi khi bạn cần sử dụng:

Dưới đây là mô tả của một số lớp và interfaces chính trong Framework Collections:

  • List interface là một tập hợp được sắp xếp (có thứ tự) cho phép chúng ta lưu trữ và truy cập các phần tử theo tuần tự. List interface kế thừa từ Collection interface. List cho phép lưu trữ các phần tử trùng lặp. Chúng ta có thể được phép soát chính xác vị trí các phần tử được chèn vào List và có thể truy cập chúng bằng chỉ số hay vị trí của chúng.
  • Set là một Collection không tuần tự (unordered Collection), nó sẽ không cho phép việc lưu trữ các phần tử trùng lặp, và Set sẽ chỉ có thể chứa nhiều nhất 1 phần tử mang giá trị null. Khi một phần tử trùng lặp được thêm vào Set hành động này sẽ bị bỏ qua vì nó không cho phép lưu trữ trùng lặp nên hành động thêm trung lặp vẫn sẽ khiến Set không thay đổi. Set thường được lưu trữ các phần tử như các hằng số.
  • Queue hay hàng đợi là một interface Collection cung cấp đầy đủ các tính năng của một Collection. Queue thực hiện cơ chế “Vào trước thì xử lý trước” hay gọi tắt là FIFO. Queue cung cấp sẵn các phương thức để bạn truy cập hoặc loại bỏ phần tử đầu tiên, và phương thức để chèn một phần tử vào hàng đợi. Khi cần truy cập vào một phần tử nào đó trong Queue, khi đó ta phải loại bỏ tất cả các phần tử đứng trước nó ra khỏi hàng đợi.
  • Deque hay hàng đợi hai đầu là interface con của Queue. Deque hỗ trợ các thao tác thêm và thao tác loại bỏ phần tử ở cả hai đầu. Ngoài ra nó còn cung cấp thêm các phương thức để truy cập hoặc loại bỏ phần tử đầu hoặc phần tử cuối của nó.

3. Các phương thức thuộc interface Collection trong Java

Có rất nhiều phương thức được khai báo và sử dụng chung trong các interface Collection. Công việc của chúng ta là ghi nhớ lại chúng để sử dụng khi cần thiết. Các phương thức đó được liệt kê ở bảng dưới đây:

Phương thức Mô tả
public boolean add(E elements) Thêm phần tử vào trong một collection
public boolean addAll(Collection<? extends E> c) Chèn các phần tử collection được chỉ định vào collection gọi phương thức này.
public boolean removeAll(Collection c) Xóa đi toàn bộ (hay tất cả) các phần tử có trong collection.
public boolean remove(Object element) Xóa đi một phần tử thuộc collection.
boolean removeIf(Predicate<? super E> filter) Xóa đi tất cả các phần tử của collection với điều kiện thỏa mãn từ vị trí được chỉ định.
public boolean retainAll(Collection<?> c) Xóa đi tất cả các phần tử của collection đang gọi. Ngoại trừ collection được chỉ định sẽ không bị xóa.
public int size() Kiểm tra tổng số phần tử có trong collection.
public void clear() Xóa đi tổng số phần tử khỏi collection.
public boolean contains(Object element) Tìm kiếm một phần tử có trong collection hay không?
public boolean containsAll(Collection<?> c) Tìm kiếm một collection có tồn tại bên trong một collection khác hay không?
public Iterator iterator() Tạo một trình lặp cho collection.
public Object[] toArray() Chuyển đổi từ collection về kiểu array.
public <T> T[] toArray(T[] a) Chuyển đổi một collection thành array. Ở đây, kiểu thời gian chạy của mảng được trả về là kiểu của mảng được chỉ định.
public boolean isEmpty () Kiểm tra một collection có là trống rỗng hay không?
default Stream<E> parallelStream() Trả về một Stream có thể song song với collection được sử dụng làm nguồn của nó.
default Stream<E> stream() Trả về một Stream tuần tự với collection được sử dụng để làm nguồn của nó.
default Spliterator<E> spliterator() Nó tạo ra một Spliterator trên các phần tử được chỉ định có trong một collection.
public boolean equals(Object element) Kiểm tra và so sánh bằng nhau giữa phần tử có trong collection với một giá trị chỉ định.
public int hashCode() Trả về mã băm của collection.

Iterator cung cấp phương thức để lặp lại các thành phần từ đầu đến cuối collection. Các phương thức của interfaces Iterator được liệt kê ở dưới đây:

Phương thức Mô tả
public boolean hasNext() Nó trả về true còn phần tử kế tiếp phần tử đang duyệt, ngược lại nó trả về false.
public object next() Nó trả về phần tử hiện tại và di chuyển con trỏ trỏ tới phần tử tiếp theo.
public void remove() Loại bỏ phần tử cuối được trả về bởi Iterator.

4. Ví dụ collection trong Java

Trong phần này, chúng ta sẽ cùng nhau tham khảo về một số ví dụ điển hình về các lớp và Interfaces có trong Framework Collection. Chúng tôi sẽ chỉ nêu ra các ví dụ liên quan đến các kiểu: List,  ArrayList, LinkedList, Queue, Deque, Set. Trong các ví dụ này sẽ bao gồm cách khai báo, thêm phần tử, duyệt phần tử có trong các collections đó!

4.1 Ví dụ về List

Interfaces List là một Interfaces con của Interfaces Collections. Nó có thể có các giá trị trùng lặp và được xây dựng bởi các lớp ArrayList, LinkedList, Vector và Stack. Trong ví dụ dưới đây, chúng ta sẽ khai báo List, thêm phần tử vào List, duyệt List:

import java.util.*;  
public class Main{  
    public static void main(String args[]){
    	//Khoi tao 1 list moi
        List<String> list= new ArrayList<String>();
        //Them phan tu vao trong List
        list.add("Oto");
        list.add("Xe May");  
        list.add("Tau Hoa");  
        list.add("May Ba");  
        //Duyet qua cac phan tu trong List
        System.out.println("Phan tu trong List la: ");
        Iterator itr = list.iterator();  
        while(itr.hasNext()){  
            System.out.println(itr.next());  
        }  
    }  
}

Kết quả:

Phan tu trong List la:
Oto
Xe May
Tau Hoa
May Ba

4.2 Ví dụ về ArrayList

Lớp ArrayList được cài đặt trên Interfaces List, ArrayList sử dụng một mảng động để lưu trữ phần tử trùng lặp của các kiểu dữ liệu khác nhau. Các phần tử được lưu trữ trong lớp ArrayList có thể được truy cập ngẫu nhiên.

import java.util.*;  
public class Main{  
    public static void main(String args[]){
    	//Khai bao mot arraylist;
        ArrayList<String> list=new ArrayList<String>();
        //Them phan tu vao trong arraylist
        list.add("Lap");
        list.add("Trinh");  
        list.add("Tu"); 
        list.add("Dau"); 
        //Duyệt qua danh arraylist thông qua Iterator
        System.out.println("Phan tu trong Arraylist la: ");
        Iterator itr=list.iterator();  
        while(itr.hasNext()){  
        	System.out.println(itr.next());  
        }  
    }  
}

Kết quả:

Phan tu trong Arraylist la: 
Lap
Trinh
Tu
Dau

4.3 Ví dụ về LinkedList

LinkedList được triển khai từ Interfaces Collections. LinkedList sử dụng một danh sách được liên kết kép trong nội bộ để lưu trữ các phần tử. Nó có thể lưu trữ các phần tử trùng lặp. LinkedList khi thao tác sẽ có thời gian nhanh chóng vì không cần phải dịch chuyển.

import java.util.*;  
public class Main{  
    public static void main(String args[]){
    	//Khai bao 1 linkedlist
        LinkedList<String> al = new LinkedList<String>();  
        //Them phan tu vao trong linkedlist
        al.add("Nguyen Van A");  
        al.add("Nguyen Van B");  
        al.add("Nguyen Van C");  
        al.add("Nguyen Van D");
        //Duyet linkedlist bang Intertor
        System.out.println("Phan tu trong LinkedList la: ");  
        Iterator<String> itr=al.iterator();  
        while(itr.hasNext()){  
        	System.out.println(itr.next());  
        }  
    }  
}

Kết quả:

Phan tu trong LinkedList la: 
Nguyen Van A
Nguyen Van B
Nguyen Van C
Nguyen Van D

4.4 Ví dụ về Queue

Queue thực hiện cơ chế “Vào trước thì xử lý trước” hay gọi tắt là FIFO. Nó có thể được định nghĩa là một danh sách có thứ tự được sử dụng để chứa các phần tử sắp được xử lý. Có nhiều lớp khác nhau như PriorityQueue, Deque và ArrayDeque triển khai Interfaces Queue.

import java.util.*;  
public class Main{  
    public static void main(String args[]){  
    	//Khai bao 1 queue moi 
        PriorityQueue<String> queue = new PriorityQueue<String>();  
        //Them cac phan tu vao queue
        queue.add("Chu Minh Nam"); 
        queue.add("Tran Ngoc Ha");  
        queue.add("Nguyen Tri Thanh");  
        queue.add("Phung Thai Son");  
     	//Hien thi cac phan tu o tren dau queue
        System.out.println("head:"+queue.element());  
        System.out.println("head:"+queue.peek());  
        //Thuc hien lap phan tu trong queue bang iterator
        System.out.println("Thuc hien lap phan tu trong queue");  
        Iterator itr = queue.iterator();  
        while(itr.hasNext()){  
        	System.out.println(itr.next());  
        } 
        //Xoa phan tu theo thu tu duoc them vao dau queue
        queue.remove();   
        //Duyet lai queue bang iterator sau khi xoa
        System.out.println("Queue sau khi xoa phan tu duoc them vao dau:");
        Iterator<String> itr2 = queue.iterator();  
        while(itr2.hasNext()){  
        	System.out.println(itr2.next());  
        }  
    }  
}

Kết quả:

head:Chu Minh Nam
head:Chu Minh Nam
Thuc hien lap phan tu trong queue
Chu Minh Nam
Phung Thai Son
Nguyen Tri Thanh
Tran Ngoc Ha
Queue sau khi xoa phan tu duoc them vao dau:
Nguyen Tri Thanh
Phung Thai Son
Tran Ngoc Ha

4.5 Ví dụ về Deque

Deque là viết tắt của một hàng đợi hai đầu cho phép chúng ta thực hiện các thao tác ở cả hai đầu. Interfaces Deque được kế thừa lại từu Interfaces Queue. Trong Deque, cung cấp các phương thức cần thiết để chúng ta có thể chèn, truy xuất và loại bỏ các phần tử khỏi cả hai đầu.

import java.util.*;  
public class Main{  
    public static void main(String[] args) {  
        //Khoi tao deque moi
        Deque<String> deque = new ArrayDeque<String>();  
        //Them phan tu vao deque
        deque.add("D15CNTT2");  
        deque.add("D16CNTT3");  
        deque.add("D17CNTT4");  
        //Duyet qua deque
        for (String str : deque) {  
        	System.out.println(str);  
        }  
    }  
}

Kết quả:

D15CNTT2
D16CNTT3
D17CNTT4

4.6 Ví dụ về Set

Set trong Java là một Interfaces có trong gói java.util. nó được kế thừa lại từ Interfaces Collections. Set đại diện cho tập hợp các phần tử không có thứ tự không cho phép lưu trữ các phần tử có giá trị trùng lặp. Chúng ta chỉ có thể lưu trữ nhiều nhất một giá trị null trong Set. Kiểu Set có thể được thực hiện bởi HashSet, LinkedHashSet và TreeSet.

import java.util.*;  
public class Main{  
    public static void main(String args[]){  
        //Tao mot HashSet moi
        HashSet<String> set = new HashSet<String>();  
        //Them phan tu vao HashSet
        set.add("Ha Noi");  
        set.add("Hai Phong");  
        set.add("Da Nang");  
        set.add("Ha Noi"); //Phan tu trung lap se khong duoc xu ly
        //Duyet qua Set bang Interator
        System.out.println("Phan tu co trong HashSet: ");  
        Iterator<String> itr=set.iterator();  
        while(itr.hasNext()){  
        	System.out.println(itr.next());  
        }  
    }  
}

Kết quả:

Phan tu co trong HashSet: 
Ha Noi
Hai Phong
Da Nang