String.equals替代多个比较(没有枚举)

时间:2011-03-30 17:49:07

标签: java string reflection equals switch-statement

我已经考虑过为我的所有字段制作枚举,但这看起来并不酷(我有许多实现类似方法的类)。还有更好的方法吗?

public void writeAttribute(String attribute, Object value) {
    if (attribute.equals("title")) {
        title = (String) value;
    } else if (attribute.equals("description")) {
        description = (String) value;
    } else if (attribute.equals("room")) {
        room = (Room) value;
    } else if (attribute.equals("type")) {
        type = AppointmentType.valueOf((String) value);
    } else if (attribute.equals("guestCount")) {
        guestCount = (Integer) value;
    }
}

根据attribute参数,我想将输入value映射到相应的字段。有没有办法清理/优化我的代码?为每个字段写.equals并不太优雅。

8 个答案:

答案 0 :(得分:2)

您是否考虑过使用HashMap存储属性,而不是为每个属性设置一个单独的成员变量?你的班级将有一个属性地图

Map<String,Object> attributes = new HashMap<String,Object>();

并且上面的方法缩小为

public void writeAttribute(String attribute, Object value) {
    this.attributes.put(attribute,value);
}

因为你无论如何都要进行投射,所以你可以使用方法在你访问时适当地转换值,或者在访问点自己投射它。

答案 1 :(得分:0)

您可以将属性/值对放在地图中:

public void writeAttribute(String attribute, Object value) {
   attributeMap.put(attribute, value);
}

然后将它们映射到字段更清晰:

title = (String)map.get(value);
description = (String)map.get(value);
room = (Room)map.get(value);
type = AppointmentType.valueOf((String)map.get(value));
guestCount = (Integer)map.get(value);

答案 2 :(得分:0)

你可以这样做:(随意使用Runnable以外的界面)

interface AttributeEvaluator {
  Object getValue(String s);
}

enum Attribute {
  TITLE(new AttributeEvaluator() { public Object getValue(String str) { return (String)value; }),
  ROOM(new AttributeEvaluator() { public Object getValue(String str) { return (Room)value; });


  private Attribute(AttributeEvaluator r) {
    this.evaluator = evaluator;
  }

  public <T> T getValueOf(String str) {
    return (T)evaluator.getValue(str);
  }
}

答案 3 :(得分:0)

我不认为你的方法是否可以避免这种if条件,尝试做类似的事情:

public void writeAttributes(Map<String, Object> attributesMap) {
    title = (String) attributesMap.get(TITLE);
    description = (String) attributesMap.get(DESCRIPTION);
    ...
}

其中TITLE和DESCRIPTION是您的最终变量。如果您在地图中没有值,例如在描述中,那么您将拥有null。

答案 4 :(得分:0)

一种方法是使用反射,请查看此post,其中介绍了如何获取字段,然后为其设置值。

答案 5 :(得分:0)

你可以尝试

public void writeAttribute(String attribute, Object value) {
    Field field = value.getClass().getDeclaredField(attribute);
    field.setAccesible(true);
    field.set(value);
}

答案 6 :(得分:0)

我们编写预处理的Java,您可以在此处找到processing code

它为我们提供了字符串开关。但是,它为编译增加了一个额外的步骤。需要处理的文件名为Foo.jpp并处理为Foo.java,但我们代码中基于String的交换机的普遍性弥补了这一不便。

示例:

/** set flags on added traps */
public void addTrap(JS key, JS function) throws JSExn {
    super.addTrap(key, function);
    // differentiate between read and write traps
    if (function.getFormalArgs().length != 1) {
        //#switch (JSU.toString(key))
        case "surface": set(SURFACE_READ_TRAP);
        case "visible": set(VISIBLE_READ_TRAP);
        case "Children": set(CHILDREN_READ_TRAP);
        //#end
        return;
    }
    //#switch (JSU.toString(key))
    case "x":         set(X_TRAP);
    case "y":         set(Y_TRAP);
    case "width":     set(WIDTH_TRAP);
    case "height":    set(HEIGHT_TRAP);
    case "minwidth":  set(MINWIDTH_TRAP);
    case "maxwidth":  set(MAXWIDTH_TRAP);
    case "minheight": set(MINHEIGHT_TRAP);
    case "maxheight": set(MAXHEIGHT_TRAP);
    case "contentwidth": set(CONTENTWIDTH_TRAP);
    case "contentheight": set(CONTENTHEIGHT_TRAP);
    case "surface":   set(SURFACE_TRAP); 
    case "visible":   set(VISIBLE_TRAP);
    case "Children":  set(CHILDREN_TRAP);
    case "Enter":     set(ENTER_TRAP);
    case "Leave":     set(LEAVE_TRAP);
    case "_Move":     set(_MOVE_TRAP);
    case "Move":      set(MOVE_TRAP);
    case "fontsize":  renderprops.setTrapFontsize(this);
    case "font":      renderprops.setTrapFont(this);
    case "shrink":    set(SHRINK_TRAP);
    case "hshrink":   set(HSHRINK_TRAP);
    case "vshrink":   set(VSHRINK_TRAP);
    //#end
}

答案 7 :(得分:0)

自Java SE 7(2011年7月28日)起,您可以切换字符串。