Java的简短形式如果Else声明

时间:2017-02-02 10:30:38

标签: java if-statement ternary-operator short

我有一个检查空值的方法。有没有办法减少方法中的行数?目前,代码看起来“脏”:

private int similarityCount (String one, String two) {

    if (one == null && two == null) {
        return 1;
    } else if (one == null && two != null) {
        return 2;
    } else if (one != null && two == null) {
        return 3;
    } else {
        if(isMatch(one, two))
             return 4;
        return 5;
    }

}

10 个答案:

答案 0 :(得分:62)

private int similarityCount (String one, String two) {

    if (one == null && two == null) {
        return 1;
    } 

    if (one == null) {
        return 2;
    } 

    if (two == null) {
        return 3;
    } 

    if (isMatch(one, two)) {
        return 4;
    }
    return 5;
}

答案 1 :(得分:33)

在这种情况下,我更喜欢嵌套条件:

private int similarityCount (String one, String two) {
    if (one==null) {
        if (two==null) {
            return 1;
        } else {
            return 2;
        }
    } else {
        if (two==null) {
            return 3;
        } else {
            return isMatch(one, two) ? 4 : 5;
        }
    }
}

当然,您可以使用更多的三元条件运算符来实现更短的版本。

private int similarityCount (String one, String two) {  
    if (one==null) {
        return (two==null) ? 1 : 2;
    } else {
        return (two==null) ? 3 : isMatch(one, two) ? 4 : 5;
    }
}

甚至(现在这种可读性越来越差):

private int similarityCount (String one, String two) {  
    return (one==null) ? ((two==null) ? 1 : 2) : ((two==null) ? 3 : isMatch(one, two) ? 4 : 5);
}

答案 2 :(得分:25)

由于函数的实际目的似乎是通过匹配它们来处理非null对象,所以我会在开头的一个guard语句中处理所有null个检查。

然后,一旦你确定没有参数是null,你就可以处理实际的逻辑:

private int similarityCount(String a, String b) {
    if (a == null || b == null) {
        return a == b ? 1 : a == null ? 2 : 3;
    }

    return isMatch(a, b) ? 4 : 5;
}

这比其他选项更简洁,更易读。

那就是说,真正的函数通常不会返回这样的数字代码。除非你的方法被简化以证明问题,否则我强烈建议你重新考虑逻辑,而是写下类似于下面的内容:

private boolean similarityCount(String a, String b) {
    if (a == null || b == null) {
        throw new NullPointerException();
    }

    return isMatch(a, b);
}

或者:

private boolean similarityCount(String a, String b) {
    if (a == null) {
        throw new IllegalArgumentException("a");
    }
    if (b == null) {
        throw new IllegalArgumentException("b");
    }

    return isMatch(a, b);
}

这些方法更为传统。另一方面,它们可能会触发异常。我们可以通过在Java 8中返回java.util.Optional<Boolean>来避免这种情况:

private Optional<Boolean> similarityCount(String a, String b) {
    if (a == null || b == null) {
        return Optional.empty();
    }

    return Optional.of(isMatch(a, b));
}

乍一看,这似乎并不比返回nulloptionals are in fact far superior更好。

答案 3 :(得分:9)

代码对我来说看起来很清楚。您可以使用嵌套和三元运算符缩短它:

if(one==null) {
    return two==null ? 1 : 2;
}
if(two==null) {
    return 3;
} 
return isMatch(one,two) ? 4 : 5;

答案 4 :(得分:5)

可以使用Java条件运算符在一行中完成:

return (one==null?(two==null?1:2):(two==null?3:(isMatch(one,two)?4:5)));

答案 5 :(得分:4)

可以创建伪查找表。有些人对嵌套的三元运算符不满意,并且它高度依赖于空白以便于阅读,但它可以是一种非常易读的条件返回方法:

private int similarityCount (String one, String two) {
    return (one == null && two == null) ? 1
         : (one == null && two != null) ? 2
         : (one != null && two == null) ? 3
         : isMatch(one, two)            ? 4
         :                                5;
}

答案 6 :(得分:1)

我喜欢表情。

private static int similarityCount (String one, String two) {    
    return one == null ? 
        similarityCountByTwoOnly(two) : 
        two == null ? 3 : (isMatch(one, two) ? 4 : 5)
    ;
}

private static int similarityCountByTwoOnly(String two) {
    return two == null ? 1 : 2;
}

顺便说一句,我可能会质疑你为什么要这样做。我会假设您在评估它之后会对返回的整数进行某种检查,并根据它对您的逻辑进行分支。如果是这种情况,那么您对方法的用户需要理解隐含在整数值中的契约时,对null进行了一次不太可读的检查。

此外,这里有一个简单的解决方案,当你需要检查字符串是否相等时,它们可能为空:

boolean same = one == null ? two == null : one.equals(two);

答案 7 :(得分:0)

摆脱IF语句非常有趣。使用Map是这样做的一种方式。由于调用了isMatch,它完全不适合这种情况,但是我提供它作为一种替代方法,将similarityCount方法体切割为一条带有一个IF的单行

以下代码有两个IF。如果GetOrDefault没有评估第二个参数,它可以减少到一个。不幸的是,它确实需要在isMatch中进行null检查。

如果你愿意的话,你可以继续这么做。例如,isMatch可以返回4或5而不是布尔值,这将有助于您进一步简化。

import com.google.common.collect.ImmutableMap;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

import java.util.Map;

public class SimilarityCount {

    private Map<SimilarityCountKey, Integer> rtn = ImmutableMap.of(new SimilarityCountKey(null, null), 1, new SimilarityCountKey(null, ""), 2, new SimilarityCountKey("", null), 3);

    public int similarityCount(String one, String two) {
        return rtn.getOrDefault(new SimilarityCountKey(one, two), isMatch(one, two) ? 4 : 5);
    }

    private boolean isMatch(String one, String two) {
        if (one == null || two == null) {
            return false;
        }
        return one.equals(two);
    }

    private class SimilarityCountKey {
        private final boolean one;
        private final boolean two;

        public SimilarityCountKey(String one, String two) {
            this.one = one == null;
            this.two = two == null;
        }

        @Override
        public boolean equals(Object obj) {
            return EqualsBuilder.reflectionEquals(this, obj);
        }

        @Override
        public int hashCode() {
            return HashCodeBuilder.reflectionHashCode(this);
        }
    }
}

如果其他人对另一个解决方案感到不满,这里有一些测试可以帮助你开始

 import org.junit.Assert;
import org.junit.Test;

import static org.hamcrest.CoreMatchers.is;

public class SimilarityCountTest {

    @Test
    public void one(){
        Assert.assertThat(new SimilarityCount().similarityCount(null,null), is(1));
    }

    @Test
    public void two(){
        Assert.assertThat(new SimilarityCount().similarityCount(null,""), is(2));
    }

    @Test
    public void three(){
        Assert.assertThat(new SimilarityCount().similarityCount("",null), is(3));
    }

    @Test
    public void four(){
        Assert.assertThat(new SimilarityCount().similarityCount("",""), is(4));
    }

    @Test
    public void five(){
        Assert.assertThat(new SimilarityCount().similarityCount("a","b"), is(5));
    }

}

答案 8 :(得分:0)

如果两者都不为null,则应该稍快一些,因为它只执行一次&#39;如果&#39;在这种情况下的陈述。

private int similarityCount (String one, String two) {

    if (one == null || two == null) {  // Something is null
        if (two != null) { // Only one is null
            return 2;
        }

        if (one != null) { // Only two is null
            return 3;
        }

        return 1; // Both must be null
    } 

    return isMatch(one, two) ? 4 : 5;
}

答案 9 :(得分:0)

大声笑......编程不是一场美女比赛。你的代码

if (one == null && two == null) {
        return 1;
} else if (one == null && two != null) {
        return 2;
    } else if (one != null && two == null) {
        return 3;
    } else {
        if(isMatch(one, two))
             return 4;
        return 5;
    }

并不脏,但对于非专业人士和专家来说也足够漂亮。您如何看待以下编码

return one == null && two == null ? 1:
       one == null && two != null ? 2:
       one != null && two == null ? 3:
       isMatch(one, two) ? 4 : 5;

太棒了,不是吗?嗯,对于外行人来说,对于“专家”来说,这是“伏都教”......人们不应该讨论“品味”,“政治”和“宗教”。但从表现的角度来看是如此:

  • 第一个版本更快
  • 第二个版本更笨拙(或更慢)

WHY`? 只需编译它“javac -g:none Test5 * .java”并比较生成的字节码。我做到了,结果如下:

第一版:

public class Test5 {
    public static void main(String[] args) {
        String one = "1";
        String two = "2";
        System.out.println(check(one, two));
    }
    private static int check(String one, String two) {
        if (one == null && two == null) {
                return 1;
        } else if (one == null && two != null) {
                return 2;
            } else if (one != null && two == null) {
                return 3;
            } else {
                if(isMatch(one, two))
                     return 4;
                return 5;
            }
    }
    public static boolean isMatch(String a, String b) {
        return true;
    }
}

生成了570个字节

第二版:

public class Test5a {
    public static void main(String[] args) {
        String one = "1";
        String two = "2";
        System.out.println(check(one, two));
    }
    private static int check(String one, String two) {
        return one == null && two == null ? 1:
               one == null && two != null ? 2:
               one != null && two == null ? 3:
               isMatch(one, two) ? 4 : 5;
    }
    public static boolean isMatch(String a, String b) {
        return true;
    }
}

产生581个字节

很明显,必须处理11个字节,这需要时间......应用程序的“过多”代码越多,性能就越差。