2015-10-07 1 views
1

Je viens de commencer à utiliser Java 8 dans un nouveau projet et maintenant j'essaye de convertir du code plus ancien. J'essaie de convertir en fragment de code suivant. Il est pour un test de frontend et compare simplement, s'il est le produit (code) avec la quantité correcte productElements:Java 8: Comparer plusieurs attributs dans deux listes

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 est juste une classe de données normale (String productCode, int quantity)

ProductWebElement est un objet étendu de FluentWebElement - ou juste un objet avec quelques attributs supplémentaires. J'ai essayé d'étendre Java 8: More efficient way of comparing lists of different types?, mais je ne pouvais pas comprendre comment le faire Est-ce que quelqu'un sait comment faire cela dans la syntaxe Java 8?

Répondre

2

Vous pouvez écrire le code suivant:

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()); 
}); 

Pour chacun de vos produits, nous essayons de trouver une correspondance ProductElement (ayant le même code de produit).

Si aucun n'est trouvé, nous lançons un AssertionError. Si nous en trouvons un, nous pouvons affirmer que les quantités sont les mêmes.

3

Vous devriez vous débarrasser de la double itération en général. Une façon de le faire, est de stocker les valeurs dans un 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); 
}); 

Notez que puisque les types réels de vos propriétés ne se présentent pas dans votre question, je ProductCode et Quantity comme ici des espaces réservés. Notez en outre que j'ai stocké les valeurs réelles des propriétés de quantité dans la carte, car c'est la seule valeur qui vous intéresse. Il n'est donc pas nécessaire d'interroger de nouveau les ProductWebElement s dans la deuxième boucle.

Cette logique pourrait également être implémentée en utilisant des boucles pré-Java 8 ordinaires ...