Explain Codes LogoExplain Codes Logo

Can I set enum start value in Java?

java
enum
singleton
best-practices
Alex KataevbyAlex Kataev·Nov 28, 2024
TLDR

In Java, enum does not support a custom start value. Rather, specific values are laid out using a constructor:

public enum Status { START(100), /* It's never "too early" for a 100! */ MIDDLE(200), /* We're halfway there! */ END(300); /* 300, THIS. IS. END. */ private final int code; Status(int code) { this.code = code; } public int getCode() { return this.code; } }

You could call Status.START.getCode() to get 100. An enum in Java is more about defining constants with names than defining a sequence of numbers.

Enum Custom Values: How-to Guides

Java's enum types are pretty much classes. Not just integers. Let's drill down into patterns and tools crucial for their power utilization.

Building Enums with Constructors & Fields

Embedding a constructor, private fields, and methods within an enum class gives it the feel of a fully-fledged class:

public enum Role { ADMIN(1), /* Power Level: 9000 */ USER(2), GUEST(3); private final int roleId; Role(int roleId) { this.roleId = roleId; } public int getRoleId() { return this.roleId; } }

Invoke Role.ADMIN.getRoleId() and you'll get 1; the power of custom values unleashed!

Leveraging Static Maps and Ordinals

A static Map can be used to map constants to custom values:

import java.util.Map; import java.util.HashMap; public enum Color { RED, /* Red. Hot. Spicy! */ GREEN, /* The color of money */ BLUE; /* Blue like... java! */ private static final Map<Color, Integer> map = new HashMap<>(); static { map.put(RED, 0xFF0000); map.put(GREEN, 0x00FF00); map.put(BLUE, 0x0000FF); } public int getColorCode() { return map.get(this); } }

This method lets us use a lookup table of custom values for each enum constant.

Switch Case for Conditional Handling

switch statement is an amazingly powerful tool that enums excel with:

public int getPriority(TaskStatus status) { switch (status) { case URGENT: return 1; /* Save the city! */ case HIGH: return 2; /* No time for lunch */ case MEDIUM: return 3; /* You got some time to spare */ case LOW: return 4; /* Procrastinator's Land */ default: return 5; } }

A succinct switch-based logic revolving around enum values.

TreeMap for Ordered Mapping

When order matters, TreeMap is your go-to tool:

import java.util.TreeMap; public enum Priority { LOW, /* Barely moving */ MEDIUM, /* We're picking up speed */ HIGH; /* Warp speed, Mr. Sulu */ private static final TreeMap<Priority, Integer> map = new TreeMap<>(); static { map.put(LOW, 1); map.put(MEDIUM, 2); map.put(HIGH, 3); } public int getLevel() { return map.get(this); } }

Retrieval is simple as Priority.HIGH.getLevel(), giving you 3.

Centralized Method for Value Retrieval

A single static method is a great way to retrieve a value across multiple enum constants:

public enum Operation { ADD, /* Plus Ultra! */ SUBTRACT, /* Reducing is also productive */ MULTIPLY, /* Let's amp it up */ DIVIDE; /* Divide and conquer */ public static Operation getOperationByOrdinal(int ordinal) { return values()[ordinal]; } }

Operation.getOperationByOrdinal(1) gets you the SUBTRACT operation.

Using Ordinals for Custom Values

The ordinal can be a base value for customizable values:

public enum Step { ONE, /* Baby steps */ TWO, /* Dual strike */ THREE, /* Three's a crowd */ FOUR; /* It's a party */ private static final int BASE = 10; public int getCustomValue() { return BASE + ordinal(); } }

Numerical sequencing now begins at 10 when you call Step.ONE.getCustomValue().

Enriched patterns in Java Enums

Adding a Cherry on top of our enumeration cake with more patterns.

Caching Values, Conserving Memory

Avoiding class reinstantiation aids memory conservation and processing, by caching values:

public enum Planet { MERCURY(3.303e+23), /* Small but mighty */ VENUS(4.869e+24), /* High pressure job */ EARTH(5.976e+24); /* Carrying the weight of the world */ private final double mass; private static final Map<Planet, Double> massLookup = new HashMap<>(); static { for (Planet p : Planet.values()) { massLookup.put(p, p.mass); } } Planet(double mass) { this.mass = mass; } public double getMass() { return massLookup.get(this); } }

This is perfect for constant values frequented in multiple queries.

Singleton Pattern as a Cinch

Enums are great for singletons for their built in instance control, an elementary and serialization safe pattern:

public enum Singleton { INSTANCE; /* Can't touch this */ private SomeValuableResource resource; Singleton() { resource = new SomeValuableResource(); } public SomeValuableResource getResource() { return resource; } }

Singleton.INSTANCE.getResource() guarantees a single initialization.

Dynamic Behavior with Anonymous Classes

Anonymous classes enable dynamic behavior for each enum constant:

public enum Calculator { ADD { @Override public int calculate(int x, int y) { return x + y; /* Plus Ultra! */ } }, SUBTRACT { @Override public int calculate(int x, int y) { return x - y; /* Less is More! */ } }; public abstract int calculate(int x, int y); }

Each enum constant provides a new implementation, granting different success behaviors.