2017-07-14 3 views
0

Exemple: Filtrer une liste de produits dont le prix est basé sur fromPrice et toPrice. Ils pourraient soit être fournis, soit juste un.Java 8: Diffuser et filtrer en fonction des conditions optionnelles

  1. Trouvez tous les produits dont le prix est supérieur à fromPrice
  2. Trouvez tous les produits dont le prix est inférieur à toPrice
  3. Trouvez tous les produits dont le prix est entre fromPrice et toPrice

Produit:

public class Product { 

    private String id; 

    private Optional<BigDecimal> price; 

    public Product(String id, BigDecimal price) { 
     this.id = id; 
     this.price = Optional.ofNullable(price); 
    } 
} 

PrixPrix:

public class PricePredicate { 

    public static Predicate<? super Product> isBetween(BigDecimal fromPrice, BigDecimal toPrice) { 
     if (fromPrice != null && toPrice != null) { 
      return product -> product.getPrice().isPresent() && product.getPrice().get().compareTo(fromPrice) >= 0 && 
        product.getPrice().get().compareTo(toPrice) <= 0; 
     } 
     if (fromPrice != null) { 
      return product -> product.getPrice().isPresent() && product.getPrice().get().compareTo(fromPrice) >= 0; 
     } 
     if (toPrice != null) { 
      return product -> product.getPrice().isPresent() && product.getPrice().get().compareTo(toPrice) <= 0; 
     } 
     return null; 
    } 
} 

Filtres:

return this.products.stream().filter(PricePredicate.isBetween(fromPrice, null)).collect(Collectors.toList()); 

return this.products.stream().filter(PricePredicate.isBetween(null, toPrice)).collect(Collectors.toList()); 

return this.products.stream().filter(PricePredicate.isBetween(fromPrice, toPrice)).collect(Collectors.toList()); 

Y at-il un moyen d'améliorer mon prédicats au lieu d'avoir le contrôle sinon nul? Tout ce qui peut être fait avec des options?

Répondre

1

Non, Facultatif n'est pas conçu pour remplacer les vérifications nuls.

Mais votre code peut être améliorée en évitant les doubles emplois, et en évitant de retourner nulle (ce qui est manifestement pas une valeur valide pour un prédicats) si les deux arguments sont nuls:

public static Predicate<Product> isBetween(BigDecimal fromPrice, BigDecimal toPrice) { 
    Predicate<Product> result = product -> true; 

    if (fromPrice != null) { 
     result = result.and(product -> product.getPrice().isPresent() && product.getPrice().get().compareTo(fromPrice) >= 0); 
    } 

    if (toPrice != null) { 
     result = result.and(product -> product.getPrice().isPresent() && product.getPrice().get().compareTo(toPrice) <= 0); 
    } 

    return result; 
} 
+1

La première phrase suffit pour gagner +1 de moi. – Jubobs

+0

Merci. Cela semble bon. mais j'obtiens une erreur de compilation ici: Facultatif price = product.getPrice(); ne peut pas résoudre le symbole 'produit' –

+0

Oh oui, désolé, mon code n'a pas de sens. Laisse-moi le réparer. –

0

Vous pouvez utiliser Apache Commons Lang, il offre la comparaison sécurité nulle:

ObjectUtils.compare(from, to) 

null is assumed to be less than a non-value