多重 If 语句简化

huangapple go评论79阅读模式
英文:

Multiple If Statement Reduction

问题

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")));
英文:

I'm looking for some help cleaning up the code below and reducing the number of lines. Is there a way to not set anything if the get returns a 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")));
            }

答案1

得分: 7

"can I make this more concise/terse"的明确问题的简单答案是"不能"。你不会真正得到你想要的东西,使这个更加简洁或精炼,computeIfPresent也不会给你你想要的同时保持代码可读性。

问题在于,当你试图从你的映射中检索一个键时,你将它放在collateral实例的不同字段中。这意味着像循环遍历映射这样的简单解决方案不会满足你的需求,因为你将无法获取到需要映射的确切字段,除非深入到反射中。

你这里的代码虽然冗长,但对于任何其他维护者来说都是完全可读和合理的,能够理解发生了什么。我看不到修改它的动机。

英文:

The simple answer to the overt question of, "can I make this more concise/terse" is "no". You're not really going to get what you're looking for in making this more terse or concise, nor would computeIfPresent really give you what you're looking for and keep your code readable.

The issue is that, when you go to retrieve a key from your map, you're putting it in a different field in your collateral instance. This means that trivial solutions such as looping over the map won't satisfy since you're not going to be able to get the exact field you need to map to without getting deep into reflection.

The code you have here, albeit verbose, is perfectly readable and reasonable to any other maintainer to understand what's going on. I see no incentive to change it.

答案2

得分: 2

我会在这里提供翻译的部分:

"我会提供另一个选项,因为这里的讨论比我想象的要多。有时候,将逻辑颠倒过来是有道理的(在这种情况下可能是这样,也可能不是)。不要将这一块代码放在主线代码中,而是将其移到“抵押品”(或者是类名)中。

然后,主线代码可能会被精简为类似以下的内容:

collateral.fillFromData(map); // TODO:为您的领域命名一个有意义的内容

或者它可以是一个工厂方法,或者是其他任何上下文决定的最佳方法。

“抵押品”类将封装决定哪些值将被填充以及如何根据传入的数据填充这些值的逻辑。该逻辑可能与现有逻辑完全相同(或者稍微进行重构,将其包装起来,就像k5_的第二种解决方案一样(尽管存在一些局部复杂性,我对此并不反感)。

这将初始化/填充逻辑局部化到拥有该数据的类中:这可能是合理的,也可能不合理。如果不合理,那么很可能在这里的某个地方缺少一个在调用原始代码的位置/方式上有意义的帮助程序/服务/实用程序类。"

英文:

I'll throw in another option since there's more discussion here than I thought there would be.

Sometimes it makes sense to flip logic like this on its head (it may or may not in this case). Instead of having this chunk of code in the mainline code, move it into Collateral (or whatever the classname is).

The mainline code would then get cooked down to something like:

collateral.fillFromData(map); // TODO: Name something that makes sense in your domain

Or it could be a factory method, or whatever–context would determine the best approach(es).

The Collateral class would encapsulate the logic that determines which values are filled, and how those values are filled, based on the data passed in. That logic would likely be identical to what's here already (or a brief refactoring to wrap it up as in k5_'s second solution (which I don't have a problem with despite some localized complexity).

This localizes initialization/filling logic to the class that owns that data: this may or may not be reasonable. If it isn't reasonable then it's likely there's a missing helper/service/utility class somewhere in here that makes sense in the context of where/how the original code is invoked.

答案3

得分: 0

如果实际设置为 null 没有问题,而且您只是想避免在创建 BigDecimal 时出现 NPE,我会使用以下辅助方法。

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");
英文:

If it is no problem to actually set null and you just want to avoid the npe creating the BigDecimal. I would go with this helper method.

BigDecimal getBigDecimalOrNull(Map&lt;String,String&gt; map, String key){
    String value= map.get(key);
    if (value == null){
       return null;
    }
    return new BigDecimal(value);
}

And use it with

collateral.setTotMktValue(getBigDecimalOrNull(map, &quot;Total Market Value&quot;));

If the setting null is an actual problem. You can use this helper method

void setBigDecimalWhenNotNull(Map&lt;String,String&gt; map, Consumer&lt;BigDecimal&gt; consumer, String key){
    String value= map.get(key);
    if (value == null){
       return null;
    }
    consumer.accept(new BigDecimal(value));
}

and use it with:

 setBigDecimalWhenNotNull(map, ColleralClass::setToMktValue, &quot;Total Market Value&quot;)

答案4

得分: 0

我怀疑你可以使用类似以下的代码:

Optional.ofNullable(map.get("cpn_rate")).ifPresent(rate -> collater.setCoupon(new BigDecimal(rate)));
  1. Optional.ofNullable https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#ofNullable-T- 不会因为 map.get("cpn_rate") 为 null 而出错。
  2. Optional.ifPresent 仅会在 map.get("cpn_rate") 不为 null 时执行其他操作。
英文:

I suspect you could use something like

Optional.ofNullable(map.get(&quot;cpn_rate&quot;)).ifPresent(rate =&gt; collater.setCoupon(new BigDecimal(rate)));
  1. Optional.ofNullable https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#ofNullable-T- will not blow up if map.get("cpn_rate") is null.
  2. Optional.ifPresent will only execute the other thing if map.get("cpn_rate") is not null.

答案5

得分: 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);
英文:

You can use Jackson Mapper to convert a Map to a POJO, but to be able to do that, you'll need to follow naming convention. The field name in POJO has to match with the key in your Map.

import org.codehaus.jackson.map.ObjectMapper;

final ObjectMapper mapper = new ObjectMapper();
final Collateral collateral = mapper.convertValue(map, Collateral.class);

huangapple
  • 本文由 发表于 2020年6月6日 00:50:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/62220374.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定