JAVA8中使用多个if else if语句和&&条件

6
我希望您能将以下代码转换为Java 8最佳代码实践。
if(i==0 && j==0) {
    return 1;    
} else if (i==0 && j==1) {
    return 2;
} else if (i==1 && j==0) {
    return 3;
} else if (i==1 && j==1) {
    return 4;
} 

编辑:OP在问题的评论中发表了帖子

if(counterFlag==0 && priorityEnable==0) { 
    return 0; 
} else if (counterFlag==0 && priorityEnable==1) { 
    return 1; 
} else if (counterFlag==1 && priorityEnable==0) { 
    return 2; 
} else { 
    return 3; 
}

我需要用返回语句替换这个syso。 - Jackie
1
我不确定那是不是一个例子。但是对于那段代码,你可以重构成 return i*2+j+1 - Cường Lư Quốc
1
@FedericoklezCulloca,“最佳实践”是用“聪明的解决方案”替换此代码。另一种选择是将此过程应用于调用者,但OP没有展示,因为这些返回值看起来很像还会有另一个类似的测试代码或开关语句... - Holger
1
@Holger 我非常尊重您的意见,但我认为最佳实践(不考虑周围代码)是将其保留原样。它非常易读。 - Federico klez Culloca
我不同意你们的观点。没有最佳实践。 - Stephen C
显示剩余3条评论
4个回答

4

我能想到的最好的解决ORIGINAL问题但不会变得晦涩/难读的方法是:

if (i == 0) {
    if (j == 0) {
        System.out.println("print something ");     
    } else if (j == 1) {
         System.out.println("print something ");     
    }
} else if (i == 1) {
    if ( j== 0) {
        System.out.println("print something ");     
    } else if (j == 1) {
         System.out.println("print something ");     
    }
}

请注意不要做一些诡计性的事情,例如将数字组合成字符串并将其用作散列键。这样做是很浪费资源的,而且存在语义陷阱。

对于此问题,有一个简洁的解决方案:

if (i >= 0 && i <= 1 && j >= 0 && j <= 1) {
    return 1 + i + 2 * j;
}

......但我不确定我会在我的代码中写下这样的东西。 它很晦涩,这种巧妙性可能会阻止JIT编译器生成最优化的代码2


1- 我不主张这是"最佳实践"。 这只是我的观点。
2- 那可能是不相关的......


2
您可以这样使用Map<String,Supplier<Integer>>
Map<String, Supplier<Integer>> map = new HashMap<>();

    map.put("00",()-> logic1());
    map.put("01",()-> 2);
    map.put("10",()-> 3);
    map.put("11",()-> 4);

您可以传递每个返回Integer作为结果的方法。

private int logic1(){
  //your logic... 
  return 1;
}

并且可以这样使用:

map.get(String.valueOf(i)+String.valueOf(j)).get();

1
抱歉我要挑剔你的回答,但是为什么要使用Supplier,而不是一个简单的Integer就可以解决问题呢? - Federico klez Culloca
可能 OP 想要一个复杂的函数。 - Hadi J
2
那么为什么要止步于此呢?为什么不尝试一下 Supplier<Supplier<Integer>> 呢? - Dioxin
@VinceEmigh 将供应商作为值传递,因为 OP 可以为每个条件声明一个方法。正如您所知,供应商是惰性的,只有在调用 get 方法时才会被调用。请查看我的更新答案! - Hadi J

1
注意:在您的示例中,您将3作为默认返回值,因此如果例如i=2或j=2,则会返回3。这是否是预期行为?我将提供假定i和j的值始终为0或1的示例。
针对您的特定示例:
这似乎是一个很好的折衷方案,它更短并且足够容易阅读:
if(counterFlag==0) {
    return priorityEnable == 0 ? 0 : 1;
}
return priorityEnable == 0 ? 2 : 3;

对于更复杂的情况(即3、4或更多个变量):我会选择类似这样的方法:

Map<int[], Integer> map = new HashMap<>();
map.put(new int[] {0, 0}, 0);
map.put(new int[] {0, 1}, 1);
map.put(new int[] {1, 0}, 2);
map.put(new int[] {1, 1}, 3);

return map.entrySet().stream()
        .filter(e -> e.getKey()[0] == counterFlag)
        .filter(e -> e.getKey()[1] == priorityEnable)
        .map(Map.Entry::getValue)
        .findFirst()
        .orElseThrow(IllegalArgumentException::new);

编辑: @Holger指出,"使用HashMap并进行线性搜索是一种浪费。使用IntBuffer作为键,您可以通过get执行直接查找"

这是一个很好的点子,我试过了,我认为这就是他的意思:

Map<IntBuffer, Integer> map = new HashMap<>();
map.put(IntBuffer.wrap(new int[] {0, 0}), 0);
map.put(IntBuffer.wrap(new int[] {0, 1}), 1);
map.put(IntBuffer.wrap(new int[] {1, 0}), 2);
map.put(IntBuffer.wrap(new int[] {1, 1}), 3);

IntBuffer intBuffer = IntBuffer.wrap(new int[] {counterFlag, priorityEnable});
return map.get(intBuffer);

1
使用HashMap然后进行线性搜索是一种浪费。使用IntBuffer作为键,您可以通过get进行直接查找... - Holger
@Holger以前从未接触过IntBuffers,我会在我的答案中进行编辑。 - Bentaye
1
@Holger 我已经按照你的建议编辑了我的答案,这是你想要的吗?它可以工作,并且确实是更高效的查找。 - Bentaye
1
是的,就是这样。 - Holger

0

你也可以做到这一点...

int value = (i==0 && j==0)?1:(i==0 && j==1)?2:(i==1 && j==0)?3:(i==1 && j==1)?4:null;

这将导致Coverity问题,因为null永远不会到达。 - Jackie

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