Java Enums: Gathering Information from Another Enumeration

I made a similar question a few days ago, but now I have new requirements and new tasks =). As usual, I use animal enumerations for didactic purposes, as soon as I don't want to explain domain specific things

I have a basic animal enumeration that is used by the entire zoo (I can add material to it, but must maintain compatibility):

public enum Animal {
  DOG,
  ELEPHANT,
  WHALE,
  SHRIMP,
  BIRD,
  GIRAFFE;
}

I need to classify them into several unrelated categories, such as gray animals (whale (my gray whale) and elephant), small animals (bird, shrimp and dog), marine animals (whale and shrimp).

I could, as suggested in my previous questions, add a lot of logic elements such as isGray, isSmall and isFromSea, but I need an approach in which I could store this somewhere else (so my enumeration is not necessary know a lot). Sort of:

public enum Animal {
  DOG,
  ELEPHANT,
  WHALE,
  SHRIMP,
  BIRD,
  GIRAFFE;

  public boolean isGray() {
    // What comes here?
  }
}

Somewhere else

public enum GrayAnimal {
  WHALE,
  ELEPHANT;
}

How is this possible? Am I asking too much from Java?

+3
source share
6 answers

Have you tried EnumSet or EnumMap ?

You can create a method

Set<Animal> grayAnimals(){
   return EnumSet.of(Animal.WHALE, Animal.ELEPHANT);
}
+8
source

I think it would be better to store such properties in the enum instances themselves, i.e.

public enum Animal {
  DOG(NOT_GRAY),
  ELEPHANT(GRAY),
  WHALE(GRAY),
  SHRIMP(NOT_GRAY),
  BIRD(NOT_GRAY),
  GIRAFFE(NOT_GRAY);

  private static boolean GRAY = true;
  private static boolean NOT_GRAY = !GRAY;

  private Animal(boolean isGray) {
    // snip
  }
}

You can even encode multiple logical properties into one byte (or use BitSet instead);

public enum Animal {
  DOG(),
  ELEPHANT(GRAY | BIG),
  WHALE(GRAY | BIG),
  SHRIMP(),
  BIRD(),
  GIRAFFE(BIG);

  private static byte GRAY = 0x01;
  private static byte BIG = GRAY << 1;

  private final byte _value;

  private Animal() {
    this(0x00);
  }

  private Animal(byte value) {
    _value = value;
  }

  public boolean isGray() {
    return _value & GRAY != 0x00;
  }

  public boolean isBig() {
    return _value & BIG != 0x00;
  }
}

However, what to just do:

public class GrayAnimal {
  public static final Animal ELEPHANT = Animal.ELEPHANT;
  public static final Animal WHALE = Animal.WHALE;
}

-

public enum Animal {
  DOG,
  ELEPHANT,
  WHALE,
  SHRIMP,
  BIRD,
  GIRAFFE;

  // thanks to Mihir, I would have used a regular HashSet instead
  public static final Set<Animal> GRAY = Collections.unmodifiableSet(EnumSet.of(ELEPHANT, WHALE));
}
+2

, , - , , .

, , .

, , :

if(critter.type == WHALE)
    critter.movement=WATER;
else if(critter.type == ELEPHANT)

OO - - , OO).

, , .

- , whale.move() WaterMovement, LandMovement.

, OO .

, , " , , ".

+1

, , :

public boolean isGray() {
     return this == WHALE || this == ELEPHANT;
}
0

- :

package p;
import java.util.*;
enum Type {
    small,big,grey;
}
enum Animal {
    bird(EnumSet.of(Type.small)),whale(EnumSet.of(Type.big, Type.grey)),elephant(EnumSet.of(Type.big, Type.grey));
    Animal(final EnumSet<Type> types) { this.types=types; }
    EnumSet<Type> types=EnumSet.noneOf(Type.class);
    boolean is(final Type type) { return types!=null?types.contains(type):false; }
    public static void main(String[] arguments) {
        for(Animal a:values()) {
            System.out.println(a+" "+a.types);
        }
    }
}
0

I think it’s better not to pollute your enum with such categorization. It’s best to separate the categories from the listings so that you can add later versions without affecting your listings. This follows the section of problems and the principle of shared responsibility for class design.

To do this, simply use EnumSet to store instances, namely:

public enum Animal {
  DOG,
  ELEPHANT,
  WHALE,
  SHRIMP,
  BIRD,
  GIRAFFE;
}

public static final EnumSet<Animal> GRAY_ANIMALS = EnumSet.of(ELEPHANT, WHALE);

If you want to add functionality above simple membership or want more syntactic sugar to expand, EnumSet

public class GrayAnimals extends EnumSet<Animal> {
    public static final GrayAnimals INSTANCE = new GrayAnimals(ELEPHANT, WHALE);
    private GrayAnimals(Animal...animals) {
        Collections.addAll(this, animals);
    }
    public boolean isGray(Animal animal) { return contains(animal); }
    // ... other methods
}
0
source

Source: https://habr.com/ru/post/1738259/


All Articles