希望以更清洁/更有效的方式将字符串与int相关联

时间:2011-04-18 03:15:05

标签: java string enums comparison performance

我该如何改进?

关系是一对一的,并且在[-1,5]上连续,所以我想使用枚举,但我不确定如何将字符串值与枚举值进行比较。

如果有更好的方法,请建议。

谢谢!

private int evaluateWord(String sval) {
    if (sval.equals("program"))
        return 1;
    else if (sval.equals("begin"))
        return 2;
    else if (sval.equals("end"))
        return 3;
    else if (sval.equals("int"))
        return 4;
    else if (sval.equals("if"))
        return 5;
    else
        System.exit(0);

8 个答案:

答案 0 :(得分:4)

您是否考虑过将映射填充到HashMap中一次,然后只是查询地图?

例如,像这样:

 private static final Map<String,Integer> m_map = new HashMap<String,Integer>();
 static {
     m_map.put( "program", 1 );
     m_map.put( "begin", 2 );
     m_map.put( "end", 3 );
     m_map.put( "int", 4 );
     m_map.put( "if", 5 );
 }

 private int evaluateWord(String sval) {
     Integer value = m_map.get( sval );
     if ( null != value ) {
        return value;
     }
     else {
        System.exit(0);
     }
 }

顺便说一句,看起来好像你正在写一个解析器。手动编写解析器是合理的。除非你有充分的理由手工编写,否则另一个需要考虑的选择是像ANTLR这样的解析器生成器。

答案 1 :(得分:4)

使用枚举:

enum Word {
  PROGRAM(1,"program"),
  BEGIN(2,"begin"),
  END(3,"end"),
  INT(4,"int"),
  IF(5,"if");

  private final int value;
  private final String representation;

  Word(int value, String representation)
  {
    this.value = value;
    this.representation = representation;
  }

  public int value()
  { return value; }

  private static Map<String, Word> fromRep =
    new HashMap<String, EnumExample2.Word>();

  public static Word fromRepresentation(String rep) {
    if (!validRep(rep)) {
      throw new IllegalArgumentException("No rep: "+rep);
    }

    return fromRep.get(rep);
  }

  public static boolean validRep(String rep)
  { return fromRep.get(rep) != null; }

  static {
    for (Word word : Word.values()) {
      fromRep.put(word.representation, word);
    }
  }
}

然后你的逻辑是:

private int evaluateWord(String sval) {
  if (!Word.validRep(sval)) {
    System.exit(0);
  }

  return Word.fromRepresentation(sval).value();
}

答案 2 :(得分:2)

散列图可以工作:

private static HashMap<String, Integer> lookup = new HashMap<String, Integer>();
static {
    lookup.put("program", 1);
    lookup.put("being", 2);
    lookup.put("end", 3);
    lookup.put("int", 4);
    lookup.put("if", 5);
}

private int evaluateWord(String sval) {
    if ( lookup.containsKey(sval) ) {
        return lookup.get(sval);
    }
    System.exit(0); 
}

答案 3 :(得分:2)

这就是地图的用途;

创建一个HashMap,向地图添加键和值,如

wordMap.put("program", Integer.valueOf(1));

...

然后,获取值

Integer val = wordMap.get(sval);

答案 4 :(得分:0)

老实说,我不担心保持这种超高效的东西,但你可以做出改变。如果您传递的单词是您检查的最后一个单词,那么您的程序最终会执行您函数中的所有检查。在这种情况下,这不应该是一个问题,但通常你不想用if语句泛滥你的程序,特别是如果你有很多案例。

使用哈希表并插入对。这样,所有的evaluateWord调用都将以分摊的常量时间返回。 :)

祝你好运!

答案 5 :(得分:0)

为什么你需要(非常主观)“清洁”的方式?

您可以通过使用哈希查找获得更高的效率,但是您需要确定它的调用相当多,以使额外的编码工作变得有价值。如果不经常发生的事情(并且,那意味着每秒不到一次),那就不值得做(YAGNI)。

你可能想要做的更好看的代码(如果这很重要)就是抛弃else位,它们完全是不必要的:

private int evaluateWord(String sval) {
    if (sval.equals("program")) return 1;
    if (sval.equals("begin"))   return 2;
    if (sval.equals("end"))     return 3;
    if (sval.equals("int"))     return 4;
    if (sval.equals("if"))      return 5;
    System.exit(0);
}

答案 6 :(得分:0)

受到你的枚举评论的启发,我提出以下内容。这有点hackish,但是:

enum Word
{
    PROGRAM (1), BEGIN (2), END (3), INT (4), IF (5);

    public int value;

    public Word (int value)
    {
        this.value = value;
    }
};

int evaluateWord (String word)
{
    return Word.valueOf(word.toUpperCase( )).value;
}

我喜欢Java enums,因为你可以做这样的事情。如果您以后想要(例如)为每个单词添加唯一的行为,或者维护一长串单词,这将特别有用。请注意,它不区分大小写。

或者,或者:

enum Word
{
    PROGRAM, BEGIN, END, INT, IF;
};

int evaluateWord (String word)
{
    return Word.valueOf(word.toUpperCase( )).ordinal( ) + 1;
}

答案 7 :(得分:0)

您可以使用数组或散列映射将枚举值映射到字符串值。