About Enumeration
Most of the enums written in the places are given an enum and then the example starts to switch. But I want to say that the data from my code is unlikely to be enums, usually strings or numbers. For example, after parsing a SQL, I first determine the SQL type. By intercepting the SQL token, the intercept may be SELECT, DELETE, UPDATE, INSERT, ALTER, etc., but they are all strings. At this time, I want to use enums, but I can't do it. How to convert the string into an enum? Similar situations include taking out data from the database and making judgments based on some types, passing data from the page, and doing different operations according to different types, but they are all strings, not enums. The tragedy is that I rarely see anyone writing this thing; so I wrote it down, hoping that someone can use it.
First of all, why use enumeration? When is it better to use enums? What are the advantages of using enums?
I think that when you are in some category classes and can enumerate and unchanged types to guide the program to route to different places, using enumeration is a better choice;
It sounds a bit confusing, but there is an example that might be understood, for example:
We can list the things we do on our daily working days:
Go to work, have meetings, eat, sleep, etc.
We can list the parts that need to be examined by the hospital's ENT department:
Eyes, nose, ears, mouth, etc.
These can be enumerated, and we have to do each of them in a different way;
Of course you can say:
1. It can be dispatched dynamically through configuration files or annotation;
2. Constants can be used to achieve similar effects;
3. Express it directly through the equals of the string, and express it with if else
If you use the configuration addition method to dispatch it, it is flexible and easy to modify; but if we use many parameters that are not modified frequently, we often increase the burden of configuration, and when you need to read the system logic, you need to read the configuration and code again; however, if the parameters are dynamically transformable information, using configuration is the correct choice;
The use of constants is usually numbers when switching cases, and strings cannot be switch cases in Java. The purpose of using constants increases readability than case 1 and case 2... but string data is also troublesome. Unless it is mapped again, there is no need. In fact, the enumeration is almost mapped for you once, but it just encapsulates the code. Since it has been done and syntactically supported, why not use it! Secondly, although constants increase readability, they do not have the concept of categories and management types. That is, an enum definition defines a category, which can list the things needed for this range well. Constants are usually some pools defined by themselves, placed in some public classes or defined randomly, and are relatively scattered. In addition, the enum is clearly defined when switching, and the case is within the range of the lock enumeration. It can not only control the system, increase readability, but also check which enum information in this category is at any time, so as to achieve the function of looking at configuration files; but it still returns In that sentence, if the parameters are variable, then it is not suitable for enumeration. Enumerations must be enumerable, or the current system considerations can be enumerated. For example, there may be many hospitals in the above hospital, but the current hospital only processes a few parts and does not process others. This is the reason. What is variable? For example, URL parameters are dispatched to the corresponding method. It is impossible for everyone to add a piece of logic and add an enumerator and a case. At this time, it is better to use [Configuration + Dynamic Method Dispatch]. Of course, the configuration can be just a file or annotation.
The most rustic thing is to use the string equals to implement it with if else. Haha, there is nothing wrong with this, but this is written in a scattered way. Secondly, each matching equals needs to be compared to each character every time you match the equals. If you loop a lot in your code, the performance is not very good, and the rest will be clearer after looking at the above description;
Secondly, enumeration provides a type management component, making the object-oriented system more perfect, so that some types of management can be configured and managed. Where enumeration is used, you can find the definition of enumeration that has been processed and has not been processed, and the above are difficult to achieve; for example, there are 10 types of operation types defined in databases, so in the process of determining, enumeration can be viewed like a configuration file, and it is very simple to manage.
Finally, enumeration is absolutely singleton, and the performance of comparison is comparable to that of digital performance, which can both obtain readability and performance.
Basic use of enum type
With such a theoretical basis, let’s take a look at the enum enum types in Java:
1. You can add variables and methods to enum
Let’s take a look at a code example:
public enum State { Normal("Normal", 1), Update("Updated", 2), Deleted("Deleted", 3), Fired("Masked", 4); // Member variable private String name; private int index; // Construct method, note: the constructor cannot be public, because enum cannot be instantiated private State(String name, int index) { this.name = name; this.index = index; } // Normal method public static String getName(int index) { for (State c : State .values()) { if (c.getIndex() == index) { return c.name; } } return null; } // get set method public String getName() { return name; } public void setName(String name) { this.name = name; } public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } }From the above code, we can see that after defining the enum value, then adding a semicolon to it, and then you can define other variables and methods. It should be noted in particular that the construction method in enum cannot be identified by public, so this is done to prevent the user from instantiating the enum.
2. Can be used to define constants
Let’s first review how to define constants in Java, and see the following code:
public static final int normalState = 1;private static final int updateState = 2;
Below we can also use enum enum to replace the above constant definition, the code is as follows:
public enum State { Normal, Update, Deleted, Fired}There is no syntax advantage in using enum to define constants in Java, but the enum enum type can provide more operational functions.
3. Implement interface in enum
Let’s first look at the following code:
public interface ICanReadState { void read(); String getState();} public enum State implements ICanReadState { Normal("Normal", 1), Update("Updated", 2), Deleted("Deleted", 3), Fired("Masked", 4); private String name; private int index; private State(String name, int index) { this.name = name; this.index = index; } // Interface method 1 @Override public String getState() { return this.name; } // Interface method 2 @Override public void read() { System.out.println(this.index + ":" + this.name); } }Just like using interfaces in general classes, the enum enum can also inherit the interface and implement all methods in the interface. The advantage of this is that it can more conveniently sort, compare and other operations on the values in the enum, and have better encapsulation.
Example
Let's first define a simple enum (here is just an example, so we will simply define 3 variables):
public enum SqlTypeEnum { INSERT , UPDATE , DELETE , SELECT}After parsing SQL, a token is obtained. How do we get the enumeration of this token?
Get it like this:
String token = "select";SqlTypeEnum sqlTypeEnum = SqlTypeEnum.valueOf(token.toUpperCase());
If not obtained, java will throw an exception: IllegalArgumentException No enum const class SqlTypeEnum.XXX
The reason I do capitalization is because enums are also capitalized (of course, if your enum is lowercase, then you are lowercase, but it is more troublesome to mix it up). In fact, valueOf calls the underlying mapping of the enum:
This method will be called when calling:
So there is also a HashMap inside, haha!
After getting this information, you can do the desired operation:
switch(sqlTypeEnum) { case INSERT: handle insert logic; break; case DELETE: handle delete logic; break; ....}OK, sometimes we may not want to use strings like INSERT or UPDATE directly in interaction, because many times the naming specifications are required;
For example, define some user action types:
1. Save user information
2. Obtain basic user information through ID
3. Get the user list
4. Delete user information through ID
etc.
We may define enumerations as:
public enum UserOptionEnum { SAVE_USER, GET_USER_BY_ID, GET_USER_LIST, DELETE_USER_BY_ID}However, the system methods and some keyword configurations are usually written as:
saveUser, getUserById, getUserById, deleteUserById
Of course, each has its own rules, but if you don’t want to do the mapping in the middle, you just compromise on it. Either replace all the enum names, which seems quite strange, or replace all the method names, which is even more strange, or you can do the mapping yourself. OK, it’s a little more troublesome, but it’s actually not troublesome?
Let's first write a method to convert enumerated underscore-style data to camels and put it in a StringUtils:
public static String convertDbStyleToJavaStyle(String dbStyleString , boolean firstUpper) { dbStyleString = dbStyleString.toLowerCase(); String []tokens = dbStyleString.split("_"); StringBuilder stringBuilder = new StringBuilder(128); int length = 0; for(String token : tokens) { if(StringUtils.isNotBlank(token)) { if(length == 0 && !firstUpper) { stringBuilder.append(token); }else { char c = token.charAt(0); if(c >= 'a' || c <= 'z') c = (char)(c - 32); stringBuilder.append(c); stringBuilder.append(token.substring(1)); } } ++length; } return stringBuilder.toString(); }Overload a method:
public static String convertDbStyleToJavaLocalStyle(String dbStyleString) { return convertDbStyleToJavaStyle(dbStyleString, false); }Then define the enum:
public enum UserOptionEnum { SAVE_USER, GET_USER_BY_ID, GET_USER_LIST, DELETE_USER_BY_ID; private final static Map<String , UserOptionEnum> ENUM_MAP = new HashMap<String, UserOptionEnum>(64); static { for(UserOptionEnum v : values()) { ENUM_MAP.put(v.toString() , v); } } public staticUserOptionEnum fromString(String v) { UserOptionEnum userOptionEnum = ENUM_MAP.get(v); return userOptionEnum == null ? DEFAULT :userOptionEnum; } public String toString() { String stringValue = super.toString(); return StringUtil.convertDbStyleToJavaLocalStyle(stringValue); }}OK, pass an event parameter like this so that if it is: saveUser, use:
String event = "saveUser";//If you get the parameter UserOptionEnum enum = UserOptionEnum.fromString(event);
In fact, I made a hashMap myself, and I added a fromString because there are some restrictions on enumeration and some methods do not allow you to overwrite, such as the valueOf method.
Actually, there is nothing to say. Let’s talk about adding some custom variables to enums. In fact, except for being a singleton, the other enums are similar to ordinary classes. They can also have constructor methods, but not by default. They can also provide custom variables and then obtain set and get methods. However, if there is set, the thread is not safe, so pay attention to this point; so the construction method is generally written:
public enum SqlTypeEnum { INSERT("insert into"), DELETE("delete from") ......Omitted; private String name;//Define custom variable private SqlTypeEnum(String name) { this.name = name; } public String getName() { return name; } public String toString() { return name + "I dash";//Rewrite the toString method} //Generally not recommended public void setName(String name) { this.name = name; }}Called:
SqlTypeEnum sqlTypeEnum = SqlTypeEnum.valueOf("INSERT");System.out.println(sqlTypeEnum);System.out.println(sqlTypeEnum.getName());It is not recommended to call it:
sqlTypeEnum.setName("Damn");In another thread:
SqlTypeEnum sqlTypeEnum = SqlTypeEnum.valueOf("INSERT");System.out.println(sqlTypeEnum);System.out.println(sqlTypeEnum.getName());I found that the result was changed, haha!