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.