条件(三元)运算符的多项选择等价物?

时间:2015-09-15 20:49:03

标签: java conditional

我有这方面的痴迷使我的Java代码更简洁。当然有理由:我在一个屏幕上看得越多,就越容易遵循逻辑。

例如,在分配值时,可能会写:

String result;
if (arg != null) {
   result = arg.toString();
} else {
   result = "default";
}

但当然这要短得多:

String result = (arg != null) ? arg.toString() : "default";

但是,对于非布尔条件(即超过2个选项),仍有一个问题依旧于switch语句,例如:

SimpleDateFormat format;
switch (dateOrder) {
case DMY :
    format = new SimpleDateFormat("{2}" + sep + "{1}" + sep + "{0}");
    break;
case MDY :
    format = new SimpleDateFormat("{1}" + sep + "{2}" + sep + "{0}");
    break;
case YMD :
    format = new SimpleDateFormat("{0}" + sep + "{1}" + sep + "{2}");
    break;
default :
    format = null;
}

我提出了一个实用程序类,它使用泛型,lambdas和链接范例来提供这样的语法:

SimpleDateFormat format = Multary.<DateOrderEnum, SimpleDateFormat>nSwitch(dateOrder)
        .nCase(DateOrderEnum.DMY, () -> new SimpleDateFormat("{2}" + sep + "{1}" + sep + "{0}"))
        .nCase(DateOrderEnum.MDY, () -> new SimpleDateFormat("{1}" + sep + "{2}" + sep + "{0}"))
        .nCase(DateOrderEnum.YMD, () -> new SimpleDateFormat("{0}" + sep + "{1}" + sep + "{2}"))
        .nDefault(() -> null)
        .result();

(该类本身相当容易实现,因此我不会厌恶读者使用该代码。)

我的问题是:

  1. 我在这里重新发明轮子吗?从搜索结果来看,我不是唯一有这种痒的人。以前有过类似的事吗?
  2. 这有什么缺点吗?我能想到的一些包括:
    • 由于在内部使用Map而不是语言结构,可能效率低下;
    • 没有编译器警告警告未使用的常量(如switchenum的情况) - 问题(包括“没有合适的情况以及没有提供默认情况”)只能在运行时检测到,并抛出一个合适的异常;
    • 也没有编译器检查重复常量或多个默认值 - 最近的调用将是确定的。这可以再次仅在运行时检查(抛出适当的异常);
    • 放弃case语句的“堕落”功能 - 每个nCase()调用只使用一个常量(尽管可以使用更多代码进行修改...这可能会混淆语法更多);
    • 代码自动格式化可以将链式命令混乱到不可读的混乱状态,因此需要注意令人满意地设置它。

1 个答案:

答案 0 :(得分:5)

您始终可以链接三向条件运算符:

Select TOP 100 PERCENT Projects.Id, dbo.Projects.ProjectName, dbo.Department.Name, dbo.Designer.FName + ' ' + dbo.Designer.LName AS Designer, dbo.Changes.ChangeDate, dbo.Projects.DueDate, dbo.Projects.Instructions, dbo.Status.Description

From GetAllLastChangeDatebyProjectIds(0) INNER JOIN
dbo.Projects ON dbo.Projects.ID = dbo.GetAllLastChangeDatebyProjectIds.ProjectID INNER JOIN
dbo.Designer ON dbo.Designer.Id = dbo.Projects.DesignerID INNER JOIN
dbo.Department ON dbo.Department.ID = dbo.Projects.DeptID INNER JOIN
dbo.Changes ON dbo.Changes.ProjectID = dbo.Projects.ID INNER JOIN
dbo.Status ON dbo.Changes.StatusID = dbo.Status.Id

Where dbo.GetAllLastChangeDatebyProjectIds.StatusID = dbo.Changes.StatusID 

ORDER BY dbo.Projects.ID DESC