有没有一种简单的方法编写多个if条件语句?

4

我有以下Java代码。 我需要执行所有if语句。有没有更好的方法来编写这段代码?在每个语句中,我将进行数据库调用。

if (!keyAccntId.equalsIgnoreCase("-1") && !(segmentId.equalsIgnoreCase("-1")) && !(regionId.equalsIgnoreCase("-1"))) {
    templateOrder.add("1");
}
if (!keyAccntId.equalsIgnoreCase("-1") && (segmentId.equalsIgnoreCase("-1")) && !(regionId.equalsIgnoreCase("-1"))) {
    templateOrder.add("2");
}
if (!keyAccntId.equalsIgnoreCase("-1") && (segmentId.equalsIgnoreCase("-1")) && (regionId.equalsIgnoreCase("-1"))) {
    templateOrder.add("3");
}
if (keyAccntId.equalsIgnoreCase("-1") && !(segmentId.equalsIgnoreCase("-1")) && !(regionId.equalsIgnoreCase("-1"))) {
    templateOrder.add("4");
}
if (keyAccntId.equalsIgnoreCase("-1") && (segmentId.equalsIgnoreCase("-1")) && !(regionId.equalsIgnoreCase("-1"))) {
    templateOrder.add("5");
}
if (keyAccntId.equalsIgnoreCase("-1") && (segmentId.equalsIgnoreCase("-1")) && (regionId.equalsIgnoreCase("-1"))) {
    templateOrder.add("6");
}

3
我会将这个转换成位掩码,然后在其上使用 switch 语句。 - njzk2
1
位掩码解决了即时问题。但我的直觉是实际的目标是值得怀疑的。也许你应该解释一下"templateOrder"是什么,以及你打算用它做什么(或者这只是实际数据库调用的占位符?) - Marco13
8
针对数字,不需要使用 equalsIgnoreCase 方法,因为数字没有大小写之分。可以尝试使用 equals("-1") - Peter Lawrey
1
顺便提一下,有8个可能的结果,其中有两个结果你没有数字。如果segmentId.equals("-1") && regionId.equals("-1"),你什么也不做。 - Peter Lawrey
@Peter Lawrey:只复制了上面的6个。条件确实存在。 - user3707778
显示剩余2条评论
5个回答

16

你可以创建一个位掩码并打开它:

public static final int KEY = 1;
public static final int SEGMENT = 2;
public static final int REGION = 4;

int value = 0;

if (keyAccntId.equalsIgnoreCase("-1")) {
    value += KEY;
}
if (segmentId.equalsIgnoreCase("-1")) {
    value += SEGMENT;
}
if (regionId.equalsIgnoreCase("-1")) {
    value += REGION;
}

这给你8个可能的值,可以打开:

switch(value) {
case 0:
    // All false
    break;
case KEY:
    // only keyAccntId is true
    break;
case REGION:
    // only segmentId is true
    break;
case KEY + REGION:
    // segmentId and keyAccntId are true
    break;
// So on
}

编辑

添加常量以提高可读性。


1
我给了你一个赞,因为这似乎是一个不错的方向。但是我不能帮助想到这个有点难以阅读。它能够很好地扩展,这是一个不错的特性。 - Duncan Jones
这难道不只是重新组织他的选项树吗?这很有帮助,但也许为他清理视觉上的东西更有帮助..? - Kyte
2
@Duncan 我同意。让它变得更好的一种方法是为每个项目使用常量,并在switch语句中与&一起使用它们(例如values += Const.KEYcase Const.KEY&Const.SEGMENT)。 - njzk2
@njzk2 是的,那将会是一个巨大的改进。如果你在回答中包含这样的代码,它可能更容易阅读。 - Duncan Jones
你想要 KEY + REGION 或者 KEY | REGION 因为 KEY & REGION0 - Peter Lawrey

7

使用Java 7的@njzk2答案的简短版本。

public static final int KEY = 0b001, SEGMENT = 0b010, REGION = 0b100;

int comb = (keyAccntId.equals("-1") ? KEY : 0) +
        (segmentId.equals("-1") ? SEGMENT : 0) +
        (regionId.equals("-1") ? REGION : 0);
switch(comb) {
     case 0:       /* none are true. */ break;
     case REGION:  /* only regionId is -1 */ break;
     // more combinations.
     case KEY + SEGMENT + REGION: /* all are -1 */ break;
}

2
我认为你应该在 switch 语句之前计算 switch 的值,以使其更易读。 - But I'm Not A Wrapper Class

2
没有"if",没有"switch"。这三行代码可以涵盖所有情况:
 int val = keyAccntId.equals("-1")? 3:0;
 val += ((segmentId.equals("-1")? 1:0) + (regionId.equals("-1")? 1:0);
 templateOrder.add(val+1+"");

你可能想要封装代码,这样它最终会变成这样:

public int getTemplateOrder(int keyAccntId, int segmentId, int regionId){
  int val = keyAccntId.equals("-1")? 3:0;
  return val + (segmentId.equals("-1")? 1:0) + (regionId.equals("-1")? 1:0) + 1;
}

//Usage
templateOrder.add(getTemplateOrder(keyAccntId, segmentId, regionId)+"");

为了提高可读性,以下是这三行:

   int acc = keyAccntId.equals("-1")? 3:0;
   int seg = segmentId.equals("-1")? 1:0;
   int reg = regionId.equals("-1")? 1:0;
   int val = acc;

   //Construct the value currently being used on each If statement.
   val += seg + reg;

   //You've got the value, so instead of If/switch, just set it.
   templateOrder.add(val+1+"");

我希望这不会太晦涩。

谢谢。


1
你确定吗?我认为当所有条件都为假时,结果值将为0,并返回-1。 - Syam S
@SyamS 现在怎么样?我喜欢它。 - FewDexter
非常感谢您的输入,但我认为我错过了您所指的那一行 :(,是指 templateOrder.add("5"); 这一行吗? - FewDexter
1
是的。在您的情况下,它返回6。问题在于他没有一个条件 keyAccntId == -1 && segmentId != -1 && regionId == -1 - Syam S
哦,我的天啊..你刚刚让我脸红了。 - FewDexter
显示剩余4条评论

0
为了使视觉效果更加简单,您可以这样做...
boolean keyTF = keyAccntId.equalsIgnoreCase("-1"), 
segmentTF = segmentId.equalsIgnoreCase("-1"), 
regionTF = regionId.equalsIgnoreCase("-1");

if (!keyTF  && !segmentTF  && !regionTF ) {
    templateOrder.add("1");
}
if (!keyTF  && segmentTF  && !regionTF ) {
    templateOrder.add("2");
}
if (!keyTF  && segmentTF  && regionTF ) {
    templateOrder.add("3");
}
if (keyTF  && !segmentTF  && !regionTF ) {
    templateOrder.add("4");
}
if (keyTF  && segmentTF  && !regionTF ) {
    templateOrder.add("5");
}
if (keyTF  && segmentTF  && regionTF ) {
    templateOrder.add("6");
}

问题在于你正在处理一个逻辑真值表,你只需依次处理所有可能性。由于你正在处理3个独立变量,所以无法进一步压缩代码。

FFF
FTF
FTT
TFF
TTF
TTT

你实际上缺少了TFT外壳 :)


它并没有简化。也许更易读,但这不是简化。这并不能满足需求。 - lpratlong

0

只有六种可能的组合会导致 add 方法的调用。

我们注意到 OP 代码中 add 方法只被调用了一次,因为 if 语句中的条件是互斥的… 如果其中一个计算结果为 TRUE,则其他语句将返回 FALSE。

回到老派的逻辑真值表:

keyAccntId.equalsIgnoreCase("-1") |       F       |       T       |
segmentId.equalsIgnoreCase("-1")  |   F   |   T   |   F   |   T   |
regionId.equalsIgnoreCase("-1")   | F | T | F | T | F | T | F | T |
----------------------------------+---+---+---+---+---+---+---+---+
templateOrder.add("1");           | y | - | - | - | - | - | - | - |
templateOrder.add("2");           | - | - | y | - | - | - | - | - |
templateOrder.add("3");           | - | - | - | y | - | - | - | - |
templateOrder.add("4");           | - | - | - | - | y | - | - | - |
templateOrder.add("5");           | - | - | - | - | - | - | y | - |
templateOrder.add("6");           | - | - | - | - | - | - | - | y |
----------------------------------+---+---+---+---+---+---+---+---+

如果结果值与条件更好地“对齐”,那么您可以减少比较的次数。
int n = 0;
if (keyAccntId.equalsIgnoreCase("-1") {
  n += 4;
} 
if (segmentId.equalsIgnoreCase("-1") {
  n += 2;
}  
if (regionId.equalsIgnoreCase("-1") {
  n += 1;
}
templateOrder.add(String.valueOf(n));

注意:上面的代码与原始代码不等同。为了使其执行相同的操作,我们需要添加一个条件测试,以便在n为1或5时不调用add方法,并将n的值转换为指定的字符串参数值:

n    arg
---  ----
0    "1"
1    - 
2    "2"
3    "3"
4    "4"
5    -
6    "5"
7    "6"

逻辑表格应该长这样:

keyAccntId.equalsIgnoreCase("-1") |       F       |       T       |
segmentId.equalsIgnoreCase("-1")  |   F   |   T   |   F   |   T   |
regionId.equalsIgnoreCase("-1")   | F | T | F | T | F | T | F | T |
----------------------------------+---+---+---+---+---+---+---+---+
n += 4;                           | - | - | - | - | y | y | y | y |
n += 2;                           | - | - | y | y | - | - | y | y |
n += 1;                           | - | y | - | y | - | y | - | y |
templateOrder.add(arg);           | y | - | y | y | y | - | y | y |
----------------------------------+---+---+---+---+---+---+---+---+

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接