如何降低方法的认知复杂度
How to reduce cognitive complexity of a method
我想降低以下方法的认知复杂度。怎么做 ?以我的观点,我不能,但我对这件事没有经验
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (!(obj instanceof Bean)) return false;
Bean other = (Bean) obj;
if (property1== null) {
if (other.property1!= null) return false;
} else if (!property1.equals(other.property1)) return false;
if (property2== null) {
if (other.property2!= null) return false;
} else if (!property2.equals(other.property2)) return false;
if (property3== null) {
if (other.property3!= null) return false;
} else if (!property3.equals(other.property3)) return false;
if (property4== null) {
if (other.property4!= null) return false;
} else if (!property4.equals(other.property4)) return false;
return true;
}
您可以使用 Java 的 Objects.equals
轻松检查字段是否相等。如果给定的两个对象相等或都是 null
,它将 return true
,否则 false
.
if (this == obj) return true;
if (obj == null || this.getClass() != obj.getClass()) return false;
Bean other = (Bean) obj;
return Objects.equals(this.property1, other.property1)
&& Objects.equals(this.property2, other.property2)
&& ...;
作为替代方案,Apache Commons EqualsBuilder
也提供了一个 reflectionEquals
方法,可以自动从您的 class 获取所有字段并进行比较。虽然这种方法可能会因为反射而变慢,并且您对正在发生的事情的控制较少。
我假设 Bean
是您自己的 class。您可以将 property1
、property2
等放入一个数组中。然后你的 equals 变成:
public boolean equals( Object obj )
{
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Bean))
return false;
Bean other = (Bean) obj;
for (int i = 0; i < properties.length; i++)
if (properties[i] == null)
{
if (other.properties[i] != null)
return false;
}
else if (!properties[i].equals( other.properties[i] ))
return false;
return true;
}
这还使您可以在以后灵活地添加更多 属性 值,而无需修改 equals()
方法。
实用程序 class 的方法 equal
可以实现接受 Bean
属性的 getter 作为可变参数:
public class Are {
static <T,R> boolean equal(T x1, T x2, Function<T, R> ... getters) {
return x1 == x2 || Arrays.stream(getters)
.allMatch(get -> Objects.equals(get.apply(x1), get.apply(x2)));
}
}
那么Bean::equals
可以这样写:
// class Bean
@Override
public boolean equals(Object obj) {
if (obj == null || this.getClass() != obj.getClass()) {
return false;
}
Bean that = (Bean) obj;
return Are.equal(this, that,
Bean::getProperty1, Bean::getProperty2, Bean::getProperty3, Bean::getProperty4
);
}
我想降低以下方法的认知复杂度。怎么做 ?以我的观点,我不能,但我对这件事没有经验
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (!(obj instanceof Bean)) return false;
Bean other = (Bean) obj;
if (property1== null) {
if (other.property1!= null) return false;
} else if (!property1.equals(other.property1)) return false;
if (property2== null) {
if (other.property2!= null) return false;
} else if (!property2.equals(other.property2)) return false;
if (property3== null) {
if (other.property3!= null) return false;
} else if (!property3.equals(other.property3)) return false;
if (property4== null) {
if (other.property4!= null) return false;
} else if (!property4.equals(other.property4)) return false;
return true;
}
您可以使用 Java 的 Objects.equals
轻松检查字段是否相等。如果给定的两个对象相等或都是 null
,它将 return true
,否则 false
.
if (this == obj) return true;
if (obj == null || this.getClass() != obj.getClass()) return false;
Bean other = (Bean) obj;
return Objects.equals(this.property1, other.property1)
&& Objects.equals(this.property2, other.property2)
&& ...;
作为替代方案,Apache Commons EqualsBuilder
也提供了一个 reflectionEquals
方法,可以自动从您的 class 获取所有字段并进行比较。虽然这种方法可能会因为反射而变慢,并且您对正在发生的事情的控制较少。
我假设 Bean
是您自己的 class。您可以将 property1
、property2
等放入一个数组中。然后你的 equals 变成:
public boolean equals( Object obj )
{
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Bean))
return false;
Bean other = (Bean) obj;
for (int i = 0; i < properties.length; i++)
if (properties[i] == null)
{
if (other.properties[i] != null)
return false;
}
else if (!properties[i].equals( other.properties[i] ))
return false;
return true;
}
这还使您可以在以后灵活地添加更多 属性 值,而无需修改 equals()
方法。
实用程序 class 的方法 equal
可以实现接受 Bean
属性的 getter 作为可变参数:
public class Are {
static <T,R> boolean equal(T x1, T x2, Function<T, R> ... getters) {
return x1 == x2 || Arrays.stream(getters)
.allMatch(get -> Objects.equals(get.apply(x1), get.apply(x2)));
}
}
那么Bean::equals
可以这样写:
// class Bean
@Override
public boolean equals(Object obj) {
if (obj == null || this.getClass() != obj.getClass()) {
return false;
}
Bean that = (Bean) obj;
return Are.equal(this, that,
Bean::getProperty1, Bean::getProperty2, Bean::getProperty3, Bean::getProperty4
);
}