Enumeration in Java

1, What is enumeration?

Enumeration is to enumerate one by one. It is often used to express those collections that can be clearly defined, such as gender, season, week, month, direction (East, West, North and South), etc.

So the use scenario of enumeration is: when variables (especially parameters of methods) can only take one from a group of possible values, we can use enumeration.

enum in Java is a special data type, which is a new feature in Java 5.

Note here that enum is a class, its full name is Enumeration, but there is also an Enumeration interface in Java, and there is no relationship between the two.

2, Why does enumeration occur?

Suppose we need to describe four directions for orientation, let's look at the following program, which is a common way to define constants when there is no enumeration type:

public enum Directions {
  NORTH, SOUTH, EAST, WEST
}

It looks good. When calling, just use Directions.NORTH. However, the enumeration implemented by this constant has many disadvantages:

  • Unsafe type

    The corresponding value of the direction constant we defined above is an integer. When the program is running, it is likely that an illegal parameter (inconsistent type) will be passed in.

  • No namespace

    Since the direction constant is only a property of a class, it has to be accessed through the class.

  • Poor consistency

    The integer constant we defined above belongs to the compile time constant. That is to say, after the compilation of the program, all references to the constant will directly write the integer value. In this way, when you modify the old integer value or add a new constant, all code in the reference area needs to be recompiled, otherwise an error will be reported.

Therefore, in order to solve these problems, enumeration types are provided in Java 5 for developers to use.

3, Definition and use of enumeration

1. Definition of enumeration

enum keyword added in Java 5 to define enumeration type.

public enum Directions {
  NORTH, SOUTH, EAST, WEST
}

We can call it as follows:

Directions direct = Directions.WEST;

In terms of definition form, enumeration types in Java are very simple, but in fact, the function of enumeration types given by java language specification is very powerful. Let's take an example to explain in detail.

2. Using in if else statements

public enum Directions {
  NORTH, SOUTH, EAST, WEST
}

public class IfElseEnum {
  public static void main(String[] args) {
    Directions direct;
    direct = Directions.WEST;
    getDirection(direct);
  }

  public static void getDirection(Directions dir) {
    if (dir == Directions.WEST)
      System.out.println("You selected WEST !!"); // code goes here.
    else
      System.out.println("Invalid Direction !!");
  }
}

3. Use in switch statement

public enum Directions {
  NORTH, SOUTH, EAST, WEST
}

public class SwitchCaseEnum {
  public static void main(String[] args) {
    Directions direct;
    direct = Directions.WEST;
    switch (direct) {
      case NORTH:
        System.out.println("You chose NORTH!");
        break;
      case SOUTH:
        System.out.println("You chose SOUTH!");
        break;
      case EAST:
        System.out.println("You chose EAST!");
        break;
      case WEST:
        System.out.println("You chose WEST!"); // code goes here.
        break;
      default:
        System.out.println("Invalid Direction....!!");
        break;
    }
  }
}

Compared with the previous constant implementation of enumeration, we can write a lot of if statements less and the code is more readable

4. Use in for loop

public enum Directions {
  NORTH, SOUTH, EAST, WEST
}

public class LoopEnum {
  public static void main(String[] args) {
    int flag = 1;
    for (Directions dir : Directions.values()) {
      System.out.printf("Direction -> %d = %s\n", flag++, dir);
    }
  }
}

The values() method is a static method of the enumeration class, which returns an array containing all enumeration values.

4, Methods of enumerating classes

All enumeration classes inherit Enum methods, which are described in detail below.

1. Coordinate() method

This returns the order of the enumeration values in the enumeration class, which depends on the order in which the enumeration values are declared.

enum Directions {
  NORTH, SOUTH, EAST, WEST
}

public class Main {
  public static void main(String[] args) {
    System.out.println(Directions.EAST.ordinal()); // 2
  }
}

2. values() method

This is a static method that returns an array of all enumeration values.

public enum Directions {
  NORTH, SOUTH, EAST, WEST
}

public class LoopEnum {
  public static void main(String[] args) {
    int flag = 1;
    for (Directions dir : Directions.values()) {
      System.out.printf("Direction -> %d = %s\n", flag++, dir);
    }
  }
}

3. toString() method

This method returns the name of the enumeration constant.

public class Main {
  public static void main(String[] args) {
    Directions dir = Directions.EAST;
    System.out.println(dir.toString());
  }
}

4. valueOf() method

This method corresponds to toString method and returns enumeration constant of specified enumeration type with specified name.

System.out.println(Directions.valueOf("EAST")); // EAST

5. equals() method

A reference used to compare two enumeration class objects.

public enum Directions {
  NORTH, SOUTH, EAST, WEST
}

public class Main {
  public static void main(String[] args) {
    Directions d1 = Directions.EAST;
    Directions d2 = Directions.EAST;
    Directions d3 = Directions.WEST;
    System.out.println("d1 == d2: " + (d1 == d2)); // d1 == d2: true
    System.out.println("d1.equals(d2): " + (d1.equals(d2))); // d1.equals(d2): true

    System.out.println("d1 == d3: " + (d1 == d3)); // d1 == d3: false
    System.out.println("d1.equals(d3): " + (d1.equals(d3))); // d1.equals(d3): false
  }
}

In the Enum class, the equals method has been overridden, and the comparison in the method directly uses = = to compare two objects, so the results are the same. Here is the source code of equals:

public final boolean equals(Object other) {
	return this==other;
}

6. getDeclaringClass() method

Directions d = Directions.EAST;
System.out.println(d.getDeclaringClass()); // class Directions

5, Advanced use of enumeration

As with ordinary classes in Java, while enumerating classes are declared, properties, methods and constructors can also be declared. However, there are some limitations.

1. Constructor of enumeration class

The constructor of an enumeration class must be private. When the constructor is written in IDE, it is private automatically. This is the default. If you delete private, you will not report an error. Therefore, we generally do not need to write the private modifier explicitly. It is redundant. This can be verified by looking at the compiled code.

So why must the constructor of an enumeration class be private?

When explaining the private modifier, we mentioned that * * the private constructor serves the singleton pattern. **Here we will introduce the concept of single case mode:

A class can not be instantiated into an object. It is responsible for creating its own object and ensuring that only a single object is created. Moreover, this class provides a way to access its unique object, which can be accessed directly through the class. This pattern is called singleton pattern, and this class is called singleton class.

In development, there are many objects that we only need, such as thread pool, cache, default setting, registry, log object, etc. at this time, it is the best choice to design it as a singleton mode.

The enumeration is designed as a singleton mode, that is, when the enumeration type is loaded by the JVM, we define how many enumeration values in the enumeration class, and how many enumeration objects will be instantiated. In order to ensure that each enumeration class object is the only instance, the JVM does not allow external instantiation (using new), so it will design the constructor as private to prevent users from using it Generate instance, destroy uniqueness.

**All enumeration values of the enumeration class are enumeration objects that the JVM will instantiate. **Note here: the enumeration value must be explicitly listed in the first row of the enumeration class, otherwise the enumeration class will never produce an instance.

Let's take a comprehensive example:

enum Directions {
  NORTH(0, 90), SOUTH(0, -90), EAST(90, 0), WEST(-90, 0); // Notice the semicolon here

  private int x;
  private int y;

  Directions(int x, int y) {
    this.x = x;
    this.y = y;
  }

  public int getX() {
    return x;
  }

  public int getY() {
    return y;
  }
}

public class Main {
  public static void main(String[] args) {
    System.out.println("Here is the coordinate mark of orientation information");
    for (Directions dir : Directions.values()) {
      System.out.println("Azimuth name: " + dir.name() + ", Coordinate marking: " + "(" + dir.getX() + ", " + dir.getY() + ")");
    }
  }
}

The output result is:

Bearing name: NORTH, coordinate mark: (0, 90)
Bearing name: SOUTH, coordinate mark: (0, - 90)
Bearing name: EAST, coordinate mark: (90, 0)
Azimuth Name: WEST, coordinate mark: (- 90, 0)

2. Override toString() method

We can also override the toString() method of the enumeration class:

enum Directions {
  NORTH(0, 90), SOUTH(0, -90), EAST(90, 0), WEST(-90, 0);

  private int x;
  private int y;

  Directions(int x, int y) {
    this.x = x;
    this.y = y;
  }

  public int getX() {
    return x;
  }

  public int getY() {
    return y;
  }

  @Override
  public String toString() {
    return "(" + this.x + ", " + this.y + ")";
  }
}

public class Main {
  public static void main(String[] args) {
    System.out.println("Here is the coordinate mark of orientation information");
    for (Directions dir : Directions.values()) {
      System.out.println("Azimuth name: " + dir.name() + ", Coordinate marking: " + dir.toString());
    }
  }
}

3. Implementation interface

All enumerations are inherited from java.lang.Enum class. Because Java does not support multiple inheritance, enumeration objects can no longer inherit other classes. But enumerations can implement interfaces.

// Interface
public interface Behaviour {
  void print();

  String getInfo();
}

// Enumeration class
public enum Color implements Behaviour {
  RED("Red", 1), GREEN("green", 2), BLANK("white", 3), YELLO("yellow", 4);
  private String name;
  private int index;

  Color(String name, int index) {
    this.name = name;
    this.index = index;
  }

  @Override
  public String getInfo() {
    return this.name;
  }

  @Override
  public void print() {
    System.out.println(this.index + ":" + this.name);
  }
}

4. Using interfaces to organize enumerations

Sometimes, we need to extend the elements in the original enum, or we want to use subclasses to group the elements in an enum. At this time, we can create and implement enumeration within an interface to group the elements and achieve the purpose of classifying and organizing enumeration elements.

For example, suppose we want to use enum to represent different kinds of Food, and at the same time we want each enum element to remain Food type. Then we can achieve this:

public interface Food {
  enum Appetizer implements Food {
    SALAD, SOUP, SPRING_ROLLS;
  }

  enum MainCourse implements Food {
    LASAGNE, BURRITO, PAD_THAI, LENTILS, HUMMOUS, VINDALOO;
  }

  enum Dessert implements Food {
    TIRAMISSU, GELTO, BLACK_FOREST_CAKE, FRUIT, CREAM_CARAMEL;
  }

  enum Coffee implements Food {
    BLACK_COFFEE, DECAF_COFFEE, ESPRESSO, LATTE, CAPPUCCINO, TEA, HERB_TEA;
  }
}

public class InterfaceOrganizeEnum {
  public static void main(String[] args) {
    Food food = Food.Appetizer.SALAD;
    food = Food.MainCourse.LASAGNE;
  }
}

For enum, implementing an interface is the only way to subclass it. So every enum embedded in Food implements the Food interface. Now, in the main method, the enum type that implements the Food interface can be used, so we can transform the example to Food, so all the things in the example above are Food.

5. On the use of enumeration collection

java.util.EnumSet and java.util.EnumMap are two enumeration sets.

  • EnumSet ensures that the elements in the set are not repeated;

  • The key in EnumMap is of enum type, while value can be of any type.

The use of these two sets will not be described here. Please refer to the JDK documentation.

Published 12 original articles, praised 0, visited 27
Private letter follow

Tags: Java jvm less JDK

Posted on Fri, 14 Feb 2020 06:30:59 -0500 by delldeveloper