In the previous post I had a look at Consumer function objects and how they were used in the forEach method of the Iterable class. An exactly opposite kind of interface to the Consumer is the Supplier interface. (like the name doesn't give it away)
To be honest I had a tough time coming up with a use case for this.I decided to first use this in a few places.
I first created a simple class Ticket:
A more suitable way would be to move this logic into a different abstraction and pass this as a parameter to the performOperation method.
The Supplier interface could be an easy way to achieve this without having to write any code.
To be honest I had a tough time coming up with a use case for this.I decided to first use this in a few places.
I first created a simple class Ticket:
publicclass Ticket {
privatestaticint counter = 0;
public Ticket() {
counter++;
}
publicstatic Ticket getSpecialTicket() {
// some processing needed to get ticket
counter++;
returnnew Ticket();The next step was to pass a ticket generator for use in application code. Normal way to do it would be:
}
publicstaticint getTicketCount() {
return counter;
}
@Override
publicString toString() {
return"T[" + this.hashCode() +"]";
}
}
publicstatic void performOperation(){Here we see the ticket being generated and used in code. If we had different sub-classes of tickets than we need to place that logic within the peformOperation method or else pass the ticket as a parameter. But what if we need multiple tickets ?
//get details of operation
//generate a ticket
Ticket ticket = new Ticket();
//use the ticket instance to perform operation
System.out.println("Ticket " + ticket + " used for operation");
}
A more suitable way would be to move this logic into a different abstraction and pass this as a parameter to the performOperation method.
The Supplier interface could be an easy way to achieve this without having to write any code.
publicstatic void performOperation(Supplier<? extends Ticket> ticketSupplier) {As can be seen here an instance of Supplier is passed here. Every time a ticket is needed, a call to the get method of Supplier class is made. As per the java documentation:
// get details of operation
// generate a ticket
Ticket ticket1 = ticketSupplier.get();
// use the ticket instance to perform operation
System.out.println("Ticket " + ticket1 + " used for operation");
//using the second ticket for
Ticket ticket2 = ticketSupplier.get();
// use the ticket instance to perform operation
System.out.println("Ticket " + ticket2 + " used for operation");
}
Represents a supplier of results.The client code for execution would be:
There is no requirement that a new or distinct result be returned each time the supplier is invoked.
This is a functional interface whose functional method is get().
publicstatic void main(String[] args) {As can be seen here, the code makes two calls to get instance of Supplier - this will result in tow calls to Ticket constructor, which will return us two ticket objects. If I wanted the static method to be used here:
performOperation(Ticket::new);
}
publicstatic void main(String[] args) {In both the cases every call to get will return a new ticket instance.
// performOperation(Ticket::new);
performOperation(Ticket::getSpecialTicket);
}
Ticket T[617901222] used for operationHowever if a singleton type of method was passed to Supplier, than we would have a single value returned by all calls to get. In both of the above calls, I used method reference. We can also achieve the same using lambda expressions:
Ticket T[1159190947] used for operation
performOperation(()->new Ticket());
performOperation(()-> getSpecialTicket());