I have the following method:
public String getAllDangerousProductsName(Offer offer){
return offer.getOfferRows().stream()
.filter(row -> row.isDangerousGood())
.map(row -> row.getItemInformation().getOfferTexts().getName())
.collect(Collectors.joining(","));
}
I want to reuse this method for row.isBulkyGood(). What I am doing currently is
public String getAllBulkyProductsName(Offer offer){
return offer.getOfferRows().stream()
.filter(row -> row.isBulkyGood())
.map(row -> row.getItemInformation().getOfferTexts().getName())
.collect(Collectors.joining(","));
}
... which is basically code repetition. Is there a way I can pass the function as method parameter to optimize this to have one method for both the filter condition?
You can pass the Predicate used in the filter right to the method which is the only thing that differs in the methods.
Assuming offer.getOfferRows() returns List<OfferRow>, then:
public String getAllDangerousProductsName(Offer offer, Predicate<OfferRow> predicate) {
return offer.getOfferRows().stream()
.filter(predicate)
.map(row -> row.getItemInformation().getOfferTexts().getName())
.collect(Collectors.joining(","));
}
Usage becomes fairly simple:
// using lambda expression
String str1 = getAllDangerousProductsName(offer, row -> row.isDangerousGood());
String str2 = getAllDangerousProductsName(offer, row -> row.isBulkyGood());
// using method reference
String str1 = getAllDangerousProductsName(offer, OfferRow::isDangerousGood);
String str2 = getAllDangerousProductsName(offer, OfferRow::isBulkyGood);
Yes, you could add a Predicate<OfferRow> argument to this method and then use method references OfferRow::isDangerousGood or OfferRow::isBulkyGood:
public static String getAllProductsNameByPredicate(Offer offer, Predicate<OfferRow> predicate){
return offer.getOfferRows().stream()
.filter(predicate)
.map(row -> row.getName())
.collect(Collectors.joining(","));
}
// invoke with different predicates
getAllProductsNameByPredicate(myOffer, OfferRow::isDangerousGood);
getAllProductsNameByPredicate(myOffer, OfferRow::isBulkyGood);
If it is needed to negate the condition of the predicate, Predicate.not may be used since Java 11.
For Java 8-10, a utility method may be implemented using Predicate.negate():
public static <R> Predicate<R> not(Predicate<R> predicate) {
return predicate.negate();
}
getAllProductsNameByPredicate(myOffer, not(OfferRow::isDangerousGood));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With