Java in EnumMap instead of ordinal index code detail

  • 2021-01-19 22:14:27
  • OfStack

This paper mainly studies the relevant content of EnumMap instead of ordinal index in Java, which is introduced as follows.

Effective Java Chinese Version 2

It is common to encounter the ordinal method of Enum to index enumerated types.


public class Herb {
  public enum Type { ANNUAL, PERENNIAL, BIENNIAL };
  private final String name;
  private final Type type;

  Herb(String name, Type type) {
    this.name = name;
    this.type = type;
  }

  @Override public String toString() {
    return name;
  }
}

Now suppose you have an array of herbs representing plants in a garden, and you want to list them by type (1-year, perennial, or biennial). To do this, you would build three collections, one for each type, and walk through the garden, placing each herb in the appropriate collection. Some programmers implement this point by putting these collections into an array indexed by the ordinal number of the type.


//Using ordinal() to index an array - DON'T DO THIS
Herb[] garden = ... ;

//Indexed by Herb.Type.ordinal()
Set<Herb>[] herbsByType = (Set<Herb>[])new Set[Herb.Type.values().length]; 
for(int i=0; i<herbsByType.length; i++) {
  herbsByType[i] = new HashSet<Herb>();
}

for(Herb h : garden) {
  herbsByType[h.type.ordinal()].add(h);
}

//Print the results
for(int i=0; i<herbsByType.length; i++) {
  System.out.printf("%s: %s%n", Herb.Type.values()[i], herbsByType[i]);
}

This approach works, but there are many problems. Because arrays are not compatible with generics. The program requires an unchecked transformation and does not compile correctly. Because the array does not know what its indexes represent, you must manually annotate the output of those indexes. But the most serious problem with this approach is that when you access an array that is indexed by the ordinal number of the enumeration, it is your responsibility to use the correct int value; int cannot provide the type safety of enumerations. If you use the wrong value, the program will quietly do the wrong job or, if you're lucky, throw an ArrayIndexOutOfBoundException exception.

java.util.EnumMap is a very fast Map implementation dedicated to enumerating keys.


//Using an EnumMap to associate data with an enum
Map<Herb.Type, Set<Herb>> herbsByType = new EnumMap<Herb.Type, 
Set<Herb>>(Herb.Type.class);

for(Herb.Type t : Herb.Type.values)
  herbsByType.put(t, new HashSet<Herb>());

for(Herb h : garden)
  herbsByType.get(h.type).add(h);

System.out.println(herbsByType);

This program is shorter, cleaner, and safer, and can run as fast as programs using Ordinal Numbers. It has no unsafe transitions; You don't have to manually annotate the output of these indexes because the mapping key knows how to translate itself into an enumeration of printable strings; It is also impossible to make an error when calculating an array index. The speed of EnumMap is comparable to ordinal indexed arrays because EnumMap uses them internally. But it hides this thought detail from the programmer, combining Map's rich features and type safety with the speed of arrays in one body. Note that the EnumMap constructor takes an Class object of key type: this is a restricted type token (bounded type token) that provides generics information at runtime.

conclusion

The above is this article about Java in EnumMap instead of ordinal index code detailed explanation of all content, I hope to help you. Interested friends can continue to refer to the site of other related topics, if there are shortcomings, welcome to leave a message to point out. Thank you for your support!


Related articles: