Watch first and then praise, and form a habit.
Praise collection, brilliant life.
preface
The enum keyword, introduced in Java 5, represents a special type of class that always inherits Java Lang. enum class is special because it is a class type, but it has some special constraints more than class types
1, Overview
In this article, we will see what Java enumerations are, what problems they solve, and how to use Java enumerations to implement some design patterns in practice.
The following example defines the status of a simple enumeration type pizza order. There are three statuses: ordered, ready and delivered:
package shuang.kou.enumdemo.enumtest; public enum PizzaStatus { ORDERED, READY, DELIVERED; }
In short, we avoid defining constants through the above code. We put all constants related to the status of pizza orders into one enumeration type.
System.out.println(PizzaStatus.ORDERED.name());//ORDERED System.out.println(PizzaStatus.ORDERED);//ORDERED System.out.println(PizzaStatus.ORDERED.name().getClass());//class java.lang.String System.out.println(PizzaStatus.ORDERED.getClass());//class shuang.kou.enumdemo.enumtest.PizzaStatus
2, Custom enumeration method
Now that we have a basic understanding of what enumerations are and how to use them, let's take the previous example to a new level by defining some additional API methods on enumerations:
public class Pizza { private PizzaStatus status; public enum PizzaStatus { ORDERED, READY, DELIVERED; }
public boolean isDeliverable() { return getStatus() == PizzaStatus.READY; } // Methods that set and get the status variable. }
3, Use = = to compare enumeration types
Because the enumeration type ensures that there is only one constant instance in the JVM, we can safely use the = = operator to compare two variables, as shown in the above example; In addition, the = = operator provides compile time and run-time security.
First, let's look at runtime security in the following code snippet, where the = = operator is used to compare States, and NullPointerException will not be raised if both values are null. Conversely, if the equals method is used, a NullPointerException will be thrown:
Pizza.PizzaStatus pizza = null; System.out.println(pizza.equals(Pizza.PizzaStatus.DELIVERED));//Abnormal null pointer System.out.println(pizza == Pizza.PizzaStatus.DELIVERED);//normal operation
For compile time security, let's take another example and compare two different enumeration types:
if (Pizza.PizzaStatus.DELIVERED.equals(TestColor.GREEN)); // Normal compilation if (Pizza.PizzaStatus.DELIVERED == TestColor.GREEN); // Compilation failed, type mismatch
4, Using enumeration types in switch statements
public int getDeliveryTimeInDays() { switch (status) { case ORDERED: return 5; case READY: return 2; case DELIVERED: return 0; } return 0; }
5, Enumerate the properties, methods, and constructors of types
You can make it more powerful by defining properties, methods and constructors in enumeration types.
Next, let's extend the above example to realize the transition from one stage of pizza to another, and learn how to get rid of the previous if statement and switch statement:
public class Pizza { 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; public boolean isOrdered() {return false;} public boolean isReady() {return false;} public boolean isDelivered(){return false;} public int getTimeToDelivery() { return timeToDelivery; } PizzaStatus (int timeToDelivery) { this.timeToDelivery = timeToDelivery; } } public boolean isDeliverable() { return this.status.isReady(); } public void printTimeToDeliver() { System.out.println("Time to delivery is " + this.getStatus().getTimeToDelivery()); } // Methods that set and get the status variable. }
The following code shows how it work s:
@Test public void givenPizaOrder_whenReady_thenDeliverable() { Pizza testPz = new Pizza(); testPz.setStatus(Pizza.PizzaStatus.READY); assertTrue(testPz.isDeliverable()); }
6, Some design patterns are implemented through enumeration
Singleton mode
In general, using classes to implement Singleton pattern is not easy. Enumeration provides a simple way to implement singletons.
Effective Java and Java and patterns highly recommend this method. What are the benefits of using this method to implement enumeration?
<Effective Java>
This method is similar to the public domain method in function, but it is more concise. It provides a serialization mechanism for free and absolutely prevents multiple instantiations, even in the face of complex serialization or reflection attacks. Although this method has not been widely used, the enumeration type of single element has become the best way to implement Singleton- Effective Java Chinese version Second Edition
Java and patterns
In Java and patterns, the author writes that using enumeration to realize single instance control will be more concise, and the serialization mechanism is provided free of charge, and the JVM fundamentally provides guarantee to absolutely prevent multiple instantiation. It is a more concise, efficient and safe way to realize single instance.
The following code snippet shows how to implement singleton mode using enumeration:
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; } }
How to use it? See the following code:
PizzaDeliveryStrategy deliveryStrategy = PizzaDeliverySystemConfiguration.getInstance().getDeliveryStrategy(); adopt PizzaDeliverySystemConfiguration.getInstance() //Get the PizzaDeliverySystemConfiguration of the singleton
Strategy mode
Generally, the policy pattern is implemented by the same interface of different classes.
This means that adding a new policy means adding a new implementation class. This task can be easily accomplished using enumeration, and adding a new implementation means that only another instance with one implementation is defined.
The following code snippet shows how to implement the policy pattern using enumeration:
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); }
Add the following methods to Pizza:
public void deliver() { if (isDeliverable()) { PizzaDeliverySystemConfiguration.getInstance().getDeliveryStrategy() .deliver(this); this.setStatus(PizzaStatus.DELIVERED); } }
How to use it? See the following code:
@Test public void givenPizaOrder_whenDelivered_thenPizzaGetsDeliveredAndStatusChanges() { Pizza pz = new Pizza(); pz.setStatus(Pizza.PizzaStatus.READY); pz.deliver(); assertTrue(pz.getStatus() == Pizza.PizzaStatus.DELIVERED); }
VII Java 8 and enumeration
The Pizza class can be rewritten in Java 8. You can see how the method lambda and Stream API make the getallundeliveredpizza() and grouppizza bystatus() methods so concise:
getAllUndeliveredPizzas():
public static List<Pizza> getAllUndeliveredPizzas(List<Pizza> input) { return input.stream().filter( (s) -> !deliveredPizzaStatuses.contains(s.getStatus())) .collect(Collectors.toList()); }
groupPizzaByStatus() :
public static EnumMap<PizzaStatus, List<Pizza>> groupPizzaByStatus(List<Pizza> pzList) { EnumMap<PizzaStatus, List<Pizza>> map = pzList.stream().collect( Collectors.groupingBy(Pizza::getStatus, () -> new EnumMap<>(PizzaStatus.class), Collectors.toList())); return map; }
VIII JSON representation of Enum type
Using Jackson library, JSON of enumeration type can be represented as POJO. The following code snippet shows Jackson annotations that can be used for the same purpose:
@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; public boolean isOrdered() {return false;} public boolean isReady() {return false;} public boolean isDelivered(){return false;} @JsonProperty("timeToDelivery") public int getTimeToDelivery() { return timeToDelivery; } private PizzaStatus (int timeToDelivery) { this.timeToDelivery = timeToDelivery; } }
We can use Pizza and Pizza status as follows:
Pizza pz = new Pizza(); pz.setStatus(Pizza.PizzaStatus.READY); System.out.println(Pizza.getJsonString(pz));
The generated Pizza state is displayed in the following JSON:
{ "status" : { "timeToDelivery" : 2, "ready" : true, "ordered" : false, "delivered" : false }, "deliverable" : true }
summary
In this article, we discussed Java enumeration types, from basic knowledge to advanced applications and practical application scenarios. Let's feel the powerful function of enumeration. It's really not so simple to make good use of enumeration classes
The above is the content of this article about enumeration classes
Wait, don't row away. Let the blogger negotiate a meal~
We'll give you some benefits. Bloggers have been promoting Alibaba cloud recently,
Activity discount price: the lowest price in the whole network is 87 yuan / year, 261 yuan / 3 years, which is cheaper than students' 9.9 per month (comfortable one)
New users can try. There is a server of their own, which is very convenient for deployment and learning in the early stage
Alibaba cloud[ Click buy]
White whoring is not good and creation is not easy. Your praise is the biggest driving force of my creation. If I write something wrong, please leave a message in the comment area for correction.
If old fellow is harvested, please give a complimentary complimentary to encourage bloggers.