用于多次比较的 String.equals 的替代方案(不带枚举)

发布于 2024-10-29 09:00:42 字数 682 浏览 8 评论 0原文

我曾考虑过为我的所有字段创建枚举,但这看起来也不酷(我有许多实现类似方法的类)。有更好的办法吗?

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 不太优雅。

I have thought about making enums for all my fields, but that doesn't look to cool either (i have many classes that implements similar methods). Is there a better way?

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

Depending on the attribute parameter, i want to map the input value to the appropriate field. Is there a way to clean up/optimize my code? Writing .equals for every field isn't too elegant.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

软甜啾 2024-11-05 09:00:42

您是否考虑过使用 HashMap 来存储属性,而不是为每个属性使用单独的命名成员变量?您的类将有一个属性映射

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

,并且上面的方法简化为

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

由于您无论如何都在进行强制转换,因此您将拥有在访问它时适当地强制转换该值的方法,或者在访问点自行强制转换它。

Rather than have an individual named member variable for each attribute, have you considered using a HashMap to store attributes? Your class would have an attribute map

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

and your method above reduces to

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

Since you're casting anyway, you would then have methods that cast the value appropriately when you access it, or cast it yourself at the point of access.

携君以终年 2024-11-05 09:00:42

您可以将属性/值对放入映射中:

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

You could put your attribute/value pairs in a map:

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

And then mapping them to fields is a little cleaner:

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);
盛装女皇 2024-11-05 09:00:42

你可以这样做:(随意使用除 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);
  }
}

you could do this: (feel free to use interface other than 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);
  }
}
千年*琉璃梦 2024-11-05 09:00:42

我认为如果你的方法不能避免这样的 if 条件,请尝试做类似的事情:

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

其中 TITLE 和DESCRIPTION 是你的最终变量。如果您的地图中没有值(例如描述),那么您的值将为空。

I don't think if your method is OK to avoid such if-conditions, try do something like that:

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

where TITLE and DESCRIPTION is your final variables. If you won't have value in your Map for example in description then you'll have there null.

始终不够 2024-11-05 09:00:42

一种方法是使用反射,请查看这篇帖子,它解释了如何获取字段然后为其设置值。

One way is using reflection, check out this post which explains how to get a field and then set the value for it.

长伴 2024-11-05 09:00:42

你可以尝试

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

You can try

public void writeAttribute(String attribute, Object value) {
    Field field = value.getClass().getDeclaredField(attribute);
    field.setAccesible(true);
    field.set(value);
}
夏雨凉 2024-11-05 09:00:42

我们编写了预处理的 Java,您可以找到 处理代码在这里。

它为我们提供了字符串开关。然而,它增加了一个额外的编译步骤。需要处理的文件被命名为 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
}

We write preprocessed Java, for which you can find the processing code here.

It gives us string switches. However it adds an additional step to compilation. Files that require processing are named Foo.jpp and are processed to Foo.java, but the pervasiveness of String-based switches in our code more than makes up for this inconvenience.

Example:

/** 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
}
楠木可依 2024-11-05 09:00:42

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

Since Java SE 7 (July 28, 2011) you can switch strings.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文