[SonarLint]:使这个匿名内部 class 成为 lambda
[SonarLint]: make this anonymous inner class a lambda
下面的代码有效,但我收到了来自 SonarLint 的通知,因为我在流中使用匿名 class 而不是 lambda 表达式,而且我不知道如何改进下面的代码来避免通知:
Properties prop = new Properties();
Properties temp = new Properties();
//... add some values and keys in prop and temp
prop.putAll(temp.entrySet().stream()
.filter( entry -> !prop.containsKey(entry.getKey()))
.map( new Function<Entry<Object, Object>, Entry<String, String>>(){
@Override
public Entry<String, String> apply(Entry<Object, Object> entry) {
return new Entry<String, String>() {
@Override
public String setValue(String value) {
return value.trim().toLowerCase();
}
@Override
public String getValue() {
return ((String) entry.getValue()).trim().toLowerCase();
}
@Override
public String getKey() {
return ((String) entry.getKey()).trim().toLowerCase();
}
};
}
})
.collect(Collectors.toMap(Entry<String,String>::getKey, Entry<String,String>::getValue)));
代码说明:
我使用 java.util 的属性 class,不幸的是,属性 returns Entry<Object, Object>
的 entrySet
而不是 Entry<String, String>
。我想 "join" 这两个属性对象将键和值小写。因此,地图允许在 Entry<String,String>
中转换 Entry<Object, Object>
。这就是为什么,有一个匿名class。
声纳建议更换
prop.putAll(temp.entrySet().stream()
.filter( entry -> !prop.containsKey(entry.getKey()))
.map( new Function<Entry<Object, Object>, Entry<String, String>>(){
@Override
public Entry<String, String> apply(Entry<Object, Object> entry) {
return new Entry<String, String>() {
@Override
public String setValue(String value) {
return value.trim().toLowerCase();
}
@Override
public String getValue() {
return ((String) entry.getValue()).trim().toLowerCase();
}
@Override
public String getKey() {
return ((String) entry.getKey()).trim().toLowerCase();
}
};
}
})
.collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
(我删除了收集器中不需要的类型参数)
和
prop.putAll(temp.entrySet().stream()
.filter( entry -> !prop.containsKey(entry.getKey()))
.map(entry -> new Entry<String, String>() {
@Override
public String setValue(String value) {
return value.trim().toLowerCase();
}
@Override
public String getValue() {
return ((String) entry.getValue()).trim().toLowerCase();
}
@Override
public String getKey() {
return ((String) entry.getKey()).trim().toLowerCase();
}
})
.collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
它使用 lambda 表达式替代匿名内部 class 实现 Function
,而不是 Entry
实现。
不过,在这里手动实现 Entry
接口是没有意义的,尤其是在这种违反合同的方式中使用实际上不需要的 setValue
方法。您只需要一个不可变的 Entry
实例,因此,您可以创建现有 class 的实例:
prop.putAll(temp.entrySet().stream()
.filter( entry -> !prop.containsKey(entry.getKey()))
.map(entry -> new AbstractMap.SimpleImmutableEntry<>(
((String) entry.getKey()).trim().toLowerCase(),
((String) entry.getValue()).trim().toLowerCase()))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
作为最后的改进,在传递给 toMap
收集器的函数中执行转换时,您可以完全摆脱 Entry
实例:
prop.putAll(temp.entrySet().stream()
.filter( entry -> !prop.containsKey(entry.getKey()))
.collect(Collectors.toMap(
entry -> ((String) entry.getKey()) .trim().toLowerCase(),
entry -> ((String) entry.getValue()).trim().toLowerCase())));
下面的代码有效,但我收到了来自 SonarLint 的通知,因为我在流中使用匿名 class 而不是 lambda 表达式,而且我不知道如何改进下面的代码来避免通知:
Properties prop = new Properties();
Properties temp = new Properties();
//... add some values and keys in prop and temp
prop.putAll(temp.entrySet().stream()
.filter( entry -> !prop.containsKey(entry.getKey()))
.map( new Function<Entry<Object, Object>, Entry<String, String>>(){
@Override
public Entry<String, String> apply(Entry<Object, Object> entry) {
return new Entry<String, String>() {
@Override
public String setValue(String value) {
return value.trim().toLowerCase();
}
@Override
public String getValue() {
return ((String) entry.getValue()).trim().toLowerCase();
}
@Override
public String getKey() {
return ((String) entry.getKey()).trim().toLowerCase();
}
};
}
})
.collect(Collectors.toMap(Entry<String,String>::getKey, Entry<String,String>::getValue)));
代码说明:
我使用 java.util 的属性 class,不幸的是,属性 returns Entry<Object, Object>
的 entrySet
而不是 Entry<String, String>
。我想 "join" 这两个属性对象将键和值小写。因此,地图允许在 Entry<String,String>
中转换 Entry<Object, Object>
。这就是为什么,有一个匿名class。
声纳建议更换
prop.putAll(temp.entrySet().stream()
.filter( entry -> !prop.containsKey(entry.getKey()))
.map( new Function<Entry<Object, Object>, Entry<String, String>>(){
@Override
public Entry<String, String> apply(Entry<Object, Object> entry) {
return new Entry<String, String>() {
@Override
public String setValue(String value) {
return value.trim().toLowerCase();
}
@Override
public String getValue() {
return ((String) entry.getValue()).trim().toLowerCase();
}
@Override
public String getKey() {
return ((String) entry.getKey()).trim().toLowerCase();
}
};
}
})
.collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
(我删除了收集器中不需要的类型参数)
和
prop.putAll(temp.entrySet().stream()
.filter( entry -> !prop.containsKey(entry.getKey()))
.map(entry -> new Entry<String, String>() {
@Override
public String setValue(String value) {
return value.trim().toLowerCase();
}
@Override
public String getValue() {
return ((String) entry.getValue()).trim().toLowerCase();
}
@Override
public String getKey() {
return ((String) entry.getKey()).trim().toLowerCase();
}
})
.collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
它使用 lambda 表达式替代匿名内部 class 实现 Function
,而不是 Entry
实现。
不过,在这里手动实现 Entry
接口是没有意义的,尤其是在这种违反合同的方式中使用实际上不需要的 setValue
方法。您只需要一个不可变的 Entry
实例,因此,您可以创建现有 class 的实例:
prop.putAll(temp.entrySet().stream()
.filter( entry -> !prop.containsKey(entry.getKey()))
.map(entry -> new AbstractMap.SimpleImmutableEntry<>(
((String) entry.getKey()).trim().toLowerCase(),
((String) entry.getValue()).trim().toLowerCase()))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue)));
作为最后的改进,在传递给 toMap
收集器的函数中执行转换时,您可以完全摆脱 Entry
实例:
prop.putAll(temp.entrySet().stream()
.filter( entry -> !prop.containsKey(entry.getKey()))
.collect(Collectors.toMap(
entry -> ((String) entry.getKey()) .trim().toLowerCase(),
entry -> ((String) entry.getValue()).trim().toLowerCase())));