In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article focuses on "how to make good use of enumerations in Java". Interested friends may wish to have a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn how to make good use of enumerations in Java.
1. Overview
The enum keyword, introduced in java5, represents a special type of class that always inherits the java.lang.Enum class, and more can be viewed in its official documentation.
Enumerations are often compared with constants, probably because we use a lot of enumerations to replace constants. So what are the advantages of this approach?
Constants defined in this way make the code more readable, allow compile-time checks, pre-record a list of acceptable values, and avoid unexpected behavior caused by passing in invalid values.
The following example defines the status of a simple enumerated type of pizza order, with three ORDERED, READY, and DELIVERED states:
Package shuang.kou.enumdemo.enumtest; public enum PizzaStatus {ORDERED, READY, DELIVERED;}
To put it simply, we avoid defining constants through the above code, and we put all the constants that are consistent with the status of the pizza order into an 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 () {if (getStatus () = = PizzaStatus.READY) {return true;} return false;} / / Methods that set and get the status variable. }
3. Use = = to compare enumerated types
Because the enumeration type ensures that only one constant instance exists in JVM, we can safely use the "= =" operator to compare two variables, as shown in the previous example; in addition, the "= =" operator provides compile-time and run-time security.
First, let's take a look at the runtime security in the following code snippet, where the "= =" operator is used to compare states, and NullPointerException is not thrown if both values are null. Conversely, if you use the equals method, NullPointerException is thrown:
If (testPz.getStatus () .equals (Pizza.PizzaStatus.DELIVERED)); if (testPz.getStatus () = = Pizza.PizzaStatus.DELIVERED)
For compile-time security, let's look at another example, comparing two different enumerated types, using the equal method to determine that the result is true, because the enumerated value of the getStatus method is the same as the enumerated value of another type, but logically it should be false. This problem can be avoided using the = = operator. Because the compiler indicates a type incompatibility error:
If (testPz.getStatus () .equals (TestColor.GREEN)); if (testPz.getStatus () = = TestColor.GREEN)
4. Use enumerated 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 the type
"there is a supplement from JavaGuide at the end of the article."
You can make it more powerful by defining properties, methods, and constructors in enumerated types.
Next, let's extend the above example to achieve the transition from one stage of pizza to another, and learn how to get rid of the previously used if and switch statements:
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:
@ Test public void givenPizaOrder_whenReady_thenDeliverable () {Pizza testPz = new Pizza (); testPz.setStatus (Pizza.PizzaStatus.READY); assertTrue (testPz.isDeliverable ());}
6 、 EnumSet and EnumMap
6.1. EnumSet
EnumSet is a Set type designed specifically for enumerated types.
Compared with HashSet, it is a very efficient and compact representation of a particular set of Enum constants because of the use of inner part vector representation.
It provides a type-safe alternative to traditional int-based "bit flags" and enables us to write concise code that is easier to read and maintain.
EnumSet is an abstract class that has two implementations: RegularEnumSet and JumboEnumSet, which you choose depends on the number of constants in the enumeration when instantiated.
EnumSet is appropriate for enumerating constant collection operations (such as subset, add, delete, containsAll, and removeAll batch operations) in many scenarios, and Enum.values () if you need to iterate over all possible constants.
Public class Pizza {private static EnumSet undeliveredPizzaStatuses = EnumSet.of (PizzaStatus.ORDERED, PizzaStatus.READY); private PizzaStatus status; public enum PizzaStatus {...} public boolean isDeliverable () {return this.status.isReady ();} public void printTimeToDeliver () {System.out.println ("Time to delivery is" + this.getStatus (). GetTimeToDelivery () + "days") } public static List getAllUndeliveredPizzas (List input) {return input.stream () .filter ((s)-> undeliveredPizzaStatuses.contains (s.getStatus () .if (Collectors.toList ());} public void deliver () {if (isDeliverable ()) {PizzaDeliverySystemConfiguration.getInstance () .getDeliveryStrategy () .requests (this) This.setStatus (PizzaStatus.DELIVERED);} / / Methods that set and get the status variable. }
The following tests demonstrate the power of EnumSet in some scenarios:
@ Test public void givenPizaOrders_whenRetrievingUnDeliveredPzs_thenCorrectlyRetrieved () {List 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 undeliveredPzs = Pizza.getAllUndeliveredPizzas (pzList); assertTrue (undeliveredPzs.size () = = 3);}
6.2. EnumMap
EnumMap is a specialized mapping implementation that uses enumeration constants as keys. It is an efficient and compact implementation compared to the corresponding HashMap and is internally represented as an array:
EnumMap map
Let's take a quick look at a real-world example that demonstrates how to use it in practice:
Public static EnumMap groupPizzaByStatus (List pizzaList) {EnumMap pzByStatus = new EnumMap (PizzaStatus.class); for (Pizza pz: pizzaList) {PizzaStatus status = pz.getStatus (); if (pzByStatus.containsKey (status)) {pzByStatus.get (status) .add (pz);} else {List newnewPzList = new ArrayList (); newPzList.add (pz) PzByStatus.put (status, newPzList);}} return pzByStatus;}
The following tests demonstrate the power of EnumMap in some scenarios:
@ Test public void givenPizaOrders_whenGroupByStatusCalled_thenCorrectlyGrouped () {List 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 map = Pizza.groupPizzaByStatus (pzList); assertTrue (map.get (Pizza.PizzaStatus.DELIVERED). Size () = = 1); assertTrue (map.get (Pizza.PizzaStatus.ORDERED). Size () = = 2); assertTrue (map.get (Pizza.PizzaStatus.READY). Size () = 1);}
7. Implement some design patterns through enumeration
7.1 singleton mode
In general, it is not easy to implement the Singleton pattern using classes, and enumerations provide an easy way to implement singletons.
This approach is highly recommended by "Effective Java" and "Java and pattern". What are the benefits of implementing enumerations in this way?
"Effective Java"
"this approach is functionally similar to the public domain approach, but it is more concise and provides a free serialization mechanism that absolutely prevents multiple instantiations, even in the face of complex serialization or reflection attacks. Although this method has not been widely used, enumerated types of single elements have become the best way to implement Singleton.-- Effective Java Chinese version second Edition
"Java and Mode"
"in Java and patterns, the author writes that using enumerations to implement single-instance control is more concise, and provides a serialization mechanism free of charge, and is fundamentally guaranteed by JVM to absolutely prevent multiple instantiations, which is a more concise, efficient and secure way to implement singletons."
The following code snippet shows how to implement singleton mode using enumerations:
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? Take a look at the following code:
PizzaDeliveryStrategy deliveryStrategy = PizzaDeliverySystemConfiguration.getInstance () .getDeliveryStrategy ()
What you get through PizzaDeliverySystemConfiguration.getInstance () is the singleton PizzaDeliverySystemConfiguration.
7.2 Policy Model
Typically, policy patterns are implemented by different classes implementing the same interface.
This means that adding a new policy means adding a new implementation class. You can easily accomplish this task with enumerations, and adding a new implementation means defining only another instance with one implementation.
The following code snippet shows how to implement the policy pattern using enumerations:
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 () .initiate (this); this.setStatus (PizzaStatus.DELIVERED);}}
How to use it? Take a look at 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);}
8. Java 8 and enumeration
The Pizza class can be rewritten with Java 8, and you can see how the methods lambda and Stream API make the getAllUndeliveredPizzas () and groupPizzaByStatus () methods so concise:
GetAllUndeliveredPizzas (): public static List getAllUndeliveredPizzas (List input) {return input.stream () .filter ((s)->! deliveredPizzaStatuses.contains (s.getStatus () .destroy (Collectors.toList ());}
GroupPizzaByStatus ():
Public static EnumMap groupPizzaByStatus (List pzList) {EnumMap map = pzList.stream () .collect (Collectors.groupingBy (Pizza::getStatus, ()-> new EnumMap (PizzaStatus.class), Collectors.toList ()); return map;}
9. JSON expression of Enum type
Using the Jackson library, you can represent the JSON of an enumerated type 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 PizzaStatus as follows:
Pizza pz = new Pizza (); pz.setStatus (Pizza.PizzaStatus.READY); System.out.println (Pizza.getJsonString (pz))
The generated Pizza status is displayed in the following JSON:
{"status": {"timeToDelivery": 2, "ready": true, "ordered": false, "delivered": false}, "deliverable": true}
For more information about JSON serialization / deserialization (including customization) of enumerated types, see Jackson- serializing enumerations into JSON objects.
At this point, I believe you have a deeper understanding of "how to make good use of enumerations in Java". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.