I worked with using lambdas for Comparator interface in my first post on Lambdas. We saw how a Function interface could be used to convert an object of one type into an object of another.
This class is used to extract the compare key for the comparator method.
The Collections framework has utilized this concept in their computeIfAbsent method:
Below is a use case with the code
There are also some more utility methods provided in the Function interface. Consider the compose method which allows us to apply another function to the input, and then applies the code inside our function.
The transformation is as below:
input : Ticket
Stage 1: Ticket -> String ( the 'before' function)
Stage 2: String -> Long
output: Long
There is also a way to combine, by adding a post function - or a function that runs after our function:
This class is used to extract the compare key for the comparator method.
users.sort(Comparator.comparing(User::getAge));The method reference will result in a Function instance that converts an User instance to a String instance (user.getAge())
The Collections framework has utilized this concept in their computeIfAbsent method:
Below is a use case with the code
public static void main(String[] args) { Function<Ticket, String> ticketKeyValFn = ticket -> ticket.toString(); Map<Ticket, String> ticketMap = new HashMap<>(); ticketMap.put(getSpecialTicket(), "For Purchase Operation"); Ticket ticket = new Ticket(); //this ticket is not in map System.out.println("Map contains ticket " + ticket + " ? " + ticketMap.containsKey(ticket)); ticketMap.computeIfAbsent(ticket, ticketKeyValFn); //now ticket is in map System.out.println("Map contains ticket " + ticket + " ? " + ticketMap.containsKey(ticket)); }The output is as below:
Map contains ticket T[1159190947] ? false Map contains ticket T[1159190947] ? trueIf I simply wanted to generate values for ticket than the code would be simply:
String value = ticketKeyValFn.apply(new Ticket());Thus we have seen that Functions serve as transformers converting one type to another. We could also use it for more complicate operations once we combine this with streams.
There are also some more utility methods provided in the Function interface. Consider the compose method which allows us to apply another function to the input, and then applies the code inside our function.
Ticket ticket = new Ticket(); //This is the before function Function<Ticket, String> ticketKeyValFn = ticketInstance -> ticketInstance.toString(); String sampleOpt = ticketKeyValFn.apply(ticket); System.out.println("Output of first function is " + sampleOpt); Function<String, Long> cleanTicketValFn = inp -> Long.valueOf(inp.substring(2,inp.length()-1)); Long no = cleanTicketValFn.apply(sampleOpt); System.out.println("Output of second function is " + no); //If using composites //cleanTicketValFn = the one that executes last - gets a string and returns a Long Function<Ticket, Long> compositeFn = cleanTicketValFn.compose(ticketKeyValFn); System.out.println("The ticket Id is " + compositeFn.apply(ticket));The output:
Output of first function is T[617901222] Output of second function is 617901222 The ticket Id is 617901222As can be seen, I have defined two functions - one that transforms a Ticket into a String and the second that transforms a String into a Long. Using compose we have combined the two.
The transformation is as below:
input : Ticket
Stage 1: Ticket -> String ( the 'before' function)
Stage 2: String -> Long
output: Long
There is also a way to combine, by adding a post function - or a function that runs after our function:
Function<String, Long> toLongFunction = string -> Long.valueOf(string); Function<Long, Integer> toIntegerCutoffFunction = longVal -> longVal.intValue(); //Now combine the two Function<String, Integer> compositeFunction = toLongFunction.andThen(toIntegerCutoffFunction); // Test call System.out.println(compositeFunction.apply("1234"));Here first the String -> Long transformation happens and then Long -> Integer transformation.
No comments:
Post a Comment