给定参数的枚举值

时间:2013-02-21 15:16:02

标签: java enums

是否有任何基于另外两种枚举类型检索枚举值的美学方法?我想做的是获得两个枚举参数的状态,如下面的例子:

public enum State{

ONE_STATE,
SECOND_STATE;
THIRD_STATE;

public static State getState(Direction dir, Type type) {
    if (dir.equals(Direction.LEFT) && type.equals(Type.BIG)) {
        return ONE_STATE;
    }
    else if (dir.equals(Direction.RIGHT) && type.equals(Type.SMALL)) {
        return SECOND_STATE;
    }
    else if (dir.equals(Direction.UP) && type.equals(Type.SMALL)) {
        return FIRST_STATE;
    }
    return THIRD_STATE;
}

}

当然这会说明,但我的目的是让事情变得更清楚,因为这些可能性的数量会随着时间而增长。

6 个答案:

答案 0 :(得分:0)

为什么不使用查找表?行数组 - 每行包含2个输入和1个输出。

LEFT,  BIG,   ONE_STATE
RIGHT, SMALL, SECOND_STATE

等。并提供一种方法来查找并在查找失败时返回默认值。

如果不这样做,您可以调查double dispatch

答案 1 :(得分:0)

枚举可以包含字段,您可以尝试以下内容:

public enum State {
    ONE_STATE(Direction.LEFT, Type.BIG),
    ...

    Direction d;
    Type t;

    private State(Direction d, Type t) {
        ...
    }

    public static State getState(Direction d, Type t) {
        for (State s : State.values()) {
            if (s.d == d && s.t == t) {
                return s;
            }
        }
        return null;
    }
}

答案 2 :(得分:0)

如何将Direction和Type作为枚举的成员,如下所示:

public enum State {

    ONE_STATE(Direction.LEFT, Type.BIG),
    SECOND_STATE(Direction.RIGHT, Type.SMALL);
    THIRD_STATE(Direction.UP, Type.SMALL);

    private Direction direction;
    private Type type;

    private State(Direction direction, Type type) {
        this.direction = direction;
        this.type = type;
    }

    public static State getState(Direction dir, Type type) {
        for (State state : values()) {
            if (state.direction == dir && state.type == type) {
                return state;
            }
        }
        return THIRD_STATE;
    }
}

请注意,如果每个枚举有多个不同的组合,则无法使用此功能。在这种情况下,您将需要使用另一张海报建议的某种查找表。例如,您可以使用Map<Pair<Direction, Type>, State>。 (Java没有Pair<T, U>类,但您可以轻松地创建一个或在许多不同的库中找到一个。)

答案 3 :(得分:0)

您可以使用switch es代替if,但这不会缩短代码。它具有更清晰的优势,而且,根据您的IDE,您可以在switch缺少案例时让错误。

包含最多项的枚举为外switch而其他内容为switch

仅当Stateenum的一个组合“达到”Direction时,才会向Type State添加字段。

switch(dir) {
  case LEFT:
  {
    switch(type) {
      case BIG:
      ...

答案 4 :(得分:0)

使用嵌套的EnummMap。 “Effective Java”一书(第33项)解释了为什么这是最好的解决方案。

// Using a nested EnumMap to associate data with enum pairs
public enum Phase {
    SOLID, LIQUID, GAS;
    public enum Transition {
        MELT(SOLID, LIQUID), FREEZE(LIQUID, SOLID),
        BOIL(LIQUID, GAS), CONDENSE(GAS, LIQUID),
        SUBLIME(SOLID, GAS), DEPOSIT(GAS, SOLID);
        final Phase src;
        final Phase dst;
        Transition(Phase src, Phase dst) {
            this.src = src;
            this.dst = dst;
        }
        // Initialize the phase transition map
        private static final Map<Phase, Map<Phase,Transition>> m =
                new EnumMap<Phase, Map<Phase,Transition>>(Phase.class);
        static {
            for (Phase p : Phase.values())
                m.put(p,new EnumMap<Phase,Transition>(Phase.class));
            for (Transition trans : Transition.values())
                m.get(trans.src).put(trans.dst, trans);
        }
        public static Transition from(Phase src, Phase dst) {
            return m.get(src).get(dst);
        }
    }
}

答案 5 :(得分:0)

您可以将DIRECTIONTYPE封装在具体的类中(比如EnumGroup)。并创建一个Hashmap,其中包含密钥作为EnumGroupvalue的对象,作为枚举State的值。通过这种方式,我们可以为stateDIRECTION值的多个组合保存STATE值。我们还可以有两个不同的EnumGroup具有相同的state值。这是代码演示。

import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
class EnumGroup 
{
    Direction direction;
    Type type;
    private EnumGroup(){}//To prevent parmeterless construction
    public EnumGroup(Direction direction , Type type)
    {
        if (direction==null || type == null)
        {
            throw new IllegalStateException("null is not allowed");
        }
        this.direction = direction;
        this.type = type;
    }
    @Override
    public int hashCode()
    {
        return direction.toString().hashCode() + type.toString().hashCode() ;
    }
    @Override
    public boolean equals(final Object other)
    {
        if (other == null || !(other instanceof EnumGroup))
        {
            return false;
        }
        if (this == other)
        {
            return true;
        }
        EnumGroup temp = (EnumGroup)other;
        if (temp.type == this.type && temp.direction == this.direction)
        {
            return true;
        }
        return false;
    }
}
enum Direction
{
    LEFT,RIGHT,DOWN,UP,ACCROSS;
}
enum Type
{
    BIG,SMALL,MEDIUM;
}
enum State
{
    ONE_STATE,FIRST_STATE,SECOND_STATE,THIRD_STATE;
    private static final Map<EnumGroup,State> map = new HashMap<EnumGroup,State>();
    static
    {
        map.put(new EnumGroup(Direction.LEFT,Type.BIG),ONE_STATE);
        map.put(new EnumGroup(Direction.RIGHT,Type.SMALL),SECOND_STATE);
        map.put(new EnumGroup(Direction.UP,Type.SMALL),FIRST_STATE);
        /*
        .
        .
        .
        */
    }
    public static State getState(EnumGroup eGroup) 
    {
        State state = map.get(eGroup);
        return state == null ? THIRD_STATE : state;
    }
}
public class EnumValueByArgument
{
    public static void main(String st[])
    {
        ArrayList<EnumGroup> list = new ArrayList<EnumGroup>();
        for (Direction direction : Direction.values())
        {
            for (Type type : Type.values() )
            {
                list.add(new EnumGroup(direction,type));
            }
        }
        for (EnumGroup eGroup : list )
        {
            System.out.println(State.getState(eGroup));
        }
    }
}