[JAVA] Enum review notes

Overview

This is a review memo of enum introduced from Java 1.5.

environment

reference

JDK review

Enum

sample

public enum Fruits {
  Apple,
  Banana,
  Cherry,
  Durian,
  Elderberry,
  Feijoa,
  Guava {
    @Override
    public String toString() {
      return name().toLowerCase();
    }
  };

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

}

name()

Returns the name of the enum constant. (Returns the name of this enum constant)

ordinal()

Returns the ordinal number (declared position) of the enumeration constant. (Returns the ordinal of this enumeration constant)

(Most of them are written as enum constants, but only the ordinal parts are written as enumeration constants.)

valueOf(String)

Returns the corresponding enum constant from the name of the enum constant. valueOf (String) is an implicit declaration method (public static) synthesized by the compiler.

values()

Returns all constants of enum type. values () is an implicit declaration method (public static) synthesized by the compiler.

equals()

When comparing enum constants, you usually use ==. The equals method of the Enum class is overridden as follows.

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

EnumSet

A special Set implementation for use with enums. All elements in an enum set must be explicitly or implicitly generated from a single enum type specified when the set is created.

Since there is no constructor, create an instance with the following factory method.

allOf(Class<E>)

Creates an EnumSet containing all enumerations of the specified enumeration type.

EnumSet<Fruits> all = EnumSet.allOf(Fruits.class);
System.out.println(all.size());
// → 7
all.forEach(System.out::println);
// → APPLE
// → BANANA
// → CHERRY
// → DURIAN
// → ELDERBERRY
// → FEIJOA
// → guava

noneOf()

Creates an empty EnumSet of the specified enum.

EnumSet<Fruits> none = EnumSet.noneOf(Fruits.class);
System.out.println(none.size());
// → 0
none.forEach(System.out::println);

of(E)

Creates an EnumSet that contains the specified enumerator first.

EnumSet<Fruits> one = EnumSet.of(Fruits.Durian);
System.out.println(one.size());
// → 1
one.forEach(System.out::println);
// → DURIAN

range(E, E)

Creates an EnumSet containing all enumerators within the range of the two specified enumerators.

EnumSet<Fruits> range = EnumSet.range(Fruits.Cherry, Fruits.Feijoa);
System.out.println(range.size());
// → 4
range.forEach(System.out::println);
// → CHERRY
// → DURIAN
// → ELDERBERRY
// → FEIJOA

EnumMap

A special Map implementation for use with enumerated keys. All keys in an enum map must be explicitly or implicitly generated from a single enum type specified when the map is created.

Unlike EnumSet, it uses a constructor to create an instance.

EnumMap​(Class<k>)

Creates an empty EnumMap of the specified enum.

EnumMap<Fruits, String> enumMap = new EnumMap<>(Fruits.class);
enumMap.put(Fruits.Apple, "Apple");
enumMap.put(Fruits.Banana, "banana");
enumMap.put(Fruits.Cherry, "Cherry");
enumMap.forEach((k, v) -> System.out.println(k + ":" + v));
// → APPLE:Apple
// → BANANA:banana
// → CHERRY:Cherry

EnumMap​(EnumMap<K,​? extends V> m)

Creates an EnumMap from the specified EnumMap. I will omit the code.

EnumMap​(Map<K,​? extends V> m)

Creates an EnumMap from the specified Map.

Map<Fruits, String> map = new HashMap<>();
map.put(Fruits.Apple, "Apple");
map.put(Fruits.Banana, "banana");
map.put(Fruits.Cherry, "Cherry");
EnumMap<Fruits, String> enumMap = new EnumMap<>(map);
enumMap.forEach((k, v) -> System.out.println(k + ":" + v));
// → APPLE:Apple
// → BANANA:banana
// → CHERRY:Cherry

Enhanced Enums

The enum extension (JEP 301: Enhanced Enums) under consideration by Project Amber of OpenJDK, but the current status (2019/01) is On Hold ( It has not been released yet because it is on hold).

Constant-specific method implementation

Declaring an abstract method with an enum type and overriding the abstract method for each enum constant in the constant-specific class body is called a constant-specific method implementation. (From "Effective Java 2nd Edition, Section 30 Using enums instead of int constants")

The following is an example of a constant-specific method implementation as seen in OSS.

Spring Boot

org.springframework.boot.convert.DurationStyle

https://github.com/spring-projects/spring-boot/blob/2.1.x/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/convert/DurationStyle.java

public enum DurationStyle {

  SIMPLE("^([\\+\\-]?\\d+)([a-zA-Z]{0,2})$") {
    @Override
    public Duration parse(String value, ChronoUnit unit) {
      // ...abridgement...
    }
    @Override
    public String print(Duration value, ChronoUnit unit) {
      // ...abridgement...
    }
  },
  ISO8601("^[\\+\\-]?P.*$") {
    @Override
    public Duration parse(String value, ChronoUnit unit) {
      //
    }
    @Override
    public String print(Duration value, ChronoUnit unit) {
      //
    }
  }

  private final Pattern pattern;

  DurationStyle(String pattern) {
    this.pattern = Pattern.compile(pattern);
  }

  public abstract Duration parse(String value, ChronoUnit unit);
  public abstract String print(Duration value, ChronoUnit unit);
}

Hibernate-ORM

org.hibernate.envers.query.criteria.MatchMode

https://github.com/hibernate/hibernate-orm/blob/5.3/hibernate-envers/src/main/java/org/hibernate/envers/query/criteria/MatchMode.java

public enum MatchMode {

  EXACT {
    @Override
    public String toMatchString(String pattern) {
      return pattern;
    }
  },
  START {
    @Override
    public String toMatchString(String pattern) {
      return pattern + '%';
    }
  },
  // ...abridgement...

  public abstract String toMatchString(String pattern);
}

org.hibernate.dialect.Database

https://github.com/hibernate/hibernate-orm/blob/5.3/hibernate-core/src/main/java/org/hibernate/dialect/Database.java

public enum Database {

  CACHE {
    // ...abridgement...
  },
  // ...abridgement...
  MYSQL {
    @Override
    public Class<? extends Dialect> latestDialect() {
      return MySQL57Dialect.class;
    }

    @Override
    public Dialect resolveDialect(DialectResolutionInfo info) {
      final String databaseName = info.getDatabaseName();

      if ( "MySQL".equals( databaseName ) ) {
        final int majorVersion = info.getDatabaseMajorVersion();
        final int minorVersion = info.getDatabaseMinorVersion();

        if ( majorVersion < 5 ) {
          return new MySQLDialect();
        }
        else if ( majorVersion == 5 ) {
          if ( minorVersion < 5 ) {
            return new MySQL5Dialect();
          }
          else if ( minorVersion < 7 ) {
            return new MySQL55Dialect();
          }
          else {
            return new MySQL57Dialect();
          }
        }

        return latestDialectInstance( this );
      }

      return null;
    }
  },
  ORACLE {
    // ...abridgement...
  }
  // ...abridgement...

  public abstract Class<? extends Dialect> latestDialect();
  public abstract Dialect resolveDialect(DialectResolutionInfo info);
}

elasticsearch

org.elasticsearch.common.unit.SizeUnit

https://github.com/elastic/elasticsearch/blob/6.6/server/src/main/java/org/elasticsearch/common/unit/SizeUnit.java

public enum SizeUnit {

  SINGLE {
    @Override
    public long toSingles(long size) {
      return size;
    }
    @Override
    public long toKilo(long size) {
      return size / (C1 / C0);
    }
    @Override
    public long toMega(long size) {
      return size / (C2 / C0);
    }
    @Override
    public long toGiga(long size) {
      return size / (C3 / C0);
    }
    @Override
    public long toTera(long size) {
      return size / (C4 / C0);
    }
    @Override
    public long toPeta(long size) {
      return size / (C5 / C0);
    }
  },
  KILO {
    // ...abridgement...
  },
  MEGA {
    // ...abridgement...
  },
  // ...abridgement...

  public abstract long toSingles(long size);
  public abstract long toKilo(long size);
  public abstract long toMega(long size);
  public abstract long toGiga(long size);
  public abstract long toTera(long size);
  public abstract long toPeta(long size);
}

org.elasticsearch.xpack.sql.expression.function.scalar.string.BinaryStringNumericProcessor

https://github.com/elastic/elasticsearch/blob/6.6/x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/string/BinaryStringNumericProcessor.java

public class BinaryStringNumericProcessor extends FunctionalBinaryProcessor<String, Number, String, BinaryStringNumericOperation> {

  public enum BinaryStringNumericOperation implements BiFunction<String, Number, String> {

    LEFT((s,c) -> {
      int i = c.intValue();
      if (i < 0) {
        return "";
      }
      return i > s.length() ? s : s.substring(0, i);
    }),
    RIGHT((s,c) -> {
      // ...abridgement...
    }),
    REPEAT((s,c) -> {
      // ...abridgement...
    });

    BinaryStringNumericOperation(BiFunction<String, Number, String> op) {
      this.op = op;
    }

    private final BiFunction<String, Number, String> op;

    @Override
    public String apply(String stringExp, Number count) {
      if (stringExp == null || count == null) {
        return null;
      }
      return op.apply(stringExp, count);
    }
  }

  // ...abridgement...
}

logback

ch.qos.logback.core.joran.spi.ConsoleTarget

https://github.com/qos-ch/logback/blob/1.1.11/logback-core/src/main/java/ch/qos/logback/core/joran/spi/ConsoleTarget.java

public enum ConsoleTarget {

  SystemOut("System.out", new OutputStream() {
    @Override
    public void write(int b) throws IOException {
      System.out.write(b);
    }
    @Override
    public void write(byte b[]) throws IOException {
      System.out.write(b);
    }
    @Override
    public void write(byte b[], int off, int len) throws IOException {
      System.out.write(b, off, len);
    }
    @Override
    public void flush() throws IOException {
      System.out.flush();
    }
  }),
  SystemErr("System.err", new OutputStream() {
    // ...abridgement...
  });

  private final String name;
  private final OutputStream stream;

  private ConsoleTarget(String name, OutputStream stream) {
    this.name = name;
    this.stream = stream;
  }

  // ...abridgement...
}

Recommended Posts

Enum review notes
Functional interface review notes
Java NIO 2 review notes
Review Swift enum types
Java Collections Framework Review Notes
Queue / BlockingQueue / TransferQueue review notes
Rails Review 1
JUnit 4 notes
Ruby Review 2
enum definition
Java review
About enum
java notes
Encapsulation review
[Java] enum
synchronized notes
Ruby Review 1
Rails Review 2
Review notes for Java 1.7 and later file copies