有没有办法检查 Lambda 变量的显式类型?
Is there a way to check for explicit types on Lambda variables?
接受这个 Lambda:
final List<String> badKeys = pivMap.entrySet().stream()
.filter(entry -> StringUtils.trimToNull(entry.getValue()) == null || entry.getValue().equals("{}") || entry.getValue().equals("{ }"))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
我们要确保 Lambda 变量有明确的类型:
final List<String> badKeys = pivMap.entrySet().stream()
.filter((final Map.Entry<String, String> entry) -> StringUtils.trimToNull(entry.getValue()) == null || entry.getValue().equals("{}") || entry.getValue().equals("{ }"))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
有没有办法使用 puppycrawl checkstyle 来检查上面的 lambda 表达式中是否存在类型?在这种情况下,变量的类型声明是:(final Map.Entry<String, String> entry)
这可以通过 MatchXPathCheck 实现:
配置:
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd">
<module name="Checker">
<property name="charset" value="UTF-8"/>
<property name="haltOnException" value="true"/>
<property name="severity" value="error"/>
<module name="TreeWalker">
<module name="MatchXpath">
<property name="query" value="//LAMBDA[IDENT][1]"/>
<message key="matchxpath.match"
value="Lambda parameters must have type."/>
</module>
</module>
</module>
这里我们使用 XPath 表达式来检查 IDENT
是否是 lambda 的第一个子代,这意味着在这种情况下它不是类型化的。
Java 示例:
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
public class MyClass {
void badLambda(Map<String, String> pivMap) {
final List<String> badKeys = pivMap.entrySet().stream()
.filter(entry -> StringUtils.trimToNull(entry.getValue()) == null // violation
|| entry.getValue().equals("{}")
|| entry.getValue().equals("{ }"))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}
void goodLambda(Map<String, String> pivMap) {
final List<String> badKeys = pivMap.entrySet().stream()
.filter((final Map.Entry<String, String> entry) -> StringUtils.trimToNull(entry.getValue()) == null // ok
|| entry.getValue().equals("{}")
|| entry.getValue().equals("{ }"))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}
}
结果:
➜ src java -jar checkstyle-8.41-all.jar -c config.xml MyClass.java
Starting audit...
[ERROR] MyClass.java:11:31: Lambda parameters must have type. [MatchXpath]
Audit done.
Checkstyle ends with 1 errors.
接受这个 Lambda:
final List<String> badKeys = pivMap.entrySet().stream()
.filter(entry -> StringUtils.trimToNull(entry.getValue()) == null || entry.getValue().equals("{}") || entry.getValue().equals("{ }"))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
我们要确保 Lambda 变量有明确的类型:
final List<String> badKeys = pivMap.entrySet().stream()
.filter((final Map.Entry<String, String> entry) -> StringUtils.trimToNull(entry.getValue()) == null || entry.getValue().equals("{}") || entry.getValue().equals("{ }"))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
有没有办法使用 puppycrawl checkstyle 来检查上面的 lambda 表达式中是否存在类型?在这种情况下,变量的类型声明是:(final Map.Entry<String, String> entry)
这可以通过 MatchXPathCheck 实现:
配置:
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd">
<module name="Checker">
<property name="charset" value="UTF-8"/>
<property name="haltOnException" value="true"/>
<property name="severity" value="error"/>
<module name="TreeWalker">
<module name="MatchXpath">
<property name="query" value="//LAMBDA[IDENT][1]"/>
<message key="matchxpath.match"
value="Lambda parameters must have type."/>
</module>
</module>
</module>
这里我们使用 XPath 表达式来检查 IDENT
是否是 lambda 的第一个子代,这意味着在这种情况下它不是类型化的。
Java 示例:
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
public class MyClass {
void badLambda(Map<String, String> pivMap) {
final List<String> badKeys = pivMap.entrySet().stream()
.filter(entry -> StringUtils.trimToNull(entry.getValue()) == null // violation
|| entry.getValue().equals("{}")
|| entry.getValue().equals("{ }"))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}
void goodLambda(Map<String, String> pivMap) {
final List<String> badKeys = pivMap.entrySet().stream()
.filter((final Map.Entry<String, String> entry) -> StringUtils.trimToNull(entry.getValue()) == null // ok
|| entry.getValue().equals("{}")
|| entry.getValue().equals("{ }"))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
}
}
结果:
➜ src java -jar checkstyle-8.41-all.jar -c config.xml MyClass.java
Starting audit...
[ERROR] MyClass.java:11:31: Lambda parameters must have type. [MatchXpath]
Audit done.
Checkstyle ends with 1 errors.