🎭 Java Enums: The Cast of Characters in Your Code
Imagine you’re putting on a play. You have a fixed list of actors who can perform—no random strangers allowed on stage! In Java, an Enum (short for enumeration) is exactly like that: a special type that holds a fixed set of constants you define.
Let’s discover Enums through a story about running a Traffic Light System! 🚦
🌟 Chapter 1: Enum Declaration and Constants
The Story
Think of a traffic light. It can only be RED, YELLOW, or GREEN. Never “PURPLE” or “RAINBOW”!
That’s what an Enum does—it creates a closed club of allowed values.
The Magic Spell (Code)
public enum TrafficLight {
RED,
YELLOW,
GREEN
}
That’s it! You just created a type called TrafficLight with exactly 3 members.
Using Your Enum
TrafficLight signal = TrafficLight.RED;
if (signal == TrafficLight.RED) {
System.out.println("STOP!");
}
Why This is Amazing
| Without Enum ❌ | With Enum ✅ |
|---|---|
String color = "red"; |
TrafficLight.RED |
Typos happen: "rde" |
Compiler catches errors |
| No autocomplete | IDE helps you |
Quick Examples
// Days of the week
enum Day { MON, TUE, WED, THU, FRI, SAT, SUN }
// Pizza sizes
enum Size { SMALL, MEDIUM, LARGE, EXTRA_LARGE }
// Card suits
enum Suit { HEARTS, DIAMONDS, CLUBS, SPADES }
🎯 Key Insight: Enums prevent “magic strings” that cause bugs!
🔧 Chapter 2: Enum Methods and Fields
The Story Continues
Our traffic light is working, but now we want each color to mean something—like how long to wait!
Enums can have fields (data) and methods (actions), just like a class!
Adding Superpowers to Our Enum
public enum TrafficLight {
RED(30),
YELLOW(5),
GREEN(25);
private final int seconds; // Field!
TrafficLight(int seconds) {
this.seconds = seconds;
}
public int getSeconds() { // Method!
return seconds;
}
}
Using the Enhanced Enum
TrafficLight light = TrafficLight.RED;
System.out.println(light.getSeconds());
// Output: 30
Built-in Magic Methods
Every enum gets free methods from Java:
// Get the name as a String
TrafficLight.RED.name(); // "RED"
// Get position (starting from 0)
TrafficLight.RED.ordinal(); // 0
TrafficLight.YELLOW.ordinal(); // 1
// Get all values as an array
TrafficLight[] all = TrafficLight.values();
// Convert String to Enum
TrafficLight light = TrafficLight.valueOf("GREEN");
Practical Example
for (TrafficLight t : TrafficLight.values()) {
System.out.println(t.name() +
" = " + t.getSeconds() + " sec");
}
// RED = 30 sec
// YELLOW = 5 sec
// GREEN = 25 sec
🏗️ Chapter 3: Enum Constructors
The Story Deepens
Remember when we wrote RED(30)? That 30 goes into a constructor!
Think of it like ordering pizza: when you say “LARGE”, the shop knows it means 14 inches. The constructor stores that information.
Constructor Rules (Very Important!)
public enum Pizza {
SMALL(8),
MEDIUM(12),
LARGE(14);
private final int inches;
// Constructor is ALWAYS private!
Pizza(int inches) {
this.inches = inches;
}
public int getInches() {
return inches;
}
}
⚠️ Golden Rule: Enum constructors are always private! You can’t write
new TrafficLight(). The only instances are the ones you declare.
Multiple Fields in Constructor
public enum Planet {
EARTH(5.97e24, 6.37e6),
MARS(6.42e23, 3.39e6),
JUPITER(1.90e27, 6.99e7);
private final double mass; // kg
private final double radius; // meters
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
public double surfaceGravity() {
double G = 6.67e-11;
return G * mass / (radius * radius);
}
}
Using It
double gravity = Planet.EARTH.surfaceGravity();
System.out.println("Earth gravity: " + gravity);
// Earth gravity: 9.8 (approximately!)
🚀 Chapter 4: Advanced Enum Features
Abstract Methods in Enums!
Each enum constant can behave differently! Like actors playing different roles:
public enum Operation {
ADD {
public int apply(int a, int b) {
return a + b;
}
},
SUBTRACT {
public int apply(int a, int b) {
return a - b;
}
},
MULTIPLY {
public int apply(int a, int b) {
return a * b;
}
};
public abstract int apply(int a, int b);
}
Using It Like Magic
int result = Operation.ADD.apply(5, 3);
// result = 8
int result2 = Operation.MULTIPLY.apply(4, 7);
// result2 = 28
Implementing Interfaces
Enums can implement interfaces too!
interface Printable {
void print();
}
enum Status implements Printable {
ACTIVE, INACTIVE, PENDING;
@Override
public void print() {
System.out.println("Status: " + this.name());
}
}
Switch Statements Made Beautiful
TrafficLight light = TrafficLight.RED;
switch (light) {
case RED -> System.out.println("Stop!");
case YELLOW -> System.out.println("Slow down!");
case GREEN -> System.out.println("Go!");
}
Singleton Pattern with Enums
The safest way to create a singleton in Java:
public enum Database {
INSTANCE;
public void connect() {
System.out.println("Connected!");
}
}
// Usage:
Database.INSTANCE.connect();
🧙♂️ Pro Tip: Java guarantees only ONE instance of
INSTANCEexists, ever!
📦 Chapter 5: EnumSet and EnumMap
The Story Finale
You’ve got your cast of characters (enum constants). Now you need special collections designed just for them!
EnumSet: The Lightning-Fast Set
EnumSet is a super-efficient Set for holding enum values.
import java.util.EnumSet;
enum Day { MON, TUE, WED, THU, FRI, SAT, SUN }
// Create sets easily
EnumSet<Day> weekend = EnumSet.of(Day.SAT, Day.SUN);
EnumSet<Day> weekdays = EnumSet.range(Day.MON, Day.FRI);
EnumSet<Day> allDays = EnumSet.allOf(Day.class);
EnumSet<Day> noDays = EnumSet.noneOf(Day.class);
EnumSet Operations
EnumSet<Day> workDays = EnumSet.of(Day.MON, Day.TUE);
workDays.add(Day.WED);
workDays.contains(Day.MON); // true
workDays.remove(Day.TUE);
// Complement: all days EXCEPT weekend
EnumSet<Day> notWeekend =
EnumSet.complementOf(weekend);
Why EnumSet?
| Regular HashSet | EnumSet |
|---|---|
| Uses hash codes | Uses bit vectors |
| More memory | Super compact |
| O(1) operations | O(1) but faster! |
EnumMap: The Perfect Partner
EnumMap is a Map where keys are enum constants.
import java.util.EnumMap;
EnumMap<Day, String> schedule =
new EnumMap<>(Day.class);
schedule.put(Day.MON, "Team Meeting");
schedule.put(Day.FRI, "Code Review");
schedule.put(Day.SAT, "Rest!");
String task = schedule.get(Day.MON);
// "Team Meeting"
Practical Example: Activity Tracker
enum Activity { RUNNING, SWIMMING, CYCLING }
EnumMap<Activity, Integer> calories =
new EnumMap<>(Activity.class);
calories.put(Activity.RUNNING, 600);
calories.put(Activity.SWIMMING, 400);
calories.put(Activity.CYCLING, 500);
// Iterate beautifully
for (var entry : calories.entrySet()) {
System.out.println(entry.getKey() +
": " + entry.getValue() + " cal");
}
Why EnumMap?
graph TD A["EnumMap Benefits"] --> B["🚀 Faster than HashMap"] A --> C["💾 Less Memory"] A --> D["🔒 Type Safe"] A --> E["📊 Maintains Order"]
🎯 The Complete Picture
graph LR A["Enum"] --> B["Constants"] A --> C["Fields & Methods"] A --> D["Constructors"] A --> E["Advanced Features"] A --> F["Collections"] B --> B1["Fixed values like RED, GREEN"] C --> C1["Store data, add behavior"] D --> D1["Initialize with values"] E --> E1["Abstract methods"] E --> E2["Interfaces"] E --> E3["Singletons"] F --> F1["EnumSet"] F --> F2["EnumMap"]
🏆 You Did It!
You now understand Java Enums from the ground up:
✅ Declaration: Create fixed sets of constants ✅ Fields & Methods: Add data and behavior ✅ Constructors: Initialize each constant ✅ Advanced: Abstract methods, interfaces, singletons ✅ Collections: EnumSet & EnumMap for performance
🌟 Final Wisdom: Use Enums whenever you have a fixed set of related constants. They make your code safer, cleaner, and more expressive!
Happy coding! 🚀
