我刚开始在新项目中使用Java 8,现在我正在尝试转换一些旧代码。
我正在尝试转换为以下代码片段。这是一个前端测试,只是比较,如果productElements
中的产品(代码)具有正确的数量:
for (Product product : products) {
boolean productFound = false;
for (ProductWebElement productElement : productElements) {
if (productElement.getProductCode().equals(product.getCode())) {
Assert.assertEquals(product.getQuantity(), productElement.getQuantity());
productFound = true;
break;
}
}
// This is optional - can be ignored
if (!productFound) {
fail("Product: " + product.getCode() + " not found!");
}
}
Product
只是一个普通的数据类(String productCode, int quantity
)
ProductWebElement
是FluentWebElement
的扩展对象 - 或者只是具有其他属性的对象。
我试图延伸 Java 8: More efficient way of comparing lists of different types?, 但我无法弄明白该怎么做。有谁知道如何用Java 8语法做到这一点?
答案 0 :(得分:3)
您可以编写以下代码:
products.forEach(p -> {
ProductWebElement productElement = productElements.stream().filter(
pe -> pe.getProductCode().equals(p.getCode())
).findAny().orElseThrow(() -> new AssertionError("Product: " + p.getCode() + " not found!"));
Assert.assertEquals(p.getQuantity(), productElement.getQuantity());
});
对于您的每个产品,我们都会尝试找到任何匹配的ProductElement
(具有相同的产品代码)。
如果没有找到,我们抛出AssertionError
。如果我们找到一个,我们可以断言数量是相同的。
答案 1 :(得分:3)
你应该摆脱一般的双重迭代。一种方法是将值存储在Map
:
Map<ProductCode,Quantity> map=productElements.stream().collect(
Collectors.toMap(ProductWebElement::getProductCode, ProductWebElement::getQuantity));
products.forEach(product -> {
Quantity q=map.get(product.getCode());
if(q==null) fail("Product: " + product.getCode() + " not found!");
Assert.assertEquals(product.getQuantity(), q);
});
请注意,由于您的属性的实际类型未显示在您的问题中,因此我在此处使用ProductCode
和Quantity
作为占位符。进一步请注意,我将实际的数量属性值存储在地图中,因为这是您感兴趣的唯一值,因此无需在第二个循环中再次查询ProductWebElement
。
这个逻辑也可以使用普通的Java 8之前的循环来实现......