2013-02-21 63 views
1

是否有任何審美方式基於其他兩種枚舉類型檢索枚舉值?我想要做的是讓一個國家有兩個枚舉變量一樣是下面的例子:給定參數的枚舉值

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; 
} 

} 

當然,這會字,但我的本意是要了解得更透徹些,因爲這樣可能會在第一時間增長數。

+0

看看我的回答 – 2013-02-26 15:40:24

回答

0

爲什麼不使用查找表?行數組 - 每行包含2個輸入和1個輸出。

LEFT, BIG, ONE_STATE 
RIGHT, SMALL, SECOND_STATE 

等,並提供一種方法來查找並返回默認值,如果查找失敗。

如果做不到這一點,你可以調查double dispatch

+0

「有效的Java」一書(條款33)認爲這個解決方案,然後解釋了爲什麼這不是最好的。 – lbalazscs 2013-02-21 15:30:52

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; 
    } 
} 
+0

我已經想過了,但正如我的例子所述,我需要在某些情況下兩個不同的輸入類型相同的枚舉值 – xwhyz 2013-02-21 15:22:37

0

如何把方向和類型作爲枚舉的成員,是這樣的:

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>類,但是您可以輕鬆地創建一個,或者在很多不同的庫中找到一個)。

+0

如何處理情況,當我需要兩個不同的值相同的狀態?像ONE_STATE(Direction.LEFT,Type.BIG),ONE_STATE(Direction.RIGHT,Type.BIG), – xwhyz 2013-02-21 15:23:45

+0

我回答你的問題,而你問它!在這種情況下,你將不得不使用Brian Agnew的解決方案。 – 2013-02-21 15:24:51

0

您可以使用switch es代替if s,但不會縮短代碼。它具有更清晰的優點,並且還取決於您的IDE,當switch缺少案例時,您可以讓它發生錯誤。

使用最多項目的枚舉爲外部switch和其他內部switch

將字段添加到您的Stateenum會,如果有中DirectionType只有一個組合「達」即State才起作用。

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

使用嵌套的EnummMap。 「有效的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); 
     } 
    } 
} 
+0

我不明白我怎樣才能得到兩個不同的參數值集相同的枚舉值 – xwhyz 2013-02-21 15:50:36

+0

您可以有一個EnumMap <方向,地圖>作爲內部嵌套的EnumMap – lbalazscs 2013-02-21 16:03:28

0

您可以在具體的類封裝DIRECTIONTYPE(說EnumGroup)。並創建一個Hashmap,其中包含密鑰作爲EnumGroupvalue的對象,作爲enum State的值。通過這種方式,我們可以爲DIRECTIONSTATE的多個組合值保存state值。我們也可以有兩個不同的EnumGroup具有相同的值state。這裏是代碼Demo。

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)); 
     } 
    } 
}