2013-07-13 49 views
0

我想知道是否有更好的方式来创建和搜索下面的静态地图。如在main()方法中所见。优化枚举查找地图

import java.util.Arrays; 
import java.util.HashMap; 
import java.util.HashSet; 
import java.util.Map; 
import java.util.Set; 

public enum PokemonType { 
    BUG("Bug"), 
    DARK("Dark"), 
    DRAGON("Dragon"), 
    ELECTRIC("Electric"), 
    FAIRY("Fairy"), 
    FIGHTING("Fighting"), 
    FIRE("Fire"), 
    FLYING("Flying"), 
    GHOST("Ghost"), 
    GRASS("Grass"), 
    GROUND("Ground"), 
    ICE("Ice"), 
    NORMAL("Normal"), 
    POISON("Poison"), 
    PSYCHIC("Psychic"), 
    ROCK("Rock"), 
    STEEL("Steel"), 
    WATER("Water"); 

    private String name; 

    @SuppressWarnings("serial") 
    public static Map<PokemonType, Set<PokemonType>> noEffect = new HashMap<PokemonType, Set<PokemonType>>() {{ 
    put(BUG, new HashSet<PokemonType>()); 
    put(DARK, new HashSet<PokemonType>()); 
    put(DRAGON, new HashSet<PokemonType>()); 
    put(ELECTRIC, new HashSet<PokemonType>() {{ addAll(Arrays.asList(GROUND)); }}); 
    put(FAIRY, new HashSet<PokemonType>()); 
    put(FIGHTING, new HashSet<PokemonType>() {{ addAll(Arrays.asList(GHOST)); }}); 
    put(FIRE, new HashSet<PokemonType>()); 
    put(FLYING, new HashSet<PokemonType>()); 
    put(GHOST, new HashSet<PokemonType>() {{ addAll(Arrays.asList(NORMAL)); }}); 
    put(GRASS, new HashSet<PokemonType>()); 
    put(GROUND, new HashSet<PokemonType>() {{ addAll(Arrays.asList(FLYING)); }}); 
    put(ICE, new HashSet<PokemonType>()); 
    put(NORMAL, new HashSet<PokemonType>() {{ addAll(Arrays.asList(GHOST)); }}); 
    put(POISON, new HashSet<PokemonType>()); 
    put(PSYCHIC, new HashSet<PokemonType>()); 
    put(ROCK, new HashSet<PokemonType>()); 
    put(STEEL, new HashSet<PokemonType>()); 
    put(WATER, new HashSet<PokemonType>()); 
    }}; 

    @SuppressWarnings("serial") 
    public static Map<PokemonType, Set<PokemonType>> notVeryEffective = new HashMap<PokemonType, Set<PokemonType>>() {{ 
    put(BUG, new HashSet<PokemonType>() {{ addAll(Arrays.asList(FIGHTING,FIRE,FLYING,GHOST,POISON,STEEL)); }}); 
    put(DARK, new HashSet<PokemonType>() {{ addAll(Arrays.asList(DARK,FIGHTING,STEEL)); }}); 
    put(DRAGON, new HashSet<PokemonType>() {{ addAll(Arrays.asList(STEEL)); }}); 
    put(ELECTRIC, new HashSet<PokemonType>() {{ addAll(Arrays.asList(DRAGON,ELECTRIC)); }}); 
    put(FAIRY, new HashSet<PokemonType>()); 
    put(FIGHTING, new HashSet<PokemonType>() {{ addAll(Arrays.asList(BUG,FLYING,POISON,PSYCHIC)); }}); 
    put(FIRE, new HashSet<PokemonType>() {{ addAll(Arrays.asList(DRAGON,FIRE,ROCK,WATER)); }}); 
    put(FLYING, new HashSet<PokemonType>() {{ addAll(Arrays.asList(ROCK,STEEL)); }}); 
    put(GHOST, new HashSet<PokemonType>() {{ addAll(Arrays.asList(STEEL)); }}); 
    put(GRASS, new HashSet<PokemonType>() {{ addAll(Arrays.asList(BUG,DRAGON,FIRE,FLYING,GRASS,POISON,STEEL)); }}); 
    put(GROUND, new HashSet<PokemonType>() {{ addAll(Arrays.asList(BUG,GRASS)); }}); 
    put(ICE, new HashSet<PokemonType>() {{ addAll(Arrays.asList(FIRE,ICE,STEEL,WATER)); }}); 
    put(NORMAL, new HashSet<PokemonType>() {{ addAll(Arrays.asList(ROCK,STEEL)); }}); 
    put(POISON, new HashSet<PokemonType>() {{ addAll(Arrays.asList(GHOST,GROUND,POISON,ROCK)); }}); 
    put(PSYCHIC, new HashSet<PokemonType>() {{ addAll(Arrays.asList(PSYCHIC,STEEL)); }}); 
    put(ROCK, new HashSet<PokemonType>() {{ addAll(Arrays.asList(FIGHTING,GROUND,STEEL)); }}); 
    put(STEEL, new HashSet<PokemonType>() {{ addAll(Arrays.asList(ELECTRIC,FIRE,STEEL,WATER)); }}); 
    put(WATER, new HashSet<PokemonType>() {{ addAll(Arrays.asList(DRAGON,GRASS,WATER)); }}); 
    }}; 

    @SuppressWarnings("serial") 
    public static Map<PokemonType, Set<PokemonType>> superEffective = new HashMap<PokemonType, Set<PokemonType>>() {{ 
    put(BUG, new HashSet<PokemonType>() {{ addAll(Arrays.asList(DARK,GRASS,PSYCHIC)); }}); 
    put(DARK, new HashSet<PokemonType>() {{ addAll(Arrays.asList(GHOST,PSYCHIC)); }}); 
    put(DRAGON, new HashSet<PokemonType>() {{ addAll(Arrays.asList(DRAGON)); }}); 
    put(ELECTRIC, new HashSet<PokemonType>() {{ addAll(Arrays.asList(FIRE,WATER)); }}); 
    put(FAIRY, new HashSet<PokemonType>()); 
    put(FIGHTING, new HashSet<PokemonType>() {{ addAll(Arrays.asList(DARK,ICE,NORMAL,ROCK,STEEL)); }}); 
    put(FIRE, new HashSet<PokemonType>() {{ addAll(Arrays.asList(BUG,GRASS,ICE,STEEL)); }}); 
    put(FLYING, new HashSet<PokemonType>() {{ addAll(Arrays.asList(BUG,FIGHTING,GRASS)); }}); 
    put(GHOST, new HashSet<PokemonType>() {{ addAll(Arrays.asList(GHOST,PSYCHIC)); }}); 
    put(GRASS, new HashSet<PokemonType>() {{ addAll(Arrays.asList(GROUND,ROCK,WATER)); }}); 
    put(GROUND, new HashSet<PokemonType>() {{ addAll(Arrays.asList(ELECTRIC,FIRE,POISON,ROCK,STEEL)); }}); 
    put(ICE, new HashSet<PokemonType>() {{ addAll(Arrays.asList(DRAGON,FLYING,GRASS,GROUND)); }}); 
    put(NORMAL, new HashSet<PokemonType>()); 
    put(POISON, new HashSet<PokemonType>() {{ addAll(Arrays.asList(GRASS)); }}); 
    put(PSYCHIC, new HashSet<PokemonType>() {{ addAll(Arrays.asList(FIGHTING,POISON)); }}); 
    put(ROCK, new HashSet<PokemonType>() {{ addAll(Arrays.asList(BUG,FIRE,FLYING,ICE)); }}); 
    put(STEEL, new HashSet<PokemonType>() {{ addAll(Arrays.asList(ICE,PSYCHIC)); }}); 
    put(WATER, new HashSet<PokemonType>() {{ addAll(Arrays.asList(FIRE,GROUND,ROCK)); }}); 
    }}; 

    public float getModifier(PokemonType opponentType) { 
    if (PokemonType.superEffective.get(this).contains(opponentType)) 
     return 2.0f; 
    if (PokemonType.notVeryEffective.get(this).contains(opponentType)) 
     return 0.5f; 
    if (PokemonType.noEffect.get(this).contains(opponentType)) 
     return 0.0f; 
    return 1.0f; 
    } 

    public String getName() { 
    return name; 
    } 

    public void setName(String name) { 
    this.name = name; 
    } 

    public String shortName() { 
    return this.name.substring(0, 3); 
    } 

    private PokemonType(String name) { 
    this.name = name; 
    } 

    public static void main(String[] args) { 
    assert(PokemonType.ELECTRIC.getModifier(PokemonType.WATER) == 2.0f); 
    assert(PokemonType.GROUND.getModifier(PokemonType.DARK) == 1.0f); 
    assert(PokemonType.FIRE.getModifier(PokemonType.DRAGON) == 0.5f); 
    assert(PokemonType.NORMAL.getModifier(PokemonType.GHOST) == 0.0f); 
    } 
} 
+0

您对“更好”的要求是什么? (这是关于运行时性能的?可读性?让编译器验证完整性?是否可以轻松地从excel中导入矩阵?完全是其他的?) – meriton

回答

0

我会用一个ImmutableMap或由于地图(一个或多个)UnmodifiableMap不应该,一旦他们被填充进行修改。

此外,我会创建一个单一的Map<List<PokemonType>, Float>,其中每个列表将包含两个PokemonType对象(第一个对象是攻击者,第二个对象是攻击者,反之亦然 - 只要它是一致)。可替换地,我将创建一个单Map<PokemonTypePair, Float>,其中PokemonTypePair

public class PokemonTypePair { 
    final public PokemonType attacker; 
    final public PokemonType defender; 

    public boolean equals(Object obj) { 
     if(obj == null) return false; 
     else if(!(obj instanceof PokemonTypePair)) return false; 
     else { 
      PokemonTypePair other = (PokemonTypePair)obj; 
      return this.attacker.equals(other.attacker) && 
       this.defender.equals(other.defender); 
     } 
    } 

    public int hashCode() { 
     return (997 * attacker == null ? 0 : attacker.hashCode())^
      (991 * defender == null ? 0 : defender.hashCode()); 
    } 
} 

的所述float每个地图项将是0.0,0.5,1.0,或2.0;或者,省略具有1.0值的映射条目,并假定缺少的映射条目对应于1.0值。

如果配对是反身的(意思是谁不是攻击者和谁是防御者 - 我不知道小精灵是如何工作的),那么你只需要一个PokemonType pokemon1字段和一个PokemonType pokemon2字段;为了简化equals方法,在pokemon1字段中放置字母顺序较低的PokemonType,并在pokemon2字段中放置字母顺序较高的PokemonType。同样,如果采用List<List<PokemonType>>方法,请按字母顺序对内部列表进行排序,否则请使用List<Set<PokemonType>>

这样,给定任何两个口袋妖怪类型,你只需要在一张地图上查找对来找到乘数,而不必检查多个地图。

如果你想快速找到无效/超级有效的/ etc,然后保持单独的列表或设置无效/超级有效的/ etc配对,即List<List<PokemonType>> ineffectivePairingList<PokemonPairing> ineffectivePairing

0

如果你有一个地图配对使用Enum键或具有枚举值的Set,使用EnumMap或EnumSet会更高效,因为它们是为这种情况而设计的。