1

我在一周中的几天(周一到周日)的 java 对象中有 7 个布尔变量。我试图从几天列表的 for 循环中找到一种简洁的方式来说明以下内容:

    private boolean isWorkDay(String day, Object pgMasterTaskList) {
        if(day=="Sunday" && pgMasterTaskList.Sunday==true) {
            return true;
        }
        if(day=="Monday" && pgMasterTaskList.Monday==true) {
            return true;
        }
        if(day=="Tuesday" && pgMasterTaskList.Tuesday==true) {
            return true;
        }
        if(day=="Wednesday" && pgMasterTaskList.Wednesday==true) {
            return true;
        }
        if(day=="Thursday" && pgMasterTaskList.Thursday==true) {
            return true;
        }
        if(day=="Friday" && pgMasterTaskList.Friday==true) {
            return true;
        }
        if(day=="Saturday" && pgMasterTaskList.Saturday==true) {
            return true;
        }
        else return false;
    }

我希望我可以用类似的东西来减少重复。

private boolean isWorkDay(String day, Object pgMasterTaskList) {
        if(pgMasterTaskList.getVariableByName(day)==true) {
            return true;
        }
        else return false;
    }

我的想法是使用反射来检查名为“Monday”的变量的值是否等等,但我不确定如何以这种方式使用它。

编辑

我已经提交了一个适用于我的具体案例的答案。再详细一点...

我正在将此信息写入 pdf,因此我正在处理字符串比较,因为我必须将它们映射到 pdf 中的字段名称。所以我试图保持一致。任何一天的组合都可以是一个工作日。我想这给我留下了 128 个连击?(2^7)。信息由 csv 输入,所以我想将 day in 作为字符串读取,因为它是这样输入的。

4

5 回答 5

2

如果您可以修改您的任务列表对象以保存一个Set工作日而不是 7 个布尔值,那么您甚至不需要循环。线性时间的表查找就可以了。

    DateTimeFormatter dowFormatter = DateTimeFormatter.ofPattern("cccc", Locale.ENGLISH);

    EnumSet<DayOfWeek> workdays = EnumSet
            .of(DayOfWeek.MONDAY, DayOfWeek.TUESDAY, DayOfWeek.THURSDAY);
    String day = "Tuesday";

    DayOfWeek dow = dowFormatter.parse(day, DayOfWeek::from);
    boolean isWorkDay = workdays.contains(dow);

    System.out.println("Is work day? " + isWorkDay);

示例的输出:

是工作日吗?真的

AnEnumSet被实现为布尔值数组。

我相信您可以将其EnumSet放入您的对象中,并将代码包装在类似于您在问题中所做的方法中。

c我在用于定义星期几的格式化程序的格式模式字符串中使用的模式字母并不经常使用。坦率地说,我怀疑在这里使用它是否正确。根据文档,它为我们提供了本地化星期几文本的独立形式。由于单独的星期几——它不是日期字符串的一部分——我认为它可能是正确的。如果没有,请使用更常见的EEEE. 至少对于英语来说,两者都有效。

编辑:即使您的 7 个布尔值来自 CSV 文件,我可能仍会使用 set 方法。对于初始化集合,我不认为我会诉诸反射,而是接受 7 个if语句(这里比我们大多数人在实际代码中所做的更简洁):

    boolean sunday = false;
    boolean monday = true;
    boolean tuesday = true;
    boolean wednesday = false;
    boolean thursday = true;
    boolean friday = false;
    boolean saturday = false;

    Set<DayOfWeek> workdays = EnumSet.noneOf(DayOfWeek.class);
    if (sunday) workdays.add(DayOfWeek.SUNDAY);
    if (monday) workdays.add(DayOfWeek.MONDAY);
    if (tuesday) workdays.add(DayOfWeek.TUESDAY);
    if (wednesday) workdays.add(DayOfWeek.WEDNESDAY);
    if (thursday) workdays.add(DayOfWeek.THURSDAY);
    if (friday) workdays.add(DayOfWeek.FRIDAY);
    if (saturday) workdays.add(DayOfWeek.SATURDAY);

    System.out.println(workdays);

[周一、周二、周四]

编辑2:

下面是将一行布尔值从 CSV 文件转换为EnumSet<DayOfWeek>.

    String lineFromCsv = "false;true;true;false;true;false;false";

    String[] workDayStrings = lineFromCsv.split(";");
    Set<DayOfWeek> workdays = EnumSet.noneOf(DayOfWeek.class);
    // Sunday
    if (Boolean.valueOf(workDayStrings[0])) {
        workdays.add(DayOfWeek.SUNDAY);
    }
    // Monday through Saturday
    for (int i = 1; i < workDayStrings.length; i++) {
        if (Boolean.valueOf(workDayStrings[i])) {
            workdays.add(DayOfWeek.of(i));
        }
    }
    System.out.println(workdays);

[周一、周二、周四]

关联

于 2020-05-16T17:25:43.410 回答
1

我使用以下方法找到了我的问题的答案:

  public static Object getValueOf(Object clazz, String lookingForValue)
      throws Exception {
    Field field = clazz.getClass().getField(lookingForValue);
    Class clazzType = field.getType();
    if (clazzType.toString().equals("double"))
      return field.getDouble(clazz);
    else if (clazzType.toString().equals("int"))
      return field.getInt(clazz);
    // else other type ...
    // and finally
    return field.get(clazz);
  }

我现在这样称呼它:

    private boolean isWorkDay(String day, PlanGridMasterTaskList pgMasterTaskList) throws Exception {
        System.out.println(getValueOf(pgMasterTaskList, day));
        if ((boolean) getValueOf(pgMasterTaskList, day)) {
            return true;
        }
        else
            return false;
    }

我在这个链接上找到了它: https ://www.rgagnon.com/javadetails/java-0038.html

感谢所有花时间回复的人(而且回复得这么快!)。

于 2020-05-16T17:36:35.387 回答
1

您可以使用 Object 类.getClass().getFields()方法来获取类中的所有变量或使用 specific.getClass().getField("variableName")来获取特定变量。

java反射api将允许将变量作为字段(java.lang.reflect)获取

  private boolean isWorkDay(String day, Object pgMasterTaskList)
      throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
    Object obj = null;
    if (pgMasterTaskList.getClass().getField(day).get(obj).equals(true)) {
      return true;
    } else
      return false;
  }

上面的行Object obj = null;只是一个占位符,用于使用 获取变量.get()

但是,这仅在day参数的值与 pgMasterTaskList 类中定义的变量名称完全匹配时才有效。如果您想要基于不区分大小写的场景进行提取,您可以使用该.getFields()方法。下面是一个相同的例子:

  private boolean isWorkDay(String day, Object pgMasterTaskList) throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
    Object obj = null;
    for (Field field : pgMasterTaskList.getClass().getFields()) {
      if (day.equalsIgnoreCase(field.getName())) {
        obj = field.get(obj);
        if ((boolean) obj == true)
          return true;
      }
    }
    return false;
  }

.get(obj)返回您的变量的类类型的对象(您的变量是布尔值,然后返回 obj 将是布尔类型)。

于 2020-05-16T17:38:12.760 回答
0

您必须为此使用反射:

private boolean isWorkDay(String day, Object pgMasterTaskList) throws NoSuchFieldException, NullPointerException, SecurityException {
    return pgMasterTaskList.getClass().getField(day);
}

注意:调用者必须处理他们通过一天为空或错误的情况,或者布尔成员不公开的情况。

于 2020-05-16T17:19:15.470 回答
0

尝试创建一个enum然后你的方法逻辑如下所示,

public class WeekMap {

    public static void main(String[] args) {
        System.out.println(isWorkDay("SUNDAY",WeekDays.SUNDAY));
        System.out.println(isWorkDay("sunday",WeekDays.SUNDAY));
        System.out.println(isWorkDay("sunday",WeekDays.SATURDAY));
        System.out.println(isWorkDay("ABS",WeekDays.SATURDAY));
    }

    private static boolean isWorkDay(String day, WeekDays pgMasterTaskList) {
        WeekDays day1 = WeekDays.valueOf(day.toUpperCase()); // Fetch the mapped day for the string
        try{
            day1 = WeekDays.valueOf(day.toUpperCase());
        } catch (IllegalArgumentException iex) {
            iex.printStackTrace(); // this can be suppress
        }
        return day1 == pgMasterTaskList;
    }
}

enum WeekDays{ // Create enum for week day names
    SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY;
}

于 2020-05-16T17:51:17.747 回答