In isReadyToDeliver
method if all products in order is available (ProductState.AVAILABLE
) and if order state is ready to send (OrderState.READY_TO_SEND
), method must return true
.
I wrote both two part but I couldn't combine them in return phrase,
I wrote return orderState.andThen(productState)
but get this error:
The method
andThen(Function<? super Boolean,? extends V>)
in the typeFunction<Order,Boolean>
is not applicable for the arguments(Function<Order,Boolean>)
public class OrderFunctions {
public Function<Order, Boolean> isReadyToDeliver() {
Function<Order, Boolean> orderState = o -> o.getState() == OrderState.READY_TO_SEND;
Function<Order, Boolean> productState =
o -> o.getProducts()
.stream()
.map(Product -> Product.getState())
.allMatch(Product -> Product == ProductState.AVAILABLE);
return ????? ;
//return orderState.andThen(productState);
//error: The method andThen(Function<? super Boolean,? extends V>) in the type Function<Order,Boolean> is not applicable for the arguments (Function<Order,Boolean>)
}
}
In case other classes are needed:
enum OrderState {CONFIRMED, PAID, WAREHOUSE_PROCESSED, READY_TO_SEND, DELIVERED }
enum ProductType { NORMAL, BREAKABLE, PERISHABLE }
public class Order {
private OrderState state;
private List<Product> products = new ArrayList<>();
public OrderState getState() {
return state;
}
public void setState(OrderState state) {
this.state = state;
}
public Order state(OrderState state) {
this.state = state;
return this;
}
public List<Product> getProducts() {
return products;
}
public void setProducts(List<Product> products) {
this.products = products;
}
public Order product(Product product) {
if (products == null) {
products = new ArrayList<>();
}
products.add(product);
return this;
}
}
public class Product {
private String code;
private String title;
private ProductState state;
public ProductState getState() {
return state;
}
public void setState(ProductState state) {
this.state = state;
}
public Product state(ProductState state) {
this.state = state;
return this;
}
}
If you change isReadyToDeliver()
to return Predicate<Order>
then you will be able to combine two predicates with .and(Predicate another)
function:
public Predicate<Order> isReadyToDeliver() {
Predicate<Order> orderState = o -> o.getState() == OrderState.READY_TO_SEND;
Predicate<Order> productState =
o -> o.getProducts()
.stream()
.map(Product -> Product.getState())
.allMatch(Product -> Product == ProductState.AVAILABLE);
return orderState.and(productState);
}
Your example with functions composition didn't work, because when you compose functions f
and g
, g
takes as a parameter value that f
function returns. In your case it was broken, because orderState
expected Order
and return Boolean
and it this case orderState.andThen()
expected a function that takes Boolean
as a parameter and returns something else. This requirement was not satisfied, because productState
expected Order
and returned Boolean
. This is exactly what following error said:
error: The method andThen(Function) in the type Function is not applicable for the arguments (Function)
But if for some reason you want to stay with Function<Order, Boolean>
then you will have return a lambda like:
public Function<Order, Boolean> isReadyToDeliver() {
Function<Order, Boolean> orderState = o -> o.getState() == OrderState.READY_TO_SEND;
Function<Order, Boolean> productState =
o -> o.getProducts()
.stream()
.map(Product -> Product.getState())
.allMatch(Product -> Product == ProductState.AVAILABLE);
return (order) -> orderState.apply(order) && productState.apply(order);
}
From the two functions orderState
and productState
you can create a new lambda expression by using &&
(the logical and)
and return it:
public Function<Order, Boolean> isReadyToDeliver() {
Function<Order, Boolean> orderState = ...;
Function<Order, Boolean> productState = ...;
return o -> orderState.apply(o) && productState.apply(o);
}
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