如何在Java中0 * ...之后跳过评估算术表达式的剩余部分

时间:2017-04-29 15:11:34

标签: java arithmetic-expressions

在逻辑表达式中,如果没有必要,将跳过剩余部分

<fragment>

用算术表达式实现同样的好方法是什么?

boolean b = false && checkSomething( something)
//checkSomething() doesn't get called

可以在*之前添加ifs。但有没有更优雅的方法来解决这个问题?没有在表达式中添加太多东西,所以表达式本身看起来尽可能接近原始

为什么我不想使用ifs? 来自

int i = 0 * calculateSomethig ( something ) 

它会变得笨重而且不清楚

return calculateA() * calculateB()
  • 8行代码而不是1,
  • 这些表达可能比a * b
  • 更复杂
  • 这些表达式代表业务逻辑,所以我想保留它们 清晰易读
  • 可能有很多人

为什么我要这么烦? 因为计算方法可能很昂贵

  • 在其他地方使用值,其中搜索和排序正在发生
  • 很多这些表达式可以一次执行(在用户事件和用户之后应该看到结果&#34;立即执行#34;
  • P(表达式中的* 0)> 0.5

2 个答案:

答案 0 :(得分:1)

&&||被称为短路运算符,因为它们不会评估JVM是否会在不评估整个表达式的情况下找到整个表达式的值。例如,JVM不必评估以下表达式的第二部分,以告诉它评估为true

6 == (2 + 4) || 8 == 9

JVM不必评估以下所有表达式,以告诉它评估为false

9 == 8 && 7 == 7

乘法运算符(*)不是短路运算符。因此,它不会那样。您可以使用if语句提到这一点。没有预定义的方法来执行此操作。

答案 1 :(得分:0)

您可以创建一个使用lambdas来懒惰地评估其参数的结构:

class LazyMul implements IntSupplier {
    private final IntSupplier [] args;

    private LazyMul(IntSupplier[] args) {
        //argument checking omitted for brevity :)
        this.args = args;
    }

    public static LazyMul of(IntSupplier ... args) {
        return new LazyMul(args);
    }

    @Override
    public int getAsInt() {
        int res = 1;
        for (IntSupplier arg: args) {
            res *= arg.getAsInt();
            if (res == 0)
                break;
        }
        return res;
    }
}

当然这甚至更长,但使用它就像LazyMul.of(this::calculateA, this::calculateB)一样简单,所以如果你多次使用它,那么每次使用if都会更好。

不幸的是,复杂(特别是嵌套)表达式的可读性受到影响,但这些是Java作为一种语言的局限性。