search.png
关于我
menu.png
Java review(5) && 逻辑短路

&&和||是短路运算符,
对于&&只要前一个值为假就会跳过后边的检验,对于&则会前后两个都进行判断。
对于||只要前一个为真就会跳过后边的检验,对于|则会前后两个都会判断。


    private boolean checkA() {
        System.out.println("check A");
        return true;
    }

    private boolean checkB() {
        System.out.println("check B");
        return false;
    }

    @Test
    public void test1() throws Exception {

        System.out.println("---------------------------");
        if (checkB() && checkA()) {
            System.out.println("&& ok");
        }
        System.out.println("---------------------------");
        if (checkB() & checkA()) {
            System.out.println("& ok");
        }
        System.out.println("---------------------------");
        if (checkA() || checkB()) {
            System.out.println("|| ok");
        }
        System.out.println("---------------------------");
        if (checkA() | checkB()) {
            System.out.println("| ok");
        }
        System.out.println("---------------------------");
    }

输出

---------------------------
check B
---------------------------
check B
check A
---------------------------
check A
|| ok
---------------------------
check A
check B
| ok
---------------------------

利用好这种逻辑短路可以提高性能,我们可以将需要优先判断的项放在前面(能更快进行否定判断或者肯定判断的项),从而减少判断的次数,提高性能。

我了做个实验:

以下是一个求水仙花数的小程序,水仙花数是一个三位数其各位数字的立方和等于该数本身。例如:3^3 + 7^3+ 0^3 = 370。
所以一个水仙花数要满足两个条件:

  1. 三位数其各位数字的立方和等于该数本身
  2. 是一个三位数
    /**
     * 判断是否是正的三位数
     *
     * @param num 数
     * @return 是否是三位数
     */
    private boolean isThreeDigit(int num) {
        return num >= 100 && num <= 999;
    }

    /**
     * “水仙花数”是一个三位数其各位数字的立方和等于该数本身。例如:3^3 + 7^3+ 0^3 = 370
     *
     * @param num 数
     * @return 是否是水仙花数
     */
    private boolean isNarcissisticNum(int num) {
        int n1 = num % 10;
        int n2 = (num / 10) % 10;
        int n3 = (num / 100) % 10;
        double sum = Math.pow(n1, 3) + Math.pow(n2, 3) + Math.pow(n3, 3);
        return Math.round(sum) == num;
    }
    
    @Test
    public void test2() throws Exception {
        long start = System.currentTimeMillis();
        Random random = new Random();
        int FIND_TIMES = 10000;
        
        for (int i = 0; i < FIND_TIMES; i ++) {
            int num = random.nextInt(10000);
            if (isNarcissisticNum(num) && isThreeDigit(num)) {
                System.out.println("find " + num);
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("先判断水仙花数、再判断三位数:" + (end - start) + "ms");


        start = System.currentTimeMillis();
        random = new Random();
        for (int i = 0; i < FIND_TIMES; i ++) {
            int num = random.nextInt(10000);
            if (isThreeDigit(num) && isNarcissisticNum(num)) {
                System.out.println("find " + num);
            }
        }
        end = System.currentTimeMillis();
        System.out.println("先判断判断三位数、再判断水仙花数:" + (end - start) + "ms");
    }

我设立了一个对照实验:

  1. 先判断是否满足水仙花数的规则,再判断是否满足三位数
  2. 先判断是否满足三位数,再判断是否满足水仙花数的规则

使用随机数判断10000次,以下是三次运行结果:

find 370
find 371
先判断水仙花数、再判断三位数:14ms
find 371
find 153
find 153
find 153
find 371
find 407
先判断判断三位数、再判断水仙花数:4ms
find 407
先判断水仙花数、再判断三位数:18ms
find 153
find 371
find 371
find 371
先判断判断三位数、再判断水仙花数:3ms
find 407
find 370
find 407
find 153
find 370
find 370
先判断水仙花数、再判断三位数:16ms
先判断判断三位数、再判断水仙花数:2ms

可以看到合理的运用逻辑短路,可以将运行时间缩短数倍以上。

版权声明

知识共享许可协议 本文章由作者“衡于墨”创作,转载请注明出处,未经允许禁止用于商业用途

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。
发布时间:2019年11月28日 12:53:59

评论区#

还没有评论哦,期待您的评论!

关闭特效