lambdas are one of the coolest elements of the java language but they can also be one of the most confusing to understand especially for a beginner when can you use one what exactly is it doing and how do you make sense of the weird syntax that it has in this video we'll talk all about why lambdas exist what they do and when you can use them and how you can implement them into your java programs my name is john i'm a lead java software engineer and i also have a full java course available in a
link down in the description so go check it out lambdas in java can only be used along with certain types of interfaces so to understand exactly what a lambda is and when we can use them we first need to go over a little bit about interfaces you probably know that an interface is kind of like a contract that says that any class that implements that interface has to provide their own implementations of the methods specified by that interface so for example if we have an interface like this one called printable this void print here is
declaring a method called print but notice it doesn't have any implementation at all but the idea is that you can create a class that implements this printable interface and when you do that class has to provide its own implementation of the print method so over here in our cat class inside the class declaration at the top we can write implements printable now notice it's giving us an error here because we're implementing the printable interface but we haven't yet defined our implementation of the print method so let's go ahead and do that now so that would
be public void print that takes no parameters so for our implementation to print out a cat let's just print out meow so now we can hop back here to our main method and create a cat my cat equals new cat and with this my cat we can call the print method on it that we've just implemented and now if we run our program we can see that it prints out meow but also down here we have this method print thing which takes in as a parameter a printable which can be any object that implements the
printable interface and inside this method it knows that whatever this thing is it does implement the printable interface so it knows that it's able to call the print method on it so that's what it's doing here since our cat class implements the printable interface we can call this print thing method and send in our cat as the printable thing so back up here instead of calling mycat.print we can instead call the print thing method and pass in our mycat object and if we run our program we get the same output as before meow because inside
this print thing method it's just calling the print method on the cat object that we sent in here's where lambdas come in now the only special thing that you can do with a printable is call this print method on it right because that's the only method specified by this interface so when this method takes in a printable the only thing that really matters about it is what that thing's implementation of this print method is but right now even though really all we want to do is provide a specific implementation of the print method here there
was a whole bunch of things that we had to do to be able to do that first we had to have some class implement the printable interface then we had to provide an implementation of that print method so it would print out what we wanted then over here we had to create a new object of that class then finally we could pass in that object into this method as the printable parameter lambdas allow us to just pass in a specific implementation of this print method as the printable parameter without needing all of that extra stuff
so you can literally think about it like this so let's go over to our cat class and copy the specific implementation of this print method that we want to use and then over here where we're calling this print thing and we need to pass in a printable instead of passing in this my cat object let's just try and pass in the specific implementation of this print method that we want it to use this gives you the concept of what we're doing with a lambda instead of passing in an object that contains a specific implementation of
the print method we're just passing in that specific implementation of the print method directly when you're implementing a method inside of a class it looks like this but when you're using lambdas to pass in a method implementation as a parameter there's some things that we leave out first the access level public in this case is not needed so we leave that out we also don't need the name of the method we just need what it does and so we can leave out the name too we also don't even need the return type which in this
case is void because the compiler can figure out the return type automatically so we can get rid of that too so now we're left with the only things that we really need to define a method implementation and that is the parameters which in this case we don't have any parameters and the actual method implementation now to make this a valid lambda syntax all we need to do is add an arrow operator here between the parameters and the method implementation the arrow operator is just a hyphen and then the greater than symbol and you can see
that we now have no more errors because this is a valid lambda expression now we can compile and run our code and it does exactly the same thing as before it prints out meow but instead of having to do all that work where we implemented the printable interface inside the cat class and then we defined the print method that we wanted inside that cat class and then created an object from that class and passed that into the print thing method instead of doing all of that we're instead just passing in the implementation of the print
method that we want it to use as our printable parameter basically instead of sending in an object which contains an action we're just sending in the action itself we can actually simplify this lambda expression even more though if the implementation that you're passing in is just one single expression you can leave out the curly braces and then you can have your whole entire lambda expression just be one line like this so notice that we're using a lambda to pass in our implementation of that print method as an object like we would any other object that
means that we can save this implementation of the print method as a variable just like we could with any other object as well so we can say printable lambda printable equals this entire lambda expression and then we can pass in this lambda printable object into the method and then if we run it it does exactly what it did before so lambdas in java give you the ability to make method implementations into objects like any other that can be saved into variables and passed into methods as parameters right now the print method inside our printable interface
doesn't take any parameters but let's see what it would look like if it did let's say it took in as a parameter some string suffix that is intended to just go at the end of whatever is printed now back over here in our lambda expression let's go ahead and get rid of this cat because we don't need it anymore over here in the lambda expression we now have an error and that's because the interface method that we are implementing has one parameter but our lambda doesn't so all we have to do is give it whatever
name we want it to use for that parameter so we could use the same name that it has in the interface and just call it suffix but we don't have to we can name it whatever we want so we can even just name it s and we don't have to specify the type here of string because java already knows that because the type in the interface is defined as a string then that's what the type of this parameter has to be as well and also if you have a single parameter in your lambda expression you
can exclude the parentheses as well but if it doesn't have any parameters or it has more than one parameter you will need the parentheses anyway then we can use this parameter however we want inside our method implementation and you don't have to use it at all if you don't want to notice that we're not getting any errors at all here if we don't use s in our method implementation but of course we can if we want to so it's a suffix right so what we can do is after meow we can just append whatever that
string is on the end since that print method now takes in that string suffix parameter we also have to add it when we're calling that print method down here so maybe we wanted to use like an exclamation point as the suffix so then we can run our program and now it prints out meow with an exclamation point now if you had more than one parameter like over here if we had a string prefix as well then over here in your lambda expression all you have to do is just separate those two parameters with a comma
like this so we can use like p for the prefix and s for the suffix so what happens if your interface method also has a return type so instead of being void let's say this instead returned a string so now back here in our lambda expression in order to implement that print method properly we have to return a string object and there are a couple ways we can do that first if your implementation has more than one line like ours did before you can just put your return statement inside your implementation here like you would
for any normal method so you can just return whatever string you want like meow and in that case we need a semicolon here and here also after the ending curly braces but if your method implementation is only one expression java interprets that as being your return value and you don't even need to use the return keyword so if we wanted this method to just return meow plus the suffix and not print out anything to the console all we have to do is make that expression into our implementation so now this expression is our entire method
implementation and java interprets that expression as the return value so java interprets this as meaning the exact same thing as if we used the curly braces and had the return keyword to return this value but this just allows us a much cleaner way to do exactly the same thing let's talk a little bit about how exactly this is working behind the scenes because i think it helps to give you a little bit deeper understanding of what's going on going back to our interface here remember that we just have one method to find this string print
when a method inside an interface has no implementation like this one does it's called an abstract method and when an interface has exactly one abstract method it's called a functional interface when you have a functional interface you can even add an annotation here above the top of your class at functional interface you don't technically have to have this annotation at the top of your interface for it to be a functional interface but it is best practice to do so because if you do the compiler will enforce that you have exactly one abstract method in your
interface so if we tried to add another abstract method to this interface like void do thing now it's giving us an error because we're saying this should be a functional interface but we're providing more than one abstract method for it to be a proper functional interface it can only have one abstract method defined these are also sometimes called sam interfaces because they have a single abstract method s-a-m this interface could contain other types of methods like static methods or default methods and still technically be a functional interface it just has to have exactly one abstract
method so what does this have to do with lambdas well lambdas can only be used in the context of a functional interface if an interface has more than one abstract method then you can't use a lambda for it so if we got rid of this functional interface annotation and added our void do thing method now we have a problem over here in our lambda implementation and it says multiple non-overriding abstract methods found in interface printable the reason this happens is that in a lambda you're only able to define the implementation of one method when the
interface has only one abstract method it works fine because java knows exactly the method that you're implementing in your lambda because there's only one so if our printable interface had two abstract methods we would always be leaving one of them completely undefined if we were allowed to create them with a lambda expression if you want to do something similar to this where you have an interface with more than one abstract method you can do what you need to with an anonymous class and you can learn more about anonymous classes in this video here from a
technical perspective all a lambda is is a shortcut to defining an implementation of a functional interface so here we have a functional interface but instead of having to create a class that implements that functional interface and then adding the implementation that you want of that single abstract method and then creating an object of this class and using that you can instead just simply create a lambda expression that contains the implementation of that functional interface method that you want it allows you to effectively treat code as a parameter if you enjoyed this video or learned something
let me know by leaving a like and be sure to subscribe so you don't miss each new java tutorial and if you're interested in my full java course you can find it in a link down in the description as always thank you so much for watching i really do appreciate you being here with me see you next time