so in the last video i finished off saying just as with predicates there are
more specific flavors of suppliers now there's boolean supplier double supplier
int supplier and also long supplier so let's actually look at an example and
let's just say that we want to print out the last name of all the employees in
the list and we can use the for each method so let's do it that way first i'm
going to start with employees.....
....
...so here we are finding the first space in the
name and then using the substring method to assign everything after it to last name
then print out the last name so just try running that confirm it works first and
you can see we've got our last names working ok then if this was something we
wanted to frequently do we would go would probably added a get last name method
to the employee class but we'll pretend that we don't want to do it for some
reason however let's pretend that there are several places in our application we
need to get the last name of a single employee we want to use a lambda
expression that maps to one of the java.util.function interfaces now
none of the interfaces we looked at so far matches what we want to do consumer
doesn't return a value supplier doesn't accept any parameters and predicate only
returns true or false
so we want to actually pass in a string and we then expect a string to be
returned
and this sounds like a job for the function interface now the interface
represents a function that takes one parameter and returns a value the
functional method that one that we use with lambdas is the apply method so
first let's create the lambda we're going to use and assign it to a variable and
will continue from there and let's just remove or comment out the other for
each statements that we've been using here on some of the this other code
as well we don't need this anymore i'm just going to comment a lot
of this out
.....and start typing up here above the initial list
setup of our employees
alright so we're going to be setting up this function interface so we're going
do....
....
.....
....
....so a couple of things
to note with what we've just done here
so first we use generics with function the first type is the argument type
which in this case would be an employee
the second type is the return type which will be a string also we need the curly
braces around the return statement even though there's only one statement and if
you recall previously for this section that when we return a value the curly
braces are always required but having said that for lambda expressions that
are a single statement and return the value we don't have to use the return
keyword tis implied alright so right now this function doesn't actually do
anything to get the last name of an employee we have to call the apply
method
and pass it to the employee object let's go ahead and actually do that and see
what happens we're going to get the last name of the second employee in the list
going to type....
....
....ok let's just run that and see if it works you can see for the second employee
which was up here
well actually that was our 3rd one because I accidentally type 2 so change to 1 we
should get me this time when I ran that because i was the second one was added we
get my surname so that's working ok now we could have just created a regular old
method called get last name also as with other lambda expressions we could also
use anonymous class but by using function we can pass code that accept
returns a value to a method in the form of a lambda expression and then run
that code without having to create an interface and a class that implements
the interface so as we've seen previously we can change what a method
does based on the function we passing so let's suppose that sometimes we want the
first name of an employee and other times you want the last name so we could
write a separate get first name and get last name methods but let's do it with
one method instead so first we're going to create a function for getting the
first name so it's going to be function.....
....
.....
....
....so this time we are starting from the start of the
string up until we find the first space so we are getting that first name instead of
the last name will finish off that definition for our function so now we're
going to add a method that accepts function employees string argument so
I'm going to delete this just for a bit of space we can see what we're doing so
let's add that function down here or methods I should so....
....
....alright so now we're going to add some code to the main method that gets the
first or the last name of each employee so do....
....
....if that returns true we are going to
actually get the first names so we're going to do......
....
.....
....so we run that to see that it works
so you can see that in some cases were getting surnames but snow is obviously
a first name
red is the first time we run this again we should get random resulted each time
you can see we are clearly getting different result each time now in a more complex
application there may well be cases where we want to run similar code for a
set of situations we may have say 30 lines of code we want to run and only two
lines of code will vary depending on the situation now rather than using
interfaces with methods that are called of the appropriate points or writing
different methods for every situation we can actually pass in functions for the
parts that very that way the code will be more concise and easy to follow
another situation which functions are useful is when we want to use callbacks
so let's say that we're fetching data in a background thread and when the
data is ready we want to massage out in some way on the background thread and
the specifics of what we want to do can vary so we want to be able to specify
the what code to run when the data has been fetched now there are a number of
ways that we could do this Java provides ways to notify threads and run code
when a background task is completed but we can also use functions so let's
actually just say that we're fetching a bunch of images from the
internet and when we have them we want to resize them all the thread that
started the background thread is responsible for providing the code
that will do the resizing so we could do with the following way and what I'm going
to do is I'm going to paste in some code because you're not going to actually run
this but we're going to discuss one possible way of doing it
now this isn't a complete code sample and we can't run it but we can discuss what
it does the thread that wants images fetched in the background who would have
to provide an instance of a class that implements resize image when the
background thread has the images it would call the run when done method and
use a provided instance to resize the images now there are different resizing
algorithms and the one we want the one we want to use may
change depending on the current load of the system so the requirements quality
vs file size and other factors we have to create a resize image implementation
for every algorithm or we could use functions and do the following its going
to paste in a bit more code here now that we've done it this way there's no need
to write an interface and a bunch of classes that then implement that
interface we can create a function for each algorithm we may want to use it once
again using lambdas reduces the amount of code we need to write and in this
particular case would make the code easier to follow now rather than having
a bunch of classes each with a resize image method we can actually define all
the functions in one place anytime we need to use a callback meaning that we
want to run code when a specific non user interface event occurs using a
function is one option to consider so hopefully at this point you're beginning to
see the power of using lambdas with functions so imagine that you want to
transform an object in some way and the transformation requires four steps
for each step
there are several different algorithms you may want to run and which one to run
will depend on a state of the application at the time or on the object
that will be transformed
let's suppose that there are three possible algorithms for step one 2 for step
2 5 for step 3 and 3 for step 4
so that's a possible 3 times 2 times 5 times 3 equals 90 variations how we do
this using interfaces in a way that wouldn't be unwieldly and require us to
write lots of implementing classes using functions instead would result in less
code and the code would also be easier to read
all we really have to do is write a method that accepts 4 functions and then
write the 13 functions we may need to use when we want to transform an object
we passing the appropriate function for each step so I don't know about you
but to me that sounds easier and a lot more readable this is really the power
and convenience of using lambda expressions
alright I'm going to finish the video here now in the next video we're going
to continue on and we're going to work a bit more using functions in our
employee codes i will see you in the next video