: Notebook: This article is filed under “blog”

: Keyboard: The sample code in this article is archived under: “Javacore”

Introduction to the

The full name of enum is enumeration, a feature introduced in JDK5.

In Java, a type decorated with the enum keyword is an enumerated type. The form is as follows:

enum ColorEn { RED, GREEN, BLUE }
Copy the code

Benefits of enumerations: Constants can be organized and managed uniformly.

Typical application scenarios of enumeration include error codes and state machines.

Nature of enumeration

Java. Lang. Enum class declaration

public abstract class Enum<E extends Enum<E>>
        implements Comparable<E>, Serializable {... }Copy the code

Create a new coloren.java file with the following contents:

package io.github.dunwu.javacore.enumeration;

public enum ColorEn {
    RED,YELLOW,BLUE
}
Copy the code

Run the javac coloren. Java command to generate the coloren. class file.

Then run the javap coloren. class command to output the following information:

Compiled from "ColorEn.java"
public final class io.github.dunwu.javacore.enumeration.ColorEn extends java.lang.Enum<io.github.dunwu.javacore.enumeration.ColorEn> {
  public static final io.github.dunwu.javacore.enumeration.ColorEn RED;
  public static final io.github.dunwu.javacore.enumeration.ColorEn YELLOW;
  public static final io.github.dunwu.javacore.enumeration.ColorEn BLUE;
  public static io.github.dunwu.javacore.enumeration.ColorEn[] values();
  public static io.github.dunwu.javacore.enumeration.ColorEn valueOf(java.lang.String);
  static {};
}
Copy the code

Bulbs: details:

As can be seen from the above example:

The essence of enumeration isjava.lang.EnumThe subclass.

Although enum may seem like a new data type, it is, in fact, a restricted class with its own methods. Enumerations are special classes that cannot inherit from other classes because they are modified to be final.

By default, the enumerated values defined are public static final. From the modifier keyword, you can see that the enumerated values are static constants in nature.

Method of enumeration

In enum, some basic methods are provided:

  • values(): Returns an array of instances of enum, and the elements in the array remain in the exact order in which they were declared in enum.
  • name(): Returns the instance name.
  • ordinal(): returns the order in which the instance was declared, starting from 0.
  • getDeclaringClass(): Returns the enum type of the instance.
  • equals(): Checks whether the objects are the same.

Enum instances can be compared using ==.

In addition, java.lang.enum implements the Comparable and Serializable interfaces, so it also provides the compareTo() method.

Example: Show the basic method of enum

public class EnumMethodDemo {
    enumColor {RED, GREEN, BLUE; }enumSize {BIG, MIDDLE, SMALL; }public static void main(String args[]) {
        System.out.println("=========== Print all Color ===========");
        for (Color c : Color.values()) {
            System.out.println(c + " ordinal: " + c.ordinal());
        }
        System.out.println("=========== Print all Size ===========");
        for (Size s : Size.values()) {
            System.out.println(s + " ordinal: " + s.ordinal());
        }

        Color green = Color.GREEN;
        System.out.println("green name(): " + green.name());
        System.out.println("green getDeclaringClass(): " + green.getDeclaringClass());
        System.out.println("green hashCode(): " + green.hashCode());
        System.out.println("green compareTo Color.GREEN: " + green.compareTo(Color.GREEN));
        System.out.println("green equals Color.GREEN: " + green.equals(Color.GREEN));
        System.out.println("green equals Size.MIDDLE: " + green.equals(Size.MIDDLE));
        System.out.println("green equals 1: " + green.equals(1));
        System.out.format("green == Color.BLUE: %b\n", green == Color.BLUE); }}Copy the code

The output

=========== Print all Color ===========
RED ordinal: 0
GREEN ordinal: 1
BLUE ordinal: 2
=========== Print all Size ===========
BIG ordinal: 0
MIDDLE ordinal: 1
SMALL ordinal: 2
green name(): GREEN
green getDeclaringClass(): class org.zp.javase.enumeration.EnumDemo$Color
green hashCode(): 460141958
green compareTo Color.GREEN: 0
green equals Color.GREEN: true
green equals Size.MIDDLE: false
green equals 1: false
green == Color.BLUE: false
Copy the code

Features of enumeration

The nature of enumerations boils down to one sentence:

Except that you can’t inherit, you can basically think of enum as a regular class.

But this sentence needs to be broken down to understand. Let’s break it down.

The basic features

If no method is defined in the enumeration, you can also add a comma, semicolon, or nothing after the last instance.

If no method is defined in the enumeration, the enumeration value defaults to an ordered value starting at 0. Take the Color enumeration type for example, whose enumeration constants are RED: 0, GREEN: 1, and BLUE: 2.

Enumerations can add methods

As mentioned in the Concepts section, enumeration values default to ordered values starting at 0. The problem then is how to assign an enumeration explicitly.

(1) Java does not allow the use of = to assign values to enumeration constants

If you’re familiar with C/C++, you’ll naturally think of the assignment symbol =. In C/C++, enum can be explicitly assigned to enumeration constants using the assignment symbol =; Unfortunately, Java syntax does not allow the use of the assignment symbol = to assign values to enumerated constants.

Example: enumeration declarations in C/C++

typedef enum {
    ONE = 1,
    TWO,
    THREE = 3,
    TEN = 10
} Number;
Copy the code

(2) Enumeration can add normal methods, static methods, abstract methods, constructors

While Java cannot assign to instances directly, it has a better solution: add methods to enums to implement explicit assignment indirectly.

When you create an enum, you can add multiple methods to it, and you can even add constructors to it.

Note one detail: if you define a method for an enum, you must add a semicolon to the end of the last instance of the enum. Also, in enUms, instances must be defined first, and fields or methods cannot be defined before instances. Otherwise, the compiler will report an error.

Example: How to define normal methods, static methods, abstract methods, constructors in enumeration

public enum ErrorCodeEn {
    OK(0) {
        @Override
        public String getDescription(a) {
            return "Success";
        }
    },
    ERROR_A(100) {
        @Override
        public String getDescription(a) {
            return "A wrong";
        }
    },
    ERROR_B(200) {
        @Override
        public String getDescription(a) {
            return "Error" B; }};private int code;

    // Constructor: Enum constructors can only be declared private or undeclared
    private ErrorCodeEn(int number) { // constructor
        this.code = number;
    }

    public int getCode(a) { // Common method
        return code;
    } // Common method

    public abstract String getDescription(a); // Abstract methods

    public static void main(String args[]) { // Static method
        for (ErrorCodeEn s : ErrorCodeEn.values()) {
            System.out.println("code: " + s.getCode() + ", description: "+ s.getDescription()); }}}// Output:
// code: 0, description: successful
// code: 100, description: error A
// code: 200, description: error B
Copy the code

Note: The above example is not desirable and is merely intended to show that enumerations support defining various methods. Correct example case error code example

Enumerations can implement interfaces

enumInterfaces can be implemented just like normal classes.

Also implementing the error code enumeration class in the previous section, you can constrain its methods by implementing an interface.

public interface INumberEnum {
    int getCode(a);
    String getDescription(a);
}

public enum ErrorCodeEn2 implements INumberEnum {
    OK(0."Success"),
    ERROR_A(100."A wrong"),
    ERROR_B(200."Error" B);

    ErrorCodeEn2(int number, String description) {
        this.code = number;
        this.description = description;
    }

    private int code;
    private String description;

    @Override
    public int getCode(a) {
        return code;
    }

    @Override
    public String getDescription(a) {
        returndescription; }}Copy the code

Enumerations cannot be inherited

An enum cannot inherit from another class, nor, of course, from another enum.

Because enums actually inherit from the java.lang. enum class, and Java does not support multiple inheritance, enums cannot inherit from other classes, and certainly cannot inherit from another enum.

Application of enumeration

Group constants

Before JDK5, constants defined in Java were public static final TYPE A; It looks like this. With enumerations, you can organize constants that are related to each other, making your code more readable, safer, and using the methods provided by enumerations.

The following three declarations are equivalent:

enum Color { RED, GREEN, BLUE }
enum Color { RED, GREEN, BLUE, }
enum Color { RED, GREEN, BLUE; }
Copy the code

The switch state machine

We often use switch statements to write state machines. After JDK7, the switch supports int, CHAR, String, and enum parameters. Switch code using enumerations is more readable than these types of parameters.

public class StateMachineDemo {
    public enum Signal {
        GREEN, YELLOW, RED
    }

    public static String getTrafficInstruct(Signal signal) {
        String instruct = "Signal light failure";
        switch (signal) {
            case RED:
                instruct = "Red light stop";
                break;
            case YELLOW:
                instruct = "Yellow light, please.";
                break;
            case GREEN:
                instruct = "Green light";
                break;
            default:
                break;
        }
        return instruct;
    }

    public static void main(String[] args) { System.out.println(getTrafficInstruct(Signal.RED)); }}// Output:
/ / stop
Copy the code

Error code

Enumerations are often used to define program error codes. Here is a simple example:

public class ErrorCodeEnumDemo {
    enum ErrorCodeEn {
        OK(0."Success"),
        ERROR_A(100."A wrong"),
        ERROR_B(200."Error" B);

        ErrorCodeEn(int number, String msg) {
            this.code = number;
            this.msg = msg;
        }

        private int code;
        private String msg;

        public int getCode(a) {
            return code;
        }

        public String getMsg(a) {
            return msg;
        }

        @Override
        public String toString(a) {
            return "ErrorCodeEn{" + "code=" + code + ", msg='" + msg + '\' ' + '} ';
        }

        public static String toStringAll(a) {
            StringBuilder sb = new StringBuilder();
            sb.append("ErrorCodeEn All Elements: [");
            for (ErrorCodeEn code : ErrorCodeEn.values()) {
                sb.append(code.getCode()).append(",");
            }
            sb.append("]");
            returnsb.toString(); }}public static void main(String[] args) {
        System.out.println(ErrorCodeEn.toStringAll());
        for(ErrorCodeEn s : ErrorCodeEn.values()) { System.out.println(s); }}}// Output:
// ErrorCodeEn All Elements: [0, 100, 200, ]
ErrorCodeEn{code=0, MSG =' success '}
ErrorCodeEn{code=100, MSG =' error A'}
ErrorCodeEn{code=200, MSG =' error B'}
Copy the code

Organize the enumeration

Enumerations of similar types can be organized through interfaces or classes, but they are generally organized in an interface fashion.

The reason is that Java interfaces automatically add the public static modifier to enum types when compiled. Java classes automatically add the static modifier to enum types when compiled. See the difference? That’s right, that is, organize the enum in the class, and if you don’t decorate it with public, then it can only be accessed in this package.

For example, organize the enum in the interface

public class EnumInInterfaceDemo {
    public interface INumberEnum {
        int getCode(a);
        String getDescription(a);
    }


    public interface Plant {
        enum Vegetable implements INumberEnum {
            POTATO(0."Potato"),
            TOMATO(0."Tomato");

            Vegetable(int number, String description) {
                this.code = number;
                this.description = description;
            }

            private int code;
            private String description;

            @Override
            public int getCode(a) {
                return this.code;
            }

            @Override
            public String getDescription(a) {
                return this.description; }}enum Fruit implements INumberEnum {
            APPLE(0.The word "apple"),
            ORANGE(0."Orange"),
            BANANA(0."Banana");

            Fruit(int number, String description) {
                this.code = number;
                this.description = description;
            }

            private int code;
            private String description;

            @Override
            public int getCode(a) {
                return this.code;
            }

            @Override
            public String getDescription(a) {
                return this.description; }}}public static void main(String[] args) {
        for(Plant.Fruit f : Plant.Fruit.values()) { System.out.println(f.getDescription()); }}}// Output:
/ / apple
/ / orange
/ / a banana
Copy the code

Example: Organize an enum in a class

This example has the same effect as the previous example.

public class EnumInClassDemo {
    public interface INumberEnum {
        int getCode(a);
        String getDescription(a);
    }

    public static class Plant2 {
        enum Vegetable implements INumberEnum {
            // Same as above
        }
        enum Fruit implements INumberEnum {
            // Same as above}}/ / a little
}
// Output:
/ / potato
/ / tomatoes
Copy the code

Strategy enumeration

An enumeration of policies is shown in Effective Java. This enumeration classifies enumeration constants by enumeration nested enumerations.

This approach is not as compact as the switch statement, but it is more secure and flexible.

Example: Example of policy enumeration in EffectvieJava

enum PayrollDay {
    MONDAY(PayType.WEEKDAY), TUESDAY(PayType.WEEKDAY), WEDNESDAY(
            PayType.WEEKDAY), THURSDAY(PayType.WEEKDAY), FRIDAY(PayType.WEEKDAY), SATURDAY(
            PayType.WEEKEND), SUNDAY(PayType.WEEKEND);

    private final PayType payType;

    PayrollDay(PayType payType) {
        this.payType = payType;
    }

    double pay(double hoursWorked, double payRate) {
        return payType.pay(hoursWorked, payRate);
    }

    // Policy enumeration
    private enum PayType {
        WEEKDAY {
            double overtimePay(double hours, double payRate) {
                return hours <= HOURS_PER_SHIFT ? 0 : (hours - HOURS_PER_SHIFT)
                        * payRate / 2;
            }
        },
        WEEKEND {
            double overtimePay(double hours, double payRate) {
                return hours * payRate / 2; }};private static final int HOURS_PER_SHIFT = 8;

        abstract double overtimePay(double hrs, double payRate);

        double pay(double hoursWorked, double payRate) {
            double basePay = hoursWorked * payRate;
            returnbasePay + overtimePay(hoursWorked, payRate); }}}Copy the code

test

System.out.println("How much a person earning 100 an hour would earn working 8 hours on a Friday:" + PayrollDay.FRIDAY.pay(8.0.100));
System.out.println("How much a person earning 100 an hour would earn working 8 hours on a Saturday:" + PayrollDay.SATURDAY.pay(8.0.100));
Copy the code

Enumeration implements the singleton pattern

The singleton pattern is the most common design pattern.

The singleton pattern has thread safety issues in concurrent environments.

For thread-safety issues, there are several traditional approaches:

  • Hungry loading
  • Synchronize and double check
  • Take advantage of Java’s static loading mechanism

Singletons can also be implemented using enumerations, and they are much simpler:

public class SingleEnumDemo {
    public enum SingleEn {

        INSTANCE;

        private String name;

        public String getName(a) {
            return name;
        }

        public void setName(String name) {
            this.name = name; }}public static void main(String[] args) {
        SingleEn.INSTANCE.setName("zp"); System.out.println(SingleEn.INSTANCE.getName()); }}Copy the code

Java Enumeration Types (Enum)

This article takes a close look at the features of Java enumeration, particularly the singleton and traditional singleton implementations of enumeration.

Enumeration utility class

Java provides two utility classes for manipulating enUms, EnumSet and EnumMap.

EnumSet

EnumSet is a high-performance Set implementation of enumeration types. It requires that the enumeration constants put into it be of the same enumeration type.

Main interface:

  • noneOf– Creates an empty EnumSet with the specified element type
  • allOf– Creates an EnumSet that specifies the element type and contains all enumeration values
  • range– Creates an EnumSet that contains elements from the specified range in the enumeration value
  • complementOf– The initial collection contains the complement of the specified collection
  • of– Create an EnumSet that contains all elements of the parameters
  • copyOf– Creates an EnumSet containing all the elements in the parameter container

Example:

public class EnumSetDemo {
    public static void main(String[] args) {
        System.out.println("Enumsets show");
        EnumSet<ErrorCodeEn> errSet = EnumSet.allOf(ErrorCodeEn.class);
        for (ErrorCodeEn e : errSet) {
            System.out.println(e.name() + ":"+ e.ordinal()); }}}Copy the code

EnumMap

EnumMap is a Map implementation tailored specifically for enumeration types. While other Map implementations (such as HashMap) can do enumeration type instance-to-value mapping, using EnumMap is more efficient: It can only accept instances of the same enumeration type as key values, and because the number of instances of enumeration types is relatively fixed and limited, EnumMap uses arrays to hold values corresponding to enumeration types. This makes EnumMap very efficient.

Main interface:

  • size– Returns the logarithm of key values
  • containsValue– Whether the specified value exists
  • containsKey– Whether the specified key exists
  • get– Obtains value based on the specified key
  • put– Retrieves the specified key-value pair
  • remove– Deletes the specified key
  • putAll– Batch fetch key/value pairs
  • clear– Clear data
  • keySet– Gets the key set
  • values– Returns all

Example:

public class EnumMapDemo {
    public enum Signal {
        GREEN, YELLOW, RED
    }

    public static void main(String[] args) {
        System.out.println("EnumMap show");
        EnumMap<Signal, String> errMap = new EnumMap(Signal.class);
        errMap.put(Signal.RED, "Red");
        errMap.put(Signal.YELLOW, "Yellow");
        errMap.put(Signal.GREEN, "Green light");
        for (Iterator<Map.Entry<Signal, String>> iter = errMap.entrySet().iterator(); iter.hasNext();) {
            Map.Entry<Signal, String> entry = iter.next();
            System.out.println(entry.getKey().name() + ":"+ entry.getValue()); }}}Copy the code

Java Enumeration Types (Enum)

EnumSet and EnumMap are introduced in detail in this article.

summary

The resources

  • Java Programming ideas
  • JAVA Core Technologies (Volume 1)
  • Effective java
  • In-depth understanding of Java enumeration types (EnUms)
  • Droidyue.com/blog/2016/1…