2016-11-11 338 views
0

我试图将一些for-loops重构为lambda表达式,其中大多数都正常工作,但我正在为包含两个if语句的for-loop而努力。Java 8 Lambda Stream forEach带有两个if语句

代码

 for (B2KTransactionDTO b2kTransactionDTO : result) { 
      //Generate loyaltyMatchId based on transaction input 
      String loyaltyMatchId = getLoyaltyMatchIdBasedOnTransactionDTO(b2kTransactionDTO); 
      if (loyaltyMatchIdAmountMap.containsKey(loyaltyMatchId)) { 
       BigDecimal cashback = loyaltyMatchIdAmountMap.get(loyaltyMatchId); 
       b2kTransactionDTO.addLoyaltyPoints(cashback); 
      } 

      String loyaltyMatchInsuranceId = getLoyaltyMatchInsuranceIdBasedOnTransactionDTO(b2kTransactionDTO); 
      if (loyaltyMatchInsuranceIdAmountMap.containsKey(loyaltyMatchInsuranceId)) { 
       BigDecimal cashback = loyaltyMatchInsuranceIdAmountMap.get(loyaltyMatchInsuranceId); 
       b2kTransactionDTO.addLoyaltyPoints(cashback); 
      } 
     } 

我重构这下面的代码:

 result.forEach(b2kTransactionDTO -> { 
      //Generate loyaltyMatchId based on transaction input 
      String loyaltyMatchId = getLoyaltyMatchIdBasedOnTransactionDTO(b2kTransactionDTO); 
      if (loyaltyMatchIdAmountMap.containsKey(loyaltyMatchId)) { 
       BigDecimal cashback = loyaltyMatchIdAmountMap.get(loyaltyMatchId); 
       b2kTransactionDTO.addLoyaltyPoints(cashback); 
      } 

      String loyaltyMatchInsuranceId = getLoyaltyMatchInsuranceIdBasedOnTransactionDTO(b2kTransactionDTO); 
      if (loyaltyMatchInsuranceIdAmountMap.containsKey(loyaltyMatchInsuranceId)) { 
       BigDecimal cashback = loyaltyMatchInsuranceIdAmountMap.get(loyaltyMatchInsuranceId); 
       b2kTransactionDTO.addLoyaltyPoints(cashback); 
      } 
     }); 

是否有可能甚至futher拉姆达nize呢?

谢谢

+6

你为什么要把它放入lambda? Labda的启动/内存密集程度稍慢,并且不会增加代码的可读性。或者你是否需要平行主义来加速处理(这只会与大数据集相关) – Tschallacka

+0

您可以将它转换为_two_独立的'foreach',并添加'map'和'filter'以更加“lambda-nize”。 (如...'map.(...)。filter(...)。map(...)。forEach(...))' –

+0

另外,你的变量名称太长了......考虑将这些地图放入一个LoyaltyManager对象中,该对象处理匹配id的逻辑和返回的返现。 – Tschallacka

回答

0

这不是你要找的答案。

我会说,不要在这里使用lambda。

Lambda的可以帮助你利用cpu的parralelism功能来加速处理大型数据集。根据我的经验,不值得使用带有较小数据集的lambda的麻烦(< 10(0).000);

保持您的代码可读性,可维护性和可插拔性。

学习制作处理目标的物体。不要把所有的东西都放在一个对象中,并且最终会得到很长的变量NamesThatDescribe的目的。

当发生长变量名时,它应该是一个信号给你,你可以将该代码重构成几个处理单个用途的对象。

如果你真的想要使用lambda的话,请尝试以下操作: 为价值持有者和处理器分离对象,并为独立任务分配对象,在需要时使用lambda会更容易,因为您只需插入任务的方法需要并传递价值持有者对象以获得您想要的结果。

所以,不是你要找的答案,但这真的太长,以至于无法在评论中解释。

0

我想你也应该考虑重构你的代码,因为它看起来像有很多比赛matchInsurance的东西之间的重复。

private static void addLoyaltyPoints(Collection<B2KTransactionDTO> result, Map<String, BigDecimal> ids, Function<B2KTransactionDTO, String> extractId) 
{ 
    result.stream() 
      .filter(b -> ids.containsKey(extractId.apply(b))) 
      .forEach(b -> b.addLoyaltyPoints(ids.get(extractId.apply(b)))); 
} 

然后您发布的整个代码将变成:

addLoyaltyPoints(result, loyaltyMatchIdAmountMap, Use::getLoyaltyMatchIdBasedOnTransactionDTO); 
addLoyaltyPoints(result, loyaltyMatchInsuranceIdAmountMap, Use::getLoyaltyMatchInsuranceIdBasedOnTransactionDTO); 

编辑:的addLoyaltyPoints另一个版本(更简洁,少表现):

private static void addLoyaltyPoints(Collection<B2KTransactionDTO> result, Map<String, BigDecimal> ids, Function<B2KTransactionDTO, String> extractId) 
{ 
    result.stream() 
      .forEach(b -> b.addLoyaltyPoints(ids.getOrDefault(extractId.apply(b), new BigDecimal(0)))); 
}