2014-12-19 52 views
1

在我工作的代码,现在我遇到了下面的一段:双重检查是否存在地图元素?

PartnerReportItem item = (map.get(partnerId) == null) ? null 
    : map.get(partnerId).get(platform); //1, check for existence 

if (item == null) { 
    item = new PartnerReportItem(); 
    item.setPlatform(platform); 
    item.setPartnerId(partnerId); 
    item.setPartnerEmail(partner.getEmail()); 
    item.setPartnerPaymentDetails(paymentDetails); 
    item.setPartnerCoef(partner.getCoef()); 
    item.setExchangeMap(exchangeMap); 

    if (!map.containsKey(partnerId)) //2, double check for existence?? 
     map.put(partnerId, new HashMap<Platform, PartnerReportItem>()); 
    map.get(partnerId).put(platform, item); 
} 

我很困惑的//1//2,因为我认为// 2 unneccesary这里。我们已经检查了地图中是否存在partnerId元素。我可能没有得到一个隐藏的想法吗?

+1

它可能是多余的('// 2'总是为真),但是在多线程环境中,可能会在地图中添加一个新值。 – 2014-12-19 08:43:29

+0

@GáborBakos我正在开发一个web应用程序,所以有多线程环境。你会建议离开这段代码吗? – 2014-12-19 08:44:45

+0

我不会删除第二个检查。它的目的。 – 2014-12-19 08:45:33

回答

4

该项目可能为空,因为map.get没有返回任何内容(外部地图不存在),或者因为内部地图不包含请求的对象。因此,执行第二次检查以检测item变为空的实际原因。

1

看起来你在地图内有一张地图。

PartnerReportItem item = (map.get(partnerId) == null) ? null : map.get(partnerId).get(platform); 

如果item不为空,这意味着partnerId在外部地图发现platform在内部地图找到。

但是,如果item为空,则外部映射中仍可能存在partnerId键,这意味着containsKey会在必要时进行检查。

+0

:)与我的答案相同 – 2014-12-19 08:47:09

1

正如其他答案所述,您需要保留此检查。然而,这实际上是一个错误的编码,因为有多个原因与PartnerReportItem实例无关(因此在第一个if语句中进行第二次检查)无关。

你最好不得不分裂它,以使意图更清晰(并避免其他人阅读你的代码时的混淆)。

Map<Platform, PartnerReportItem> innerMap = map.get(partnerId); 
if(innerMap == null) { 
    innerMap = new HashMap<Platform, PartnerReportItem>(); 
    innerMap.put(partnerId, createPartnerReportItem(...)); 
} else { 
    PartnerReportItem item = innerMap.get(partnerId); 
    if(item == null) { 
     innerMap.put(partnerId, createPartnerReportItem(...)); 
    } 
} 

或另一种变体:

Map<Platform, PartnerReportItem> innerMap = map.get(partnerId); 
if(innerMap == null) { 
    innerMap = new HashMap<Platform, PartnerReportItem>(); 
} 
PartnerReportItem item = innerMap.get(partnerId); 
if(item == null) { 
    innerMap.put(partnerId, createPartnerReportItem(...)); 
} 

的一点是,是谁写的,虽然,这将是更少的代码,但最终这个三元嵌套声明程序员,你看,这只是混乱。总是写可读的代码!