Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use a lambda expression to pass a method as a parameter when calling another method?

Say I have two methods void chargeToIndividual(int amount, int account) and void chargeToCompany(int amount, int account). Say I have another method called void processSale(String item, Customer c). What can I do so I can pass either chargeToIndividual or chargeToCompany as an argument to processSale and how would I call it?

For example I want to be able to do

if(isIndividual(someCustomer))
{
  processSale(anItem, someCustomer, chargeToIndividual)
}
else if(isCompany(someCustomer))
{
  processSale(anItem, someCustomer, chargeToCustomer)
}

and inside processSale() how would I actually call chargeToIndividual or chargeToCustomer()?

like image 317
Celeritas Avatar asked Dec 31 '25 08:12

Celeritas


1 Answers

You have two functions:

void chargeToIndividual(int amount, int account);
void chargeToCompany(int amount, int account);

What they have in common is that they both take two int parameters and return void. There's no functional interface in java.util.function that matches this shape. But it's easy to define our own:

interface IntIntConsumer {
    void accept(int amount, int account);
}

You'd rewrite the calling code as follows:

if (isIndividual(someCustomer)) {
    processSale(anItem, someCustomer, MyClass::chargeToIndividual);
} else if (isCompany(someCustomer)) {
    processSale(anItem, someCustomer, MyClass::chargeToCompany);
} else { ... }

Or if chargeToIndividual and chargeToCustomer are instance methods, possibly use this::chargeToIndividual and this::chargeToCustomer. An alternate formulation would be to store the charging function in a local variable. Then you'll have only one call to processSale:

IntIntConsumer chargeFunc;

if (isIndividual(someCustomer)) {
    chargeFunc = this::chargeToIndividual;
} else if (isCompany(someCustomer)) {
    chargeFunc = this::chargeToCompany;
} else { ... }

processSale(anItem, someCustomer, chargeFunc);

Now in processSale the call to the charging function would look like this:

void processSale(Item item, Customer customer, IntIntConsumer func) {
    ...
    func.accept(item.getAmount(), customer.getAccount());
    ...
}

Of course I've made some assumptions about where to get the amount and account arguments, but I think you can get the idea.

like image 200
Stuart Marks Avatar answered Jan 01 '26 22:01

Stuart Marks