EnumSet is a specialized Set implementation for use with enum types. It’s part of the java.util package. Being a highly efficient, compact alternative to traditional sets, it is designed to provide all of the richness of the traditional Set interface without the time and space overheads.

Key Points:

Optimized for Enums: EnumSet is specifically designed for use with enum types.

Performance: It’s implemented as a bit-vector, which makes it extremely efficient (faster than HashSet).

Not Thread-Safe: EnumSet itself is not thread-safe. External synchronization is needed if multiple threads modify an enum set concurrently and at least one of the threads modifies it.

Nulls: EnumSet does not permit the use of null elements.

Common Operations with EnumSet in Java

import java.util.EnumSet;

// Define an enumeration for days of the week
enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

public class EnumSetDemo {
    public static void main(String[] args) {
        // 1. Initialization using allOf
        EnumSet<Day> allDays = EnumSet.allOf(Day.class);
        System.out.println("All days: " + allDays);

        // 2. Initialization using noneOf
        EnumSet<Day> noDays = EnumSet.noneOf(Day.class);
        System.out.println("No days: " + noDays);

        // 3. Initialization with specific days
        EnumSet<Day> weekend = EnumSet.of(Day.SATURDAY, Day.SUNDAY);
        System.out.println("Weekend days: " + weekend);

        // 4. Initialization with a range
        EnumSet<Day> weekdays = EnumSet.range(Day.MONDAY, Day.FRIDAY);
        System.out.println("Weekdays: " + weekdays);

        // 5. Using complementOf to get the opposite of a specific set
        EnumSet<Day> notWeekend = EnumSet.complementOf(weekend);
        System.out.println("Not weekend days: " + notWeekend);
    }
}

Output:

All days: [MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY]
No days: []
Weekend days: [SATURDAY, SUNDAY]
Weekdays: [MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY]
Not weekend days: [MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY]

Explanation:

1. allOf: Creates an EnumSet containing all the constants of the specified enumeration class.

2. noneOf: Creates an empty EnumSet with the specified element type.

3. of: Creates an EnumSet with the specified constants. Here, it's used to initialize the weekend with SATURDAY and SUNDAY.

4. range: Creates an EnumSet ranging from the specified constant start to end. Here, it's used to create a set with all weekdays.

5. complementOf: Creates an EnumSet with elements not present in the specified set. In this case, it returns all days except the weekend.

EnumSet is a specialized set for use with enum types. It’s very compact and efficient, making operations like add or remove run faster than their HashSet counterparts.

Real-World Use Case: Managing User Permissions with EnumSet

import java.util.EnumSet;

// Define an enumeration for permissions
enum Permission {
    READ, WRITE, EXECUTE, DELETE
}

class User {
    private String name;
    private EnumSet<Permission> permissions;

    public User(String name, EnumSet<Permission> permissions) {
        this.name = name;
        this.permissions = permissions;
    }

    public boolean hasPermission(Permission permission) {
        return permissions.contains(permission);
    }

    @Override
    public String toString() {
        return name + " has permissions: " + permissions;
    }
}

public class PermissionManager {
    public static void main(String[] args) {
        // 1. Granting all permissions
        User admin = new User("Admin", EnumSet.allOf(Permission.class));
        System.out.println(admin);

        // 2. Granting read-only permission
        User guest = new User("Guest", EnumSet.of(Permission.READ));
        System.out.println(guest);

        // 3. Checking user permissions
        System.out.println("Admin has WRITE permission: " + admin.hasPermission(Permission.WRITE));
        System.out.println("Guest has WRITE permission: " + guest.hasPermission(Permission.WRITE));
    }
}

Output:

Admin has permissions: [READ, WRITE, EXECUTE, DELETE]
Guest has permissions: [READ]
Admin has WRITE permission: true
Guest has WRITE permission: false

Explanation:

1. The Permission enum lists the different types of permissions a user can have. Using EnumSet, we can efficiently represent a combination of these permissions.

2. The User class uses an EnumSet to store the permissions granted to the user. The hasPermission method checks if a specific permission is present in the user's EnumSet of permissions.

3. In the PermissionManager class:

– An admin user is granted all permissions using EnumSet.allOf(Permission.class).

– A guest user is granted only the read permission using EnumSet.of(Permission.READ).

– We then check and print whether each user has the WRITE permission.