Table of contents
-
- In a word, what is an enumeration class
- Custom Enum Methods (tell us that the enumeration class can be used inside the class, as seen above)
- Using Enum Types in Switch Statements (classic usage of switch+enum combination)
- Comparing Enum Types Using “==” Operator (`==` for enumeration class comparison)
- How to check if an enumeration value exists
- Singleton Pattern
- EnumSet
- EnumMap
- Java 8 and Enums
- JSON Representation of Enum
- Application of inheritance in enumeration class
- Summarize:
Java 5 introduces enumeration classes, please refer to the official documentation for details .
In a word, what is an enumeration class
pure enum value
public enum PizzaStatus {
ORDERED,
READY,
DELIVERED;
}
Enum value added attribute
public enum Distance {
KILOMETER("km", 1000),
MILE("miles", 1609.34),
METER("meters", 1),
INCH("inches", 0.0254),
CENTIMETER("cm", 0.01),
MILLIMETER("mm", 0.001);
private String unit;
private final double meters;
private Distance(String unit, double meters) {
this.unit = unit;
this.meters = meters;
}
// standard getters and setters
}
Fields, Methods and Constructors in Enums (enum values can also provide methods)
@Data
public class Pizza {
public enum PizzaStatus {
ORDERED(5) {
@Override
public boolean isOrdered() {
return true;
}
}, READY(2) {
@Override
public boolean isReady() {
return true;
}
}, DELIVERED(0) {
@Override
public boolean isDelivered() {
return true;
}
};
private int timeToDelivery;
PizzaStatus(int timeToDelivery) {
this.timeToDelivery = timeToDelivery;
}
// 下单
public boolean isOrdered() {
return false;
}
// 准备
public boolean isReady() {
return false;
}
// 交付
public boolean isDelivered() {
return false;
}
public int getTimeToDelivery() {
return timeToDelivery;
}
}
private PizzaStatus status;
public boolean isDeliverable() {
return this.status.isReady();
}
public void printTimeToDeliver() {
System.out.println("Time to delivery is " + this.getStatus().getTimeToDelivery());
}
}
Strategy Pattern (methods can be provided based on the enumeration value, here you can expand the strategy design pattern)
public enum PizzaDeliveryStrategy {
EXPRESS {
@Override
public void deliver(Pizza pz) {
System.out.println("Pizza will be delivered in express mode");
}
}, NORMAL {
@Override
public void deliver(Pizza pz) {
System.out.println("Pizza will be delivered in normal mode");
}
};
public abstract void deliver(Pizza pz);
}
public static void main(String[] args) {
Pizza testPz = new Pizza();
testPz.setStatus(Pizza.PizzaStatus.READY); // true
testPz.printTimeToDeliver(); // Time to delivery is 2
}
Custom Enum Methods (tell us that the enumeration class can be used inside the class, as seen above)
@Data
public class Pizza {
private PizzaStatus status;
public enum PizzaStatus {
ORDERED,
READY,
DELIVERED;
}
public boolean isDeliverable() {
if (getStatus() == PizzaStatus.READY) {
return true;
}
return false;
}
}
Using Enum Types in Switch Statements (classic usage of switch+enum combination)
public int getDeliveryTimeInDays() {
switch (status) {
case ORDERED: return 5;
case READY: return 2;
case DELIVERED: return 0;
}
return 0;
}
Comparing Enum Types Using “==” Operator (for enumeration class comparison ==
)
the “==” operator provides compile-time and run-time safety.
run-time safety
if(testPz.getStatus().equals(Pizza.PizzaStatus.DELIVERED)); ← null 会报 NullPointerException
if(testPz.getStatus() == Pizza.PizzaStatus.DELIVERED); ← Either value can be null and we won't get a NullPointerException
compile-time safety
PizzaStatus.DELIVERED.equals(PizzaStatus2.ORDERED) ← 编译不会报错,会返回false
PizzaStatus.DELIVERED == PizzaStatus2.ORDERED ← 编译会报错
How to check if an enumeration value exists
How to judge whether an enumeration value exists (Check if an Enum Value Exists in Java)
Singleton Pattern
public enum PizzaDeliverySystemConfiguration {
INSTANCE;
PizzaDeliverySystemConfiguration() {
// Initialization configuration which involves overriding defaults like delivery strategy
// 初始化配置,包括覆盖默认值,如交付策略
}
private PizzaDeliveryStrategy deliveryStrategy = PizzaDeliveryStrategy.NORMAL;
public static PizzaDeliverySystemConfiguration getInstance() {
return INSTANCE;
}
public PizzaDeliveryStrategy getDeliveryStrategy() {
return deliveryStrategy;
}
}
Add the following method to the Pizza class
public void deliver() {
if (isDeliverable()) {
PizzaDeliverySystemConfiguration.getInstance().getDeliveryStrategy().deliver(this);
this.setStatus(PizzaStatus.DELIVERED);
}
}
public static void main(String[] args) {
Pizza pz = new Pizza();
pz.setStatus(Pizza.PizzaStatus.READY);
pz.deliver(); // Pizza will be delivered in normal mode
System.out.println(pz.getStatus() == Pizza.PizzaStatus.DELIVERED); // true
}
EnumSet
More efficient compared to HashSet
@Data
public class Pizza {
private static EnumSet<PizzaStatus> undeliveredPizzaStatuses = EnumSet.of(PizzaStatus.ORDERED, PizzaStatus.READY);
private PizzaStatus status;
public enum PizzaStatus {
ORDERED(5) {
@Override
public boolean isOrdered() {
return true;
}
}, READY(2) {
@Override
public boolean isReady() {
return true;
}
}, DELIVERED(0) {
@Override
public boolean isDelivered() {
return true;
}
};
private int timeToDelivery;
PizzaStatus(int timeToDelivery) {
this.timeToDelivery = timeToDelivery;
}
// 下单
public boolean isOrdered() {
return false;
}
// 准备
public boolean isReady() {
return false;
}
// 交付
public boolean isDelivered() {
return false;
}
public int getTimeToDelivery() {
return timeToDelivery;
}
}
public boolean isDeliverable() {
return this.status.isReady();
}
public void printTimeToDeliver() {
System.out.println("Time to delivery is " + this.getStatus().getTimeToDelivery() + " days");
}
public static List<Pizza> getAllUndeliveredPizzas(List<Pizza> input) {
return input.stream().filter((s) -> undeliveredPizzaStatuses.contains(s.getStatus())).collect(Collectors.toList());
}
}
public static void main(String[] args) {
List<Pizza> pzList = new ArrayList<>();
Pizza pz1 = new Pizza();
pz1.setStatus(Pizza.PizzaStatus.DELIVERED);
Pizza pz2 = new Pizza();
pz2.setStatus(Pizza.PizzaStatus.ORDERED);
Pizza pz3 = new Pizza();
pz3.setStatus(Pizza.PizzaStatus.ORDERED);
Pizza pz4 = new Pizza();
pz4.setStatus(Pizza.PizzaStatus.READY);
pzList.add(pz1);
pzList.add(pz2);
pzList.add(pz3);
pzList.add(pz4);
List<Pizza> undeliveredPzs = Pizza.getAllUndeliveredPizzas(pzList);
System.out.println(undeliveredPzs.size()); // 3
}
EnumMap
EnumMap is an efficient and compact implementation compared to the corresponding HashMap, internally represented as an array.
EnumMap(A Guide to EnumMap)
public static EnumMap<PizzaStatus, List<Pizza>> groupPizzaByStatus(List<Pizza> pizzaList) {
EnumMap<PizzaStatus, List<Pizza>> pzByStatus = new EnumMap<PizzaStatus, List<Pizza>>(PizzaStatus.class);
for (Pizza pz : pizzaList) {
PizzaStatus status = pz.getStatus();
if (pzByStatus.containsKey(status)) {
pzByStatus.get(status).add(pz);
} else {
List<Pizza> newPzList = new ArrayList<Pizza>();
newPzList.add(pz);
pzByStatus.put(status, newPzList);
}
}
return pzByStatus;
}
Java 8 and Enums
public static List<Pizza> getAllUndeliveredPizzas(List<Pizza> input) {
return input.stream().filter((s) -> undeliveredPizzaStatuses.contains(s.getStatus())).collect(Collectors.toList());
}
public static EnumMap<PizzaStatus, List<Pizza>> groupPizzaByStatus2(List<Pizza> pzList) {
EnumMap<PizzaStatus, List<Pizza>> map = pzList.stream().filter(a -> a != null && a.getStatus() != null).collect(Collectors.groupingBy(Pizza::getStatus, () -> new EnumMap<>(PizzaStatus.class), Collectors.toList()));
return map;
}
public static Map<PizzaStatus, List<Pizza>> groupPizzaByStatus3(List<Pizza> pizzaList) {
Map<PizzaStatus, List<Pizza>> collect = pizzaList.stream().filter(a -> a != null && a.getStatus() != null).collect(Collectors.groupingBy(Pizza::getStatus));
return collect;
}
public static void main(String[] args) {
List<Pizza> pzList = new ArrayList<>();
Pizza pz1 = new Pizza();
pz1.setStatus(Pizza.PizzaStatus.DELIVERED);
Pizza pz2 = new Pizza();
pz2.setStatus(Pizza.PizzaStatus.ORDERED);
Pizza pz3 = new Pizza();
pz3.setStatus(Pizza.PizzaStatus.ORDERED);
Pizza pz4 = new Pizza();
pz4.setStatus(Pizza.PizzaStatus.READY);
pzList.add(pz1);
pzList.add(pz2);
pzList.add(pz3);
pzList.add(pz4);
EnumMap<Pizza.PizzaStatus, List<Pizza>> map = Pizza.groupPizzaByStatus(pzList);
System.out.println(map);
//{ORDERED=[Pizza(status=ORDERED), Pizza(status=ORDERED)], READY=[Pizza(status=READY)], DELIVERED=[Pizza(status=DELIVERED)]}
EnumMap<Pizza.PizzaStatus, List<Pizza>> map2 = Pizza.groupPizzaByStatus2(pzList);
System.out.println(map2);
// {ORDERED=[Pizza(status=ORDERED), Pizza(status=ORDERED)], READY=[Pizza(status=READY)], DELIVERED=[Pizza(status=DELIVERED)]}
Map<Pizza.PizzaStatus, List<Pizza>> map3 = Pizza.groupPizzaByStatus3(pzList);
System.out.println(map3);
// {READY=[Pizza(status=READY)], ORDERED=[Pizza(status=ORDERED), Pizza(status=ORDERED)], DELIVERED=[Pizza(status=DELIVERED)]}
}
JSON Representation of Enum
Further Reading : Serialization and deserialization of enumeration classes using Jackson (How To Serialize and Deserialize Enums with Jackson)
@Data
public class Pizza {
private PizzaStatus status;
@JsonFormat(shape = JsonFormat.Shape.OBJECT)
public enum PizzaStatus {
ORDERED(5) {
@Override
public boolean isOrdered() {
return true;
}
}, READY(2) {
@Override
public boolean isReady() {
return true;
}
}, DELIVERED(0) {
@Override
public boolean isDelivered() {
return true;
}
};
private int timeToDelivery;
PizzaStatus(int timeToDelivery) {
this.timeToDelivery = timeToDelivery;
}
// 下单
public boolean isOrdered() {
return false;
}
// 准备
public boolean isReady() {
return false;
}
// 交付
public boolean isDelivered() {
return false;
}
@JsonProperty("timeToDelivery")
public int getTimeToDelivery() {
return timeToDelivery;
}
}
public boolean isDeliverable() {
return this.status.isReady();
}
}
Pizza pz = new Pizza();
pz.setStatus(Pizza.PizzaStatus.READY);
ObjectMapper objectMapper = new ObjectMapper();
String s = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(pz);
System.out.println(s);
{
"status" : {
"ready" : true,
"ordered" : false,
"delivered" : false,
"timeToDelivery" : 2
},
"deliverable" : true
}
Application of inheritance in enumeration class
Further Reading : Application of Inheritance in Enumeration Classes (Extending Enums in Java)
-------------------------------------------------- --------------------------- Reading notes are taken from the article: A Guide to Java Enums
------------- -------------------------------------------------- -------------- Reading notes are taken from the article: Enum in Java
Summarize:
-
enum is the keyword
-
Enumeration classes do not support inheritance
-
Enum can implement interface
-
Enum constructors are always private. An instance of an enum cannot be created using the new operator
-
An enum constant is implicitly static final, but its variables can still be changed.
-
We can define methods in enum and enum fields can override them too.
-
We can declare abstract method in java enum, then all enum fields must implement abstract method
-
It is recommended that enumerations use == for comparison