Trong bài này, chúng ta sẽ tìm hiểu về class Enumset trong Java và các hàm khác nhau của nó qua các ví dụ.

Class EnumSet của collections framework trong Java triển khai tập hợp các phần tử của một enum đơn.

Trước khi bạn tìm hiểu về EnumSet, hãy chắc chắn rằng bạn đã biết về Enums trong Java.

Nó triển khai interface Set.

1. Tạo Enumset

Để tạo một EnumSet, trước tiên chúng ta phải import gói java.util.EnumSet.

Khác với việc triển khai set, EnumSet không có các constructor công khai. Chúng ta phải sử dụng các hàm được xác định trước để tạo ra một EnumSet.

1.1 Sử dụng hàm allOf (Size)

Hàm allof() tạo ra một EnumSet có chứa tất cả các giá trị của enum kiểu Size đã chỉ định. Ví dụ,

/**
* Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
*
* @author cafedevn
* Contact: cafedevn@gmail.com
* Fanpage: https://www.facebook.com/cafedevn
* Instagram: https://instagram.com/cafedevn
* Twitter: https://twitter.com/CafedeVn
* Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

import java.util.EnumSet;

class Main {
    // an enum named Size
    enum Size {
        SMALL, MEDIUM, LARGE, EXTRALARGE
    }
    
    public static void main(String[] args) {

        // Creating an EnumSet using allOf()
        EnumSet<Size> sizes = EnumSet.allOf(Size.class);

        System.out.println("EnumSet: " + sizes);
    }

}

Kết quả

EnumSet: [SMALL, MEDIUM, LARGE, EXTRALARGE]

Lưu ý câu lệnh,

EnumSet<Size> sizes = EnumSet.allOf(Size.class);

Ở đây, Size.Class  biểu diễn  enum có tên Size mà chúng ta đã tạo ra.

1.2 Sử dụng noneOf (Size)

Hàm noneOf() tạo ra một EnumSet trống. Ví dụ,

/**
* Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
*
* @author cafedevn
* Contact: cafedevn@gmail.com
* Fanpage: https://www.facebook.com/cafedevn
* Instagram: https://instagram.com/cafedevn
* Twitter: https://twitter.com/CafedeVn
* Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

import java.util.EnumSet;

class Main {

     // an enum type Size
    enum Size {
        SMALL, MEDIUM, LARGE, EXTRALARGE
    }

    public static void main(String[] args) {

        // Creating an EnumSet using noneOf()
        EnumSet<Size> sizes = EnumSet.noneOf(Size.class);

        System.out.println("Empty EnumSet: " + sizes);
    }
}

Kết quả

Empty EnumSet : []

Ở đây, chúng ta đã tạo ra một enum trống có tên là Size.

Lưu ý : Chúng ta chỉ có thể chèn các phần tử của kiểu enum Size trong chương trình trên. Bởi vì chúng ta đã tạo ra EnumSet trống bằng cách sử dụng enum Size.

1.3 Sử dụng hàm range(e1, e2)

Hàm range() tạo ra một EnumSet chứa tất cả các giá trị của một enum giữa 2 giá trị e1 và e2 bao gồm cả hai giá trị này. Ví dụ,

/**
* Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
*
* @author cafedevn
* Contact: cafedevn@gmail.com
* Fanpage: https://www.facebook.com/cafedevn
* Instagram: https://instagram.com/cafedevn
* Twitter: https://twitter.com/CafedeVn
* Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

import java.util.EnumSet;

class Main {

    enum Size {
        SMALL, MEDIUM, LARGE, EXTRALARGE
    }

    public static void main(String[] args) {

        // Creating an EnumSet using range()
        EnumSet<Size> sizes = EnumSet.range(Size.MEDIUM, Size.EXTRALARGE);

        System.out.println("EnumSet: " + sizes);
    }
}

Kết quả

EnumSet: [MEDIUM, LARGE, EXTRALARGE]

1.4 Sử dụng hàm of()

Hàm of() tạo ra một EnumSet có chứa các phần tử đã chỉ định. Ví dụ,

/**
* Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
*
* @author cafedevn
* Contact: cafedevn@gmail.com
* Fanpage: https://www.facebook.com/cafedevn
* Instagram: https://instagram.com/cafedevn
* Twitter: https://twitter.com/CafedeVn
* Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

import java.util.EnumSet;

class Main {

    enum Size {
        SMALL, MEDIUM, LARGE, EXTRALARGE
    }

    public static void main(String[] args) {

        // Using of() with a single parameter
        EnumSet<Size> sizes1 = EnumSet.of(Size.MEDIUM);
        System.out.println("EnumSet1: " + sizes1);

        EnumSet<Size> sizes2 = EnumSet.of(Size.SMALL, Size.LARGE);
        System.out.println("EnumSet2: " + sizes2);
    }
}

Kết quả

EnumSet1: [MEDIUM]
EnumSet2: [SMALL, LARGE]

2. Các hàm của Enumset

Class EnumSet cung cấp hàm cho phép chúng ta thực hiện các toán tử khác nhau trên EnumSet.

3. Chèn các phần tử vào Enumset

  • add() – chèn các giá trị enum được chỉ định vào EnumSet
  • addAll() chèn tất cả các phần tử của collection đã chỉ định vào set

Ví dụ,

import java.util.EnumSet;

class Main {

    enum Size {
        SMALL, MEDIUM, LARGE, EXTRALARGE
    }

    public static void main(String[] args) {

        // Creating an EnumSet using allOf()
        EnumSet<Size> sizes1 = EnumSet.allOf(Size.class);

        // Creating an EnumSet using noneOf()
        EnumSet<Size> sizes2 = EnumSet.noneOf(Size.class);

        // Using add method
        sizes2.add(Size.MEDIUM);
        System.out.println("EnumSet Using add(): " + sizes2);

        // Using addAll() method
        sizes2.addAll(sizes1);
        System.out.println("EnumSet Using addAll(): " + sizes2);
    }
}

Kết quả

EnumSet using add(): [MEDIUM]
EnumSet using addAll(): [SMALL, MEDIUM, LARGE, EXTRALARGE]

Trong ví dụ trên, chúng ta đã sử dụng hàm addAll() để chèn tất cả các phần tử của EnumSet Size1 đến EnumSet Size2.

Ta cũng có thể chèn các phần tử từ các collection khác như ArrayList, LinkedList, v.v để một EnumSet bằng cách sử dụng hàm addAll(). Tuy nhiên, tất cả các collection nên thuộc cùng loại enum.

5. Truy cập các phần tử của Enumset

Để truy cập các phần tử của EnumSet, chúng ta có thể sử dụng hàm iterator(). Để sử dụng hàm này, chúng ta phải import gói java.util.Iterator. Ví dụ,

/**
* Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
*
* @author cafedevn
* Contact: cafedevn@gmail.com
* Fanpage: https://www.facebook.com/cafedevn
* Instagram: https://instagram.com/cafedevn
* Twitter: https://twitter.com/CafedeVn
* Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

import java.util.EnumSet;
import java.util.Iterator;

class Main {

    enum Size {
        SMALL, MEDIUM, LARGE, EXTRALARGE
    }

    public static void main(String[] args) {

        // Creating an EnumSet using allOf()
        EnumSet<Size> sizes = EnumSet.allOf(Size.class);

        Iterator<Size> iterate = sizes.iterator();

        System.out.print("EnumSet: ");
        while(iterate.hasNext()) {
            System.out.print(iterate.next());
            System.out.print(", ");
        }
    }
}

Kết quả

EnumSet: SMALL, MEDIUM, LARGE, EXTRALARGE,

Lưu ý :

  • hasNext()trả về true nếu có phần tử tiếp theo trong EnumSet
  • next() trả về phần tử tiếp theo trong EnumSet

6. Loại bỏ các phần tử khỏi Enumset

  • remove() – xóa phần tử đã chỉ định khỏi EnumSet
  • removeAll() – loại bỏ tất cả các phần tử khỏi EnumSet

Ví dụ,

/**
* Cafedev.vn - Kênh thông tin IT hàng đầu Việt Nam
*
* @author cafedevn
* Contact: cafedevn@gmail.com
* Fanpage: https://www.facebook.com/cafedevn
* Instagram: https://instagram.com/cafedevn
* Twitter: https://twitter.com/CafedeVn
* Linkedin: https://www.linkedin.com/in/cafe-dev-407054199/
*/

import java.util.EnumSet;

class Main {

    enum Size {
        SMALL, MEDIUM, LARGE, EXTRALARGE
    }

    public static void main(String[] args) {

        // Creating EnumSet using allOf()
        EnumSet<Size> sizes = EnumSet.allOf(Size.class);
        System.out.println("EnumSet: " + sizes);

        // Using remove()
        boolean value1 = sizes.remove(Size.MEDIUM);
        System.out.println("Is MEDIUM removed? " + value1);

        // Using removeAll()
        boolean value2 = sizes.removeAll(sizes);
        System.out.println("Are all elements removed? " + value2);
    }
}

Kết quả

EnumSet: [SMALL, MEDIUM, LARGE, EXTRALARGE]
Is MEDIUM removed? true
Are all elements removed? true

7. Các hàm khác

HàmMô tả
copyOf()Tạo một bản sao của EnumSet
contains()Tìm kiếm phần tử đã chỉ định trong EnumSet  và trả về kết quả boolean
isEmpty()Kiểm tra xem EnumSet có trống hay không
size()Trả về kích thước của EnumSet
clear()Loại bỏ tất cả các phần tử khỏi EnumSet

8. Clonable interface và serializable interface 

Class EnumSet cũng triển khai Cloneable interface và Serializable interface.

Clonable interface

Nó cho phép class  EnumSet tạo một bản sao các instance của class đó.

Serializable interface

Khi các đối tượng Java cần được truyền qua mạng, các đối tượng đó cần được chuyển đổi thành dạng bit hoặc byte. Cần phải làm vậy vì các đối tượng Java không truyền được qua mạng.

Serializable Interface cho phép các class để được tuần tự hóa. Điều này có nghĩa là: các đối tượng của các class triển khai Serializable interface có thể được chuyển đổi thành dạng bit hoặc byte.

9. Tại sao cần sử dụng Enumset?

EnumSet giúp ta lưu trữ các giá trị enum một cách hiệu quả so các set khác (như HashSet, TreeSet).

Một EnumSet chỉ lưu trữ các giá trị enum của một enum cụ thể. Do đó, JVM sẽ biết tất cả các giá trị có thể có của set.

Đây là lý do tại sao các EnumSet được triển khai nội bộ như một chuỗi các bit. Các bit xác định xem các phần tử có trong EnumSet hay không.

Bit của một phần tử tương ứng được bật nếu phần tử đó có trong set.

Đăng ký kênh youtube để ủng hộ Cafedev nha các bạn, Thanks you!