我正在寻找一些帮助来清理下面的代码并减少行数。如果get返回null,是否可以不设置任何内容?
if (map.get("cpn_rate") != null) {
collateral.setCoupon(new BigDecimal(map.get("cpn_rate")));
}
if (map.get("Price") != null) {
collateral.setPrice(new BigDecimal(map.get("Price")));
}
if (map.get("Par") != null) {
collateral.setPar(new BigDecimal(map.get("Par")));
}
if (map.get("mkt_val") != null) {
collateral.setMarketValue(new BigDecimal(map.get("mkt_val")));
}
if (map.get("Accrued Intr") != null) {
collateral.setAccurInterest(new BigDecimal(map.get("Accrued Intr")));
}
if (map.get("Total Market Value") != null) {
collateral.setTotMktValue(new BigDecimal(map.get("Total Market Value")));
}
答案 0 :(得分:7)
对于“可以让我变得更简洁/简洁”这个明显问题的简单答案是“否”。使computeIfPresent
变得更简洁或简洁,您并不会真正获得所需的内容,file set也不会真正为您提供所需的内容 并保持代码可读性
问题在于,当您从地图中检索密钥时,会将其放在collateral
实例的其他字段中。这意味着诸如遍历地图这样的琐碎解决方案将无法满足您的需求,因为您将无法获得需要映射到的 exact 字段,而无需深入思考。
您在这里拥有的代码虽然很冗长,但是对于任何其他维护人员来说,它都是完全可读且合理的,以了解发生了什么事情。我认为没有动力去改变它。
答案 1 :(得分:2)
我将提出另一种选择,因为这里的讨论超出了我的预期。
有时候,像这样翻转逻辑是有意义的(在这种情况下可能会也可能不会)。不用在主线代码中包含这段代码,而是将其移至Collateral
(或任何类名)中。
然后将主线代码简化为:
collateral.fillFromData(map); // TODO: Name something that makes sense in your domain
或者它可以是工厂方法,或者可以由上下文确定最佳方法。
Collateral
类将封装逻辑,该逻辑根据传入的数据确定填充哪些值以及如何填充这些值。该逻辑可能与已经在这里了(或者像k5_的第二个解决方案一样进行了简短的重构,将其包装起来(尽管有些局部的复杂性,但我没有问题)。
这会将初始化/填充逻辑本地化到拥有该数据的类:这可能是合理的,也可能是不合理的。如果不合理,则可能是这里缺少某个帮助程序/服务/实用程序类,这在调用原始代码的位置/方式方面很有意义。
答案 2 :(得分:0)
如果实际上设置null
没问题,而您只是想避免npe创建BigDecimal。我会使用这种辅助方法。
BigDecimal getBigDecimalOrNull(Map<String,String> map, String key){
String value= map.get(key);
if (value == null){
return null;
}
return new BigDecimal(value);
}
并与
一起使用collateral.setTotMktValue(getBigDecimalOrNull(map, "Total Market Value"));
如果设置null
是实际问题。您可以使用这种帮助方法
void setBigDecimalWhenNotNull(Map<String,String> map, Consumer<BigDecimal> consumer, String key){
String value= map.get(key);
if (value == null){
return null;
}
consumer.accept(new BigDecimal(value));
}
并将其用于:
setBigDecimalWhenNotNull(map, ColleralClass::setToMktValue, "Total Market Value")
答案 3 :(得分:0)
我怀疑你可以使用类似的东西
Optional.ofNullable(map.get("cpn_rate")).ifPresent(rate => collater.setCoupon(new BigDecimal(rate)));
答案 4 :(得分:0)
您可以使用Jackson Mapper将Map转换为POJO,但是要做到这一点,您需要遵循命名约定。 POJO中的字段名称必须与Map中的键匹配。
import org.codehaus.jackson.map.ObjectMapper;
final ObjectMapper mapper = new ObjectMapper();
final Collateral collateral = mapper.convertValue(map, Collateral.class);