Chapter 19 Enumerated Types


Insert picture description here
The keyword enum can create a limited set of named values ​​as a new type, and these named values ​​can be used as regular program components

1. Basic enum characteristics
  1. When creating enum, the compiler will generate a related class for you, this class inherits from java.lang.Enum

  2. method
  • values(): returns an array of enum instances in the order declared in the enum
  • ordinal(): The order of every enum instance in declaration
  • getDeclaringClass(): Return to the enum class
  • name(): Returns the name of the enum instance when it was declared
  • ValueOf(): Returns the corresponding enum instance according to the given name, if there is no instance with the given name, an exception will be thrown
  1. Use static imports for enum
  • import static enumerated.Spiciness.*;
2. Add a new method to enum
  1. In addition to not inheriting from an enum, we can basically regard enum as a regular class

  2. If you plan to define your own method, you must add a semicolon at the end of the enum instance sequence. At the same time Java requires you to define enum instance first (see Chapter19\Example01\OzWitch.java)

  3. Using static import can substitute the identifier of the enum instance into the current namespace, so there is no need to modify the enum instance with enum.

  4. Constructors and methods in enum are no different from ordinary classes, because aside from a few restrictions, enum is an ordinary class

  5. Method of covering enum
  • (1) Override the toString() method, which provides us with another way to generate different string description information for enumeration instances
  • (2) The toString() method of overriding enum is no different from overriding the general method
3. enum in switch statement
package Chapter19.Example02;//: enumerated/TrafficLight.java
// Enums in switch statements.
import static net.mindview.util.Print.*;

// Define an enum type:
enum Signal {
    
     GREEN, YELLOW, RED, }

public class TrafficLight {
    
    
  Signal color = Signal.RED;
  public void change() {
    
    
    switch(color) {
    
    
      // Note that you don't have to say Signal.RED
      // in the case statement:
      case RED:    color = Signal.GREEN;
                   break;
      case GREEN:  color = Signal.YELLOW;
                   break;
      case YELLOW: color = Signal.RED;
                   break;
    }
  }
  public String toString() {
    
    
    return "The traffic light is " + color;
  }
  public static void main(String[] args) {
    
    
    TrafficLight t = new TrafficLight();
    for(int i = 0; i < 7; i++) {
    
    
      print(t);
      t.change();
    }
  }
} /* Output:
The traffic light is RED
The traffic light is GREEN
The traffic light is YELLOW
The traffic light is RED
The traffic light is GREEN
The traffic light is YELLOW
The traffic light is RED
*///:~
  1. Using enum in switch is a very convenient function provided by enum
4.The mystery of value()
  • value() is a static method added by the compiler
5. Realization, not inheritance
  1. All enum are inherited from java.lang.Enum class. Since Java does not support multiple inheritance, your enum can no longer inherit other classes
  2. When we create a new enum, one or more interfaces can be implemented at the same time
6. Random selection
  1. We can use generics to make this work more general
  2. <T extends Enum> T is an enum instance
package Chapter19.Example03;

import java.util.Random;

public class Enums {
    
    
    private static Random rand = new Random(47);

    public static <T extends Enum<T>> T random(Class<T> ec) {
    
    
        return random(ec.getEnumConstants());
    }

    public static <T> T random(T[] values) {
    
    
        return values[rand.nextInt(values.length)];
    }
}

7. Use interfaces to organize enumerations
  1. Inside an interface, create an enumeration that implements the interface to group elements to achieve the purpose of classifying and organizing enumerated elements
//: enumerated/menu/Meal2.java
package Chapter19.Example04;
import net.mindview.util.*;

public enum Meal2 {
    
    
  APPETIZER(Food.Appetizer.class),
  MAINCOURSE(Food.MainCourse.class),
  DESSERT(Food.Dessert.class),
  COFFEE(Food.Coffee.class);
  private Food[] values;
  private Meal2(Class<? extends Food> kind) {
    
    
    values = kind.getEnumConstants();
  }
  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 {
    
    
      TIRAMISU, GELATO, BLACK_FOREST_CAKE,
      FRUIT, CREME_CARAMEL;
    }
    enum Coffee implements Food {
    
    
      BLACK_COFFEE, DECAF_COFFEE, ESPRESSO,
      LATTE, CAPPUCCINO, TEA, HERB_TEA;
    }
  }
  public Food randomSelection() {
    
    
    return Enums.random(values);
  }
  public static void main(String[] args) {
    
    
    for(int i = 0; i < 5; i++) {
    
    
      for(Meal2 meal : Meal2.values()) {
    
    
        Food food = meal.randomSelection();
        System.out.println(food);
      }
      System.out.println("---");
    }
  }
} /* Same output as Meal.java *///:~
8. Use EnumSet instead of flags
  1. EnumSet is to create a substitute for enum to replace the traditional "bit flag" based on int. These signs can be used to indicate some kind of "on/off" information
  2. The advantage of using EnumSet is: it has better expressive ability when it shows whether a binary bit exists, and there is no need to worry about performance
  3. The basis of EnumSet is long. When there are more than 64 elements, a long will be added
9. Use EnumMap
  1. EnumMap is a special map, it requires the key (key) must come from an enum
  2. EnumMap allows programmers to change value objects
10. Constant-related methods
  1. To implement constant-related methods, you need to define one or more abstract methods for enum, and then implement the abstract method for each enum instance
  2. We can't really use enum instance as a type
  3. Use enum chain of responsibility
  • In the chain of responsibility design pattern, programmers solve a problem in many different ways and then link them together. When a request comes, it traverses the chain until a solution in the chain can handle the request
  1. State machine using enum
  • A state machine can have a limited number of specific states. It usually transitions from one state to the next based on the input, but there may also be transient states, and once the task execution ends, the state machine will immediately leave the transient state
11. Multiplexing
  1. Java only supports one-way distribution: if the operation to be performed is more than one object of unknown type, then Java's dynamic binding mechanism can only handle one of the types
  2. To configure a good multi-channel distribution requires a lot of processes, but remember that its advantage lies in the elegant syntax of method calls, which avoids the ugly code that determines the types of multiple objects in one method
//: enumerated/RoShamBo1.java
// Demonstration of multiple dispatching.
package Chapter19.Example05;
import java.util.*;

import static Chapter19.Example05.Outcome.*;

interface Item {
    
    
  Outcome compete(Item it);
  Outcome eval(Paper p);
  Outcome eval(Scissors s);
  Outcome eval(Rock r);
}

class Paper implements Item {
    
    
  public Outcome compete(Item it) {
    
     return it.eval(this); }
  public Outcome eval(Paper p) {
    
     return DRAW; }
  public Outcome eval(Scissors s) {
    
     return WIN; }
  public Outcome eval(Rock r) {
    
     return LOSE; }
  public String toString() {
    
     return "Paper"; }
}	

class Scissors implements Item {
    
    
  public Outcome compete(Item it) {
    
     return it.eval(this); }
  public Outcome eval(Paper p) {
    
     return LOSE; }
  public Outcome eval(Scissors s) {
    
     return DRAW; }
  public Outcome eval(Rock r) {
    
     return WIN; }
  public String toString() {
    
     return "Scissors"; }
}

class Rock implements Item {
    
    
  public Outcome compete(Item it) {
    
     return it.eval(this); }
  public Outcome eval(Paper p) {
    
     return WIN; }
  public Outcome eval(Scissors s) {
    
     return LOSE; }
  public Outcome eval(Rock r) {
    
     return DRAW; }
  public String toString() {
    
     return "Rock"; }
}	

public class RoShamBo1 {
    
    
  static final int SIZE = 20;
  private static Random rand = new Random(47);
  public static Item newItem() {
    
    
    switch(rand.nextInt(3)) {
    
    
      default:
      case 0: return new Scissors();
      case 1: return new Paper();
      case 2: return new Rock();
    }
  }
  public static void match(Item a, Item b) {
    
    
    System.out.println(
      a + " vs. " + b + ": " +  a.compete(b));
  }
  public static void main(String[] args) {
    
    
    for(int i = 0; i < SIZE; i++)
      match(newItem(), newItem());
  }
} /* Output:	
Rock vs. Rock: DRAW
Paper vs. Rock: WIN
Paper vs. Rock: WIN
Paper vs. Rock: WIN
Scissors vs. Paper: WIN
Scissors vs. Scissors: DRAW
Scissors vs. Paper: WIN
Rock vs. Paper: LOSE
Paper vs. Paper: DRAW
Rock vs. Paper: LOSE
Paper vs. Scissors: LOSE
Paper vs. Scissors: LOSE
Rock vs. Scissors: WIN
Rock vs. Paper: LOSE
Paper vs. Rock: WIN
Scissors vs. Paper: WIN
Paper vs. Scissors: LOSE
Paper vs. Scissors: LOSE
Paper vs. Scissors: LOSE
Paper vs. Scissors: LOSE
*///:~
package Chapter19.Example05;
public enum Outcome {
    
     WIN, LOSE, DRAW } ///:~
  1. Use enum distribution
  • The enum instance is not a type, and the enum instance cannot be used as a parameter type, so the eval() method cannot be overloaded
  • One way is to use the constructor to initialize each enum instance and take a "set of" results as parameters. The two are put together to form a structure similar to the query table
  1. Use constant related methods
  • Although enum instances can have different behaviors, they are still not types and cannot be used as parameter types in method signatures. The best way is to use enum in the switch statement
  1. Use EnumMap to distribute
  • Use EnumMap to achieve "true" two-way distribution
  1. Use a two-dimensional array
  • Due to the use of arrays, this method is not "safe"

Guess you like

Origin blog.csdn.net/Tianc666/article/details/108976804