我有一个检查空值的方法。有没有办法减少方法中的行数?目前,代码看起来“脏”:
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;
}
}
答案 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));
}
乍一看,这似乎并不比返回null
但optionals 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个字节,这需要时间......应用程序的“过多”代码越多,性能就越差。