This course will be retired on June 1, 2025.
Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
Let's explore the built in Function Shapes
Learn more
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
So we now have a couple of pretty
succinct ways to create and
0:00
pass functions into methods.
0:04
Are you starting to get a sense
of how powerful this can be?
0:06
Are you noticing how it feels
just a little bit different?
0:09
Well, that feeling is totally fine and
it's actually expected.
0:12
Like we talked about,
this is a different way of thinking,
0:15
it's bound to feel a little bit strange,
especially at first.
0:18
We're about to go a little bit deeper now,
but the basic concepts are the same.
0:22
The main thing that I want you to know
is that you can provide a Lambda or
0:26
method reference anyplace these different
functional interfaces are expected.
0:30
And again,
the way these functional interfaces work
0:35
is that they have
a single abstract method.
0:38
As long as our Lambda, or
method reference, meet the signature
0:41
of the expected functional
interfaces method we can use it.
0:45
This method signature is also
known as a function shape.
0:49
I like to think of a function shape
as one of these little kid's toys
0:53
where you have these shapes that
need to fit into the specific holes.
0:56
The shape needs to line-up
to fit in specifically.
0:59
Now, so far we've only looked at
one type of function shape, and
1:03
that is the Consumer.
1:07
Out of the box there are quite a few of
these function shapes that Java offers.
1:08
Each of these function shapes
have a pretty specific use case.
1:12
In my experience,
most of the problems that we encounter
1:16
can be solved with the defaults provided
in the Java.util.function package.
1:20
So I want to take a moment with you and
explore the documentation.
1:25
We'll review the Consumer and then go over
the three other basic function shapes.
1:28
Okay, so I'm gonna go and search for
1:33
Java.util.function and then package.
1:37
And it's gonna bring up this right here.
1:43
This is the official help, so
1:45
this package contains some more
specialized versions of the basics.
1:47
So, for instance, this first one
here is our friend Consumer, right?
1:51
But as you can see it accepts two
parameters, so it's called a BiConsumer.
1:56
So to get started looking in here,
2:01
let's look at one that we're familiar
with, our old friend Consumer.
2:03
Let's take a look.
2:06
So down here in Consumer,
It says, represents an operation
2:07
that accepts a single input argument and
returns in the result.
2:10
It's exactly what we were working with.
2:14
So let's click into it.
2:16
So if we scroll down a little
bit here to the methods,
2:19
we can see the different types.
2:21
And if we click in here under
Abstract Methods, you can see the single
2:23
Abstract Method that we were talking
about, which we know is called accept.
2:27
Now its signature requires a type of T,
2:31
which if we look up here it says the type
of input to the operation, right?
2:34
So in our case this T was a string and
it returns nothing, right?
2:38
It returns a void.
2:41
Now we know that we could use this
with a forEach on iterables because,
2:42
well, we just used it.
2:46
But what if we wanted to see where
this was used elsewhere in the JDK?
2:48
Now, when learning how to use different
tools I find it super helpful
2:52
to see some examples of
how it's being used.
2:56
There's a handy little tab at
the top of Java docs called Use.
2:58
So let's do that, let's click Use.
3:02
Or you can [LAUGH] also read this as use,
3:04
like show me some use for
this, either way.
3:07
All right, so here it shows
Packages that use Consumer and
3:12
here's places where it's
being used as a parameter.
3:15
So we'll see here that forEach
uses a Consumer, just like we saw.
3:19
I find this super handy when
you're trying to learn something.
3:23
So let's pop back to the Package level,
so we'll click Package.
3:25
All right, so let's pick up on
our next functional interface.
3:29
Let's scroll down here and
take a look at Supplier,
3:32
represents a supplier of results.
3:36
Thanks a lot.
3:39
Let's dive in.
3:40
Okay, and we'll go down and we'll take
look at the single Abstract Method,
3:42
it's just called get.
3:46
Okay, so it gets a result.
3:47
So it doesn't take any parameters and
it returns a type of T,
3:50
which in this case is the type of
result supplied by this supplier.
3:55
So this function will supply
its caller with a value.
3:59
Now note, this is a different
shape than the Consumer.
4:03
Our Consumer is a function that consumed
an object and did some stuff but
4:06
didn't return anything.
4:11
This supplier, when implemented,
won't actually take anything,
4:12
it just returns, it supplies something.
4:16
This is handy in places where
you want an object, and
4:19
you don't really care how it's created.
4:21
Supplies, here's your birthday cake.
4:23
Sorry, that was a dumb joke.
4:25
No supplies there.
4:27
Man, that double.
4:28
So the way that these functional
interfaces are named, Consumer and
4:29
Supplier, describes how they
are expected to be used.
4:34
Now speaking of being used,
let's click the Use tab again up here.
4:37
So let's scroll down and let's take a look
at Methods with parameters of type.
4:42
Let's take a look at this one here,
this is a pretty fun one.
4:49
This is called Objects.requireNonNull.
4:51
So if we click into here, we can see
that this was introduced in 1.8 or
4:55
Java 8, as we call it.
5:01
So it's a helper method that you can
use to make sure that your parameters
5:02
are not null and it actually throws
a null pointer exception for you.
5:06
It kind of wraps up all
that ceremony we do, right?
5:10
Like if object is null, then throw a new
illegal argument exception sort of thing,
5:12
kind of wraps that all up.
5:16
It's a customized null pointer exception.
5:17
So it's pretty straightforward, right?
5:21
You just give it an object, and
5:22
then you give it a supplier,
the second parameter, right?
5:23
This is similar to how the forEach
method expected a Consumer.
5:27
This requireNonNull
method expects a Supplier.
5:31
So let's use it, right?
5:35
Let's flip back to our code.
5:37
And let's do it in this yell method here,
right?
5:39
So make sure that words comes
in always non null, right?
5:41
And actually let's do this.
5:47
Let's imagine a feature request came in.
5:48
And the object here was to create an issue
in our bug tracker system every time that
5:51
yell is called with a null value, so that
we could try to stop that from happening.
5:57
You don't want anybody to
yell without any words.
6:02
So what we'll do is if it is null we'll
open up an issue in a bug tracking system.
6:05
Sound good?
6:10
So let's do it.
6:11
So we will say Objects.requireNonNull.
6:11
And we're gonna check here on words first.
6:17
We'll see that it wants a Supplier.
6:20
Cuz it's an overloaded method.
6:24
One takes string and one takes a Supplier.
6:26
Now these Suppliers are great because
they're what's known as lazy.
6:29
The Supplier will only be called
when words here, when this is null.
6:33
Otherwise it's just a function
waiting to be called.
6:37
But it's not going to do anything just yet
because it's lazy.
6:40
So we need to add a Supplier here,
so let's put a Lambda in place.
6:44
So what I'll do is I'll open
the parentheses like we know, now.
6:48
[SOUND] It doesn't have any parameters,
so what do I do?
6:52
Well, the answer is this,
you just leave the parens.
6:55
Just like when you call a method
that doesn't take any parameters.
6:59
It's just opened and
closed, just like that.
7:01
Okay, and
then we need to do the body, right?
7:04
What we want over here, is we want to
return a string that will be used for
7:08
the null pointer exceptions message, okay?
7:11
So what's gonna happen is when this
is missing it's going to try to
7:14
get this message.
7:18
So we'll just keep this on a single line,
right?
7:19
So there's no need for the open bracket.
7:22
One more sugary nicety
of a single line Lambda
7:25
is the return keyword is always assumed.
7:28
So I can just put what I
want to have returned here.
7:31
So, let's see,
that would look something like this.
7:33
Let's say that we want it to say Created
Issue and then we'll make up a method.
7:36
We'll just talk about a method.
7:45
Andd so we'll say Main.,
let's call it createIssue.
7:46
It'll be a static method.
7:50
It doesn't exist, but
we'll do that for now.
7:52
And let's see.
7:57
So we'll create the create method issue.
7:58
And in here we'll just fake an API call.
8:03
We'll say something like Some
8:05
external API call to a bug tracker.
8:09
And we could imagine that that would
happen, is it would go out call,
8:15
create a ticket, and
it would return some sort of ID.
8:18
So we'll just pretend for right now
8:21
that this is some sort of ID to our bug
tracking system so we can find issues.
8:23
So since this method is expensive, right,
tt's gonna go out and do this API call,
8:28
we don't want this to happen all the time.
8:33
And we're leaning on the laziness of
the requireNonNull method, right?
8:34
Keeping all of this execution, all of this
stuff in here is inside of the Supplier.
8:39
It's only gonna happen when this is null.
8:43
So if we come down here to the end,
we can actually now make it fail, right?
8:47
So we'll say Main.yell,
now I'm gonna pass in a null.
8:50
Then we run it.
8:56
And bam, some external call to a bug
tracking system and we'll see up here
9:00
in the NullPointerException that
it says Created issueABC123.
9:06
Pretty powerful?
9:11
We'll dive deeper into the laziness
concept here in a bit and
9:12
in fact I'm gonna go park that
term just to make sure that
9:15
we don't forget about
talking about it more.
9:18
So let's do that,
here we're gonna add lazy.
9:21
This seems like a pretty good time to take
a little break before we dive back into
9:24
the remaining basic function shapes.
9:28
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up