Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use Java enumeration to improve work efficiency

2025-01-30 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly shows you "how to use Java enumeration to improve work efficiency", the content is easy to understand, clear, hope to help you solve your doubts, the following let Xiaobian lead you to study and learn "how to use Java enumeration to improve work efficiency" this article.

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 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;publicenum 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 ()); / / ORDEREDSystem.out.println (PizzaStatus.ORDERED); / / ORDEREDSystem.out.println (PizzaStatus.ORDERED.name (). GetClass ()); / class java.lang.StringSystem.out.println (PizzaStatus.ORDERED.getClass ()); / / class shuang.kou.enumdemo.enumtest.PizzaStatus2. 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:

Publicclass Pizza {private PizzaStatus status; publicenum PizzaStatus {ORDERED, READY, DELIVERED;} public boolean isDeliverable () {if (getStatus () = = PizzaStatus.READY) {returntrue;} returnfalse;} / / 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 where two different enumeration types are compared and the result is determined to be true using the equal method, because the enumeration value of the getStatus method is the same as the enumeration value of the other 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. Using enumerated types in switch statements

Public int getDeliveryTimeInDays () {switch (status) {case ORDERED: return5; case READY: return2; case DELIVERED: return0;} return0;} 5. Enumerate the properties, methods, and constructors of types

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:

Publicclass Pizza {private PizzaStatus status; publicenum PizzaStatus {ORDERED (5) {@ Override public boolean isOrdered () {returntrue;}}, READY (2) {@ Override public boolean isReady () {returntrue }}, DELIVERED (0) {@ Override public boolean isDelivered () {returntrue;}}; privateint timeToDelivery; public boolean isOrdered () {returnfalse;} public boolean isReady () {returnfalse;} public boolean isDelivered () {returnfalse } public int getTimeToDelivery () {return timeToDelivery;} PizzaStatus (int timeToDelivery) {this.timeToDelivery = timeToDelivery;}} public boolean isDeliverable () {returnthis.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:

@ Testpublic 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.

Publicclass Pizza {privatestatic EnumSet undeliveredPizzaStatuses = EnumSet.of (PizzaStatus.ORDERED, PizzaStatus.READY); private PizzaStatus status; publicenum PizzaStatus {...} public boolean isDeliverable () {returnthis.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:

@ Testpublic 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:

Publicstatic 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 newPzList = new ArrayList (); newPzList.add (pz); pzByStatus.put (status, newPzList) }} return pzByStatus;}

The following tests demonstrate the power of EnumMap in some scenarios:

@ Testpublic 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, provides a serialization mechanism for free, and absolutely prevents multiple instantiations, even in the face of complex serialization or reflection attacks. Although this approach is not widely used, the enumerated type of a single element has become the best way to implement Singleton. The second edition of Effective Java Chinese version

"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:

Publicenum 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:

Publicenum 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:

@ Testpublic 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 enumerations

The Pizza class can be rewritten with Java 8, and you can see how the methods lambda and Stream API make getAllUndeliveredPizzas () and

The groupPizzaByStatus () method has become so concise:

Public static List getAllUndeliveredPizzas (List input) {return input.stream () .filter ((s)->! deliveredPizzaStatuses.contains (s.getStatus () .Collectors.toList ();}

GroupPizzaByStatus ():

Publicstatic EnumMap groupPizzaByStatus (List pzList) {EnumMap map = pzList.stream (). Collect (Collectors.groupingBy (Pizza::getStatus, ()-> new EnumMap (PizzaStatus.class), Collectors.toList ()); return map;} 9. JSON representation 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) publicenum PizzaStatus {ORDERED (5) {@ Override public boolean isOrdered () {returntrue;}}, READY (2) {@ Override public boolean isReady () {returntrue;}}, DELIVERED (0) {@ Override public boolean isDelivered () {returntrue Privateint timeToDelivery; public boolean isOrdered () {returnfalse;} public boolean isReady () {returnfalse;} public boolean isDelivered () {returnfalse;} @ 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.

10. Summary

In this article, we discussed Java enumeration types, from basic knowledge to advanced applications and practical application scenarios, which made us feel the power of enumerations.

11. Supplement

As we mentioned above, we can make it more powerful by defining properties, methods, and constructors in enumerated types.

Let me show you through a practical example that there may be several different uses when we call SMS CAPTCHA, which we define as follows:

Publicenum PinType {REGISTER (100000, "registered use"), FORGET_PASSWORD (100001, "forget your password"), UPDATE_PHONE_NUMBER (100002, "Update Mobile number use"); privatefinalint code; privatefinal String message; PinType (int code, String message) {this.code = code; this.message = message;} public int getCode () {return code } public String getMessage () {return message;} @ Override public String toString () {return "PinType {" + "code=" + code + ", message='" + message +'\'+'}';}}

Actual use:

System.out.println (PinType.FORGET_PASSWORD.getCode ()); System.out.println (PinType.FORGET_PASSWORD.getMessage ()); System.out.println (PinType.FORGET_PASSWORD.toString ())

Output:

100001

Forget the password to use

PinType {code=100001, message=' forgot password to use'}

In this way, it will be very flexible and convenient to use in practice!

The above is all the contents of the article "how to use Java enumerations to improve productivity". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!

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.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report