Transcript from the "Functional Interfaces" Lesson
>> So the next section is on functional programming. This is another style of development software. It uses mathematical functions on an input set to produce an output set. Now while Java is an object oriented programming language, it does provide the java.util.function package, which hosts several functional interfaces. I think this might be all of them, if none were added recently.
[00:00:32] But as you can see, quite a bit of functional interfaces. So what is a functional interface anyway? Well, it's an interface that has just one abstract method. And that one method is what lambda expressions and method references. Remember, we just talked about those, it's what they implement. So again, lambda expressions, well, method references are a shortcut for lambda expressions, so same thing, right?
[00:01:06] But lambda expressions are essentially an implementation. They're anonymous functions, right? They're an anonymous function that is the implementation of the one abstract method within a functional interface. So example, this is a list of countries, yes. If we wanted to print each country, we could use the for each in a lambda expression that says to print each one out, okay?
[00:01:40] The lambda expression is actually the implementation of the consumer functional interface from the java.util package. So on line 9 here, this is the consumer interface. On line 9, we see that this interface has one abstract method that accepts a single input argument and it returns no result, okay?
[00:02:13] This is already in the Java util function is not anything that I've written, I just pulled the code. Specifically, our lambda expression is the implementation. The functional interfaces single abstract method, which in this case is the accept. So what that is doing, that c arrow system.out.println/c, it's saying, hey, make that the implementation for that abstract method.
[00:02:46] So to illustrate this, I've created a variable called print. Whose type is consumer. That's the functional interface from java.util. When we call for each and we pass in this interface, the implementation that we provided for accept is what is executed. So, I said, the consumer equals c arrow println, give that whole object to forEach, and it's basically gonna just execute that code.
[00:03:30] So even without the forEach, we can call the abstract method from the consumer interface accept, right? So I said, all right, print as a consumer object, .accept. That's the abstract method, and then I can pass in any object and it's going to use that implementation that I specified on the first line.
[00:03:54] And it's using the hello world as the input to that abstract method. Cuz remember it takes a single input. So in addition to the lambda expression, we could also use the method reference. And this will work exactly the same. So consumer, that's the example I just showed you.
[00:04:13] Of course, there are many more. These are the core functional interfaces provided in that java.util package. So, I'll go through these. We have consumer we've already talked about. We also have supplier. This returns a value, but it does not accept any input. We have predicate which has a function that accepts one argument as input and it returns a Boolean value as the output.
[00:04:42] We have function which accepts one argument as input and then it produces a result. And then the other two there are specific types of function operators. Such as the unary operator, an operation that accepts a single argument as input, and then it returns output of that same type.
[00:05:08] So notice with unary, we have T as the type of input, and also T as the type that will be returned back. So that implies that's the same. And then binary works kind of the same way except it takes two parameters, both of the same type, and it returns something of that same type, all right?
[00:05:30] So the remaining interfaces in this package, the java.util.function, package there are specific variations of these. So these are the core ones. Basically, given these and the variations on them, the idea here is that whatever lambda expression you come up with should meet one of these. Kind of have a lot of different ones for you to choose from.
[00:06:06] So back to functional interfaces, in addition to the one abstract method that's available in every functional interface, the interface can also provide default and static methods. So we talked about that when we looked at interfaces, right? So functional interfaces are no different. They have that one abstract method, but they can also include additional methods as well.
[00:06:30] So in this example, this is the function interface, and this provides the default method that's called andThen. Which will allow you to perform another operation on the result from the previous operation. So here are two separate statements. We have square, which uses a lambda expression to implement the apply method of the function to return the square of the input.
[00:07:03] And then we have add, which adds the input to itself. And then it returns the sum, so we could say first execute square and then execute add and then we could say apply all of this, all right? And when you say apply, that's when you provide the actual input that you want it to use.
[00:07:35] And apply is the abstract method in the class, right? So you give it that input and you say, all right, with this input, I want you to do what I specify for square and then what's this default method and then do what I provided for add. So you would get 50 there.
[00:08:01] So while the functional interfaces in the javautil.function package cover most of the use cases that you may have. You can create your own functional interface if you just need it to, right? If none of them fit the bill and you're doing something really extraordinary, then you can create your own functional interface.
[00:08:23] It's recommended that you use this functional interface attribute. So you would just do add functional interface and annotation is what it's called. So you would annotate this with a functional interface. You don't have to, but it's convention and it'll help you out. Because Java would then enforce that you can only have one abstract method, which, if you wanna be a functional interface, that's the rule, right?
[00:08:55] So, if you had that one abstract method, then you would let the implementers know what are the arguments if there are any. So in yours you say yeah, I take three arguments or whatever, and then the result that would be returned. So in this one, you specifically said, I take three integers and I return an integer back, right?
[00:09:21] And some of those other interfaces that we looked at, notice they didn't have a return type that you were familiar with. They had things like T and R or whatever. So these are generic types, where you can say, I don't really care, the type of the object, I'm just gonna leave a placeholder here,, but, they can give me any object, and I'm able to deal with it.
[00:09:46] Okay, optionally in your own custom functional interface you can also include your static and your default methods if you want.