user3748908
user3748908

Reputation: 905

Correct use of guava Predicate on two types

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

Answers (1)

Alexis C.
Alexis C.

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

Related Questions