【问题标题】:String array to multiple objects字符串数组到多个对象
【发布时间】:2014-02-02 11:09:06
【问题描述】:

我有一个字符串数组

String[] weekDays

weekDays 表示星期几。例如

{1, 2, 4} means Monday, Tuesday, Thusday
{2,5,6,7} means Tuesday, Friday, Saturday, Sunday

我有 7 个布尔值表示一周中的 7 天,并且必须根据 weekDays 设置 true 或 false。

我的代码

private static void setWeekDays(final Object object, final String[] weekDays) {
    for (String day : weekDays) {
        if( day.equalsIgnoreCase("1")) {
            object.setMonday(true);
        } else if( day.equalsIgnoreCase("2")) {
            object.setTuesday(true);
        } else if( day.equalsIgnoreCase("3")) {
            object.setWednesday(true);
        } else if( day.equalsIgnoreCase("4")) {
            object.setThrusday(true);
        } else if( day.equalsIgnoreCase("5")) {
            object.setFriday(true);
        } else if( day.equalsIgnoreCase("6")) {
            object.setSaturday(true);
        } else if( day.equalsIgnoreCase("7")) {
            object.setSunday(true);
        } 
    }
}

但它有很多 if else 语句,在执行此操作之前,我明确地将所有布尔值设置为 false。 有没有其他简单的方法来做同样的事情?有什么建议吗??

【问题讨论】:

  • +1 表示努力。例如,我想看看“setSunday”是做什么的。在我看来,那些“设置..”功能可能不必要地针对每一天。如果您可以通过“set...”方法传递字符串的值并且它执行 XYZ,那么您可以使用一行代码完成所有这些操作,而不是 if 或 switch。
  • 数据库中基本上有7个字段,相对于7天来设置所有这些字段有7种方法。
  • 那么七法就过分了。您应该能够根据传递的值和您的数据库架构的任何更多信息来隐式引用这些数据库字段。将您设置的方法的代码添加到 OP。
  • @DeeMac 对不起,我不明白你的意思。那么你能描述一下你提到的那个吗
  • 你可以考虑使用 switch-case 并执行:Integer.parseInt(day);

标签: java arrays string if-statement logic


【解决方案1】:

我认为您可以尝试为此使用 ENUM。

例如

public enum WeekDay {
   MONDAY("1");

   private String value;

   private WeekDay(String value) {
       this.value = value;
   }

   public static WeekDay find(String value) {
       for (WeekDay weekDay : values()) {
           if (weekDay.value.equals(value)) {
               return weekDay;
           }
       }
   }

因此,您可以将此 ENUM 用作 DTO 的字段。

【讨论】:

  • 感谢您的回复。但我的问题不是存储这些东西。但是我从一个数组源重新获取输入,并且要读取该数组,我必须设置七个布尔变量。
【解决方案2】:

将枚举定义为一周中的几天:

 enum DayOfWeek { 
     MONDAY, TUESDAY, etc.
 }

创建一个从字符串到一天的地图:

 Map<String, DayOfWeek> dayByString = new HashMap<String, DayOfWeek>();

用你想要的所有查找填充地图,即

 dayByString.put("1", DayOfWeek.MONDAY);
 dayByString.put("2", DayOfWeek.TUESDAY);

现在查看当天只需执行以下操作:

 DayOfWeek day = dayByString.get(str);

如果没有匹配 - 或匹配的星期几,这将返回 null。

现在使用 EnumSet 代替 7 个布尔值:

 Set<DayOfWeek> days = new EnumSet<DayOfWeek>(DayOfWeek.class);

在内部,它将使用位域来表示日期,因此将非常快速且节省空间。

设置标志做days.add(day);

要取消设置,请执行days.remove(day);

要检查它是否已设置,请执行 days.contains(day);days.contains(DayOfWeek.MONDAY);

private static void setWeekDays(EnumSet<DayOfWeek> set, final String[] weekDays) {
    set.clear();
    for (String day : weekDays) {
        set.add(dayByString.get(day));
    }
}

你已经完成了,这就是你所需要的。

EnumSet 是存储它的正确方法。还有其他选项,但 7 个布尔值完全错误。

【讨论】:

  • 感谢您的回复。但我的问题不是存储这些东西。但是我从一个数组源重新获取输入,并且要读取该数组,我必须设置七个布尔变量。
  • 我的例子就是这样做的。我再补充一点
  • 我不能使用 EnumSet。这 7 个布尔值使用 hibernate 映射到 Db 中的 7 个字段。
  • 实际上你可以使用自定义休眠映射,虽然我不确定如何做到这一点,但无论如何这是一个单独的问题。如果您有 7 个单独的布尔值,那么您无法做任何事情来使映射更好,因为您需要通过不同的代码引用每个布尔值。
  • 嗯,你可以使用反射,但这比你拥有的更脏。
【解决方案3】:

您可以尝试以下操作:

  1. 在您的 DTO 对象中添加以下代码

    列出 weekDaysList;

    private void setWeekDays(String[] weekDays){            
        weekDaysList = Arrays.asList(weekDays);
    }
    
    private boolean isWeekdaySet(String weekday){
        if (weekDaysList == null || weekDaysList.size() == 0){
            return false;
        }
        return weekDaysList.contains(weekday);
    }
    
  2. 更新每个getMonday、getTuesday方法如下:
公共布尔 getMonday() { 返回 isWeekdaySet("1"); } 公共布尔 getTuesday(){ 返回 isWeekdaySet("2"); }

我希望这会有所帮助。

【讨论】:

  • hashMap int他的解决方案有什么用。
【解决方案4】:

如果DTO类不能修改,可以先尝试做一个方法映射,使用反射调用目标方法,如下:

private static Method[] methods;

private static void init() throws Exception {

    Class klass = BusTravelDetailDTO.class;
    String[] methodNames = new String[]{null, "setMonday", "setTuesday", "setSunday"};
    methods = new Method[methodNames.length];
    for (int i = 0; i < methods.length; i++) {
        if(methodNames[i] != null) {
            methods[i] = klass.getMethod(methodNames[i], Boolean.class);
        }
    }
}


private static void setWeekDays(final Object object, final String[] weekDays) {

    for (String day : weekDays) {
        methods[Integer.parseInt(day)].invoke(object, Boolean.TRUE);
    }
}

但是,由于您只有七个选择,if-else 可能是最简单有效的方法。

如果可以修改 DTO 类,请使用 enum 而不是七个布尔标志。

【讨论】:

    猜你喜欢
    • 2022-12-02
    • 1970-01-01
    • 2019-11-22
    • 1970-01-01
    • 1970-01-01
    • 2017-08-27
    • 2021-08-08
    • 1970-01-01
    • 2021-03-20
    相关资源
    最近更新 更多