Reputation: 905
I'm not sure if I completely understand how guava's Predicate<T>
should be use. I have two classes Promotion
and Customer
, and I want to check which one of the promotions is applicable to a customer.
public Optional<Promotion> getApplicablePromotionToCustomer(final List<Promotion> activePromotions,
final Customer customer) {
return FluentIterable.from(activePromotions).firstMatch(new Predicate<Promotion>() {
@Override
public boolean apply(final Promotion input) {
return input.getCustomerType().equals(customer.getType()) && new DateRangeComparator().overlaps(input.getDateRange(), customer.getDateRange());
}
});
}
My questions are related to the correct typing of Predicate
. Is it correct to make Predicate
of type Promotion
or should I build a wrapper class with Promotion
and Customer
? I'm not even sure of how to word it. Am I using a "Predicate
with a Customer
and applying it to a Promotion
"?
If I want to extract the anonymous implementation of Predicate
to it's own class, I'll have to make the constructor take a Customer
, and even a DateRangeComparator
if want to make that customizable. Is this fine or approach is totally wrong?
Upvotes: 0
Views: 115
Reputation: 93842
Is it correct to make Predicate of type Promotion or should I build a wrapper class with Promotion and Customer?
Yes it's correct. The filtering function you want to implement will be of the form f(x) = y
where y
belongs to {false, true}
.
Here the type of x
is the type of the element on which you want to apply the function (so the type of the Predicate
). Since you filter a List<Promotion>
the type of the predicate will be Predicate<Promotion>
. The logic used to test the element (with the Customer
and the DateRangeComparator
is the function itself but the input type is definitely Promotion
there.
Am I using a "Predicate with a Customer and applying it to a Promotion"?
Everyone has its own wording, as long as you are clear I think it does not really matters. But yes, you apply the predicate to a Promotion
.
If I want to extract the anonymous implementation of Predicate to it's own class, I'll have to make the constructor take a Customer, and even a DateRangeComparator if want to make that customizable. Is this fine or approach is totally wrong?
Yes there's nothing wrong doing that. The only thing I would keep in mind is that you should try to implement a stateless predicate whenever possible, i.e a predicate that doesn't retain what it filtered so that each item can be processed independently. This is very useful when you start to do parallel computations, because every object that has to be tested can use the predicate as a standalone "box".
Upvotes: 3