1 00:00:00,590 --> 00:00:04,120 So we now have a couple of pretty succinct ways to create and 2 00:00:04,120 --> 00:00:06,420 pass functions into methods. 3 00:00:06,420 --> 00:00:09,530 Are you starting to get a sense of how powerful this can be? 4 00:00:09,530 --> 00:00:12,900 Are you noticing how it feels just a little bit different? 5 00:00:12,900 --> 00:00:15,870 Well, that feeling is totally fine and it's actually expected. 6 00:00:15,870 --> 00:00:18,780 Like we talked about, this is a different way of thinking, 7 00:00:18,780 --> 00:00:22,140 it's bound to feel a little bit strange, especially at first. 8 00:00:22,140 --> 00:00:25,790 We're about to go a little bit deeper now, but the basic concepts are the same. 9 00:00:26,870 --> 00:00:30,390 The main thing that I want you to know is that you can provide a Lambda or 10 00:00:30,390 --> 00:00:34,420 method reference anyplace these different functional interfaces are expected. 11 00:00:35,530 --> 00:00:38,490 And again, the way these functional interfaces work 12 00:00:38,490 --> 00:00:41,170 is that they have a single abstract method. 13 00:00:41,170 --> 00:00:45,100 As long as our Lambda, or method reference, meet the signature 14 00:00:45,100 --> 00:00:49,270 of the expected functional interfaces method we can use it. 15 00:00:49,270 --> 00:00:51,950 This method signature is also known as a function shape. 16 00:00:53,270 --> 00:00:56,690 I like to think of a function shape as one of these little kid's toys 17 00:00:56,690 --> 00:00:59,700 where you have these shapes that need to fit into the specific holes. 18 00:00:59,700 --> 00:01:03,070 The shape needs to line-up to fit in specifically. 19 00:01:03,070 --> 00:01:07,060 Now, so far we've only looked at one type of function shape, and 20 00:01:07,060 --> 00:01:08,470 that is the Consumer. 21 00:01:08,470 --> 00:01:12,650 Out of the box there are quite a few of these function shapes that Java offers. 22 00:01:12,650 --> 00:01:16,640 Each of these function shapes have a pretty specific use case. 23 00:01:16,640 --> 00:01:20,050 In my experience, most of the problems that we encounter 24 00:01:20,050 --> 00:01:23,840 can be solved with the defaults provided in the Java.util.function package. 25 00:01:25,150 --> 00:01:28,250 So I want to take a moment with you and explore the documentation. 26 00:01:28,250 --> 00:01:32,520 We'll review the Consumer and then go over the three other basic function shapes. 27 00:01:33,600 --> 00:01:37,342 Okay, so I'm gonna go and search for 28 00:01:37,342 --> 00:01:41,706 Java.util.function and then package. 29 00:01:43,833 --> 00:01:45,510 And it's gonna bring up this right here. 30 00:01:45,510 --> 00:01:47,400 This is the official help, so 31 00:01:47,400 --> 00:01:51,250 this package contains some more specialized versions of the basics. 32 00:01:51,250 --> 00:01:56,140 So, for instance, this first one here is our friend Consumer, right? 33 00:01:56,140 --> 00:02:01,470 But as you can see it accepts two parameters, so it's called a BiConsumer. 34 00:02:01,470 --> 00:02:03,350 So to get started looking in here, 35 00:02:03,350 --> 00:02:06,600 let's look at one that we're familiar with, our old friend Consumer. 36 00:02:06,600 --> 00:02:07,210 Let's take a look. 37 00:02:07,210 --> 00:02:10,960 So down here in Consumer, It says, represents an operation 38 00:02:10,960 --> 00:02:14,690 that accepts a single input argument and returns in the result. 39 00:02:14,690 --> 00:02:16,240 It's exactly what we were working with. 40 00:02:16,240 --> 00:02:17,257 So let's click into it. 41 00:02:19,364 --> 00:02:21,696 So if we scroll down a little bit here to the methods, 42 00:02:21,696 --> 00:02:23,130 we can see the different types. 43 00:02:23,130 --> 00:02:27,380 And if we click in here under Abstract Methods, you can see the single 44 00:02:27,380 --> 00:02:31,280 Abstract Method that we were talking about, which we know is called accept. 45 00:02:31,280 --> 00:02:34,570 Now its signature requires a type of T, 46 00:02:34,570 --> 00:02:38,280 which if we look up here it says the type of input to the operation, right? 47 00:02:38,280 --> 00:02:41,680 So in our case this T was a string and it returns nothing, right? 48 00:02:41,680 --> 00:02:42,710 It returns a void. 49 00:02:42,710 --> 00:02:46,420 Now we know that we could use this with a forEach on iterables because, 50 00:02:46,420 --> 00:02:48,150 well, we just used it. 51 00:02:48,150 --> 00:02:52,100 But what if we wanted to see where this was used elsewhere in the JDK? 52 00:02:52,100 --> 00:02:56,020 Now, when learning how to use different tools I find it super helpful 53 00:02:56,020 --> 00:02:58,400 to see some examples of how it's being used. 54 00:02:58,400 --> 00:03:02,570 There's a handy little tab at the top of Java docs called Use. 55 00:03:02,570 --> 00:03:04,250 So let's do that, let's click Use. 56 00:03:04,250 --> 00:03:07,874 Or you can [LAUGH] also read this as use, 57 00:03:07,874 --> 00:03:12,081 like show me some use for this, either way. 58 00:03:12,081 --> 00:03:15,854 All right, so here it shows Packages that use Consumer and 59 00:03:15,854 --> 00:03:19,400 here's places where it's being used as a parameter. 60 00:03:19,400 --> 00:03:23,420 So we'll see here that forEach uses a Consumer, just like we saw. 61 00:03:23,420 --> 00:03:25,550 I find this super handy when you're trying to learn something. 62 00:03:25,550 --> 00:03:28,010 So let's pop back to the Package level, so we'll click Package. 63 00:03:29,250 --> 00:03:32,576 All right, so let's pick up on our next functional interface. 64 00:03:32,576 --> 00:03:36,689 Let's scroll down here and take a look at Supplier, 65 00:03:36,689 --> 00:03:39,500 represents a supplier of results. 66 00:03:39,500 --> 00:03:40,610 Thanks a lot. 67 00:03:40,610 --> 00:03:42,890 Let's dive in. 68 00:03:42,890 --> 00:03:46,475 Okay, and we'll go down and we'll take look at the single Abstract Method, 69 00:03:46,475 --> 00:03:47,915 it's just called get. 70 00:03:47,915 --> 00:03:50,370 Okay, so it gets a result. 71 00:03:50,370 --> 00:03:55,010 So it doesn't take any parameters and it returns a type of T, 72 00:03:55,010 --> 00:03:59,870 which in this case is the type of result supplied by this supplier. 73 00:03:59,870 --> 00:04:03,760 So this function will supply its caller with a value. 74 00:04:03,760 --> 00:04:06,810 Now note, this is a different shape than the Consumer. 75 00:04:06,810 --> 00:04:11,300 Our Consumer is a function that consumed an object and did some stuff but 76 00:04:11,300 --> 00:04:12,540 didn't return anything. 77 00:04:12,540 --> 00:04:16,110 This supplier, when implemented, won't actually take anything, 78 00:04:16,110 --> 00:04:19,060 it just returns, it supplies something. 79 00:04:19,060 --> 00:04:21,490 This is handy in places where you want an object, and 80 00:04:21,490 --> 00:04:23,330 you don't really care how it's created. 81 00:04:23,330 --> 00:04:25,740 Supplies, here's your birthday cake. 82 00:04:25,740 --> 00:04:27,350 Sorry, that was a dumb joke. 83 00:04:27,350 --> 00:04:28,750 No supplies there. 84 00:04:28,750 --> 00:04:29,930 Man, that double. 85 00:04:29,930 --> 00:04:34,190 So the way that these functional interfaces are named, Consumer and 86 00:04:34,190 --> 00:04:37,651 Supplier, describes how they are expected to be used. 87 00:04:37,651 --> 00:04:42,748 Now speaking of being used, let's click the Use tab again up here. 88 00:04:42,748 --> 00:04:49,540 So let's scroll down and let's take a look at Methods with parameters of type. 89 00:04:49,540 --> 00:04:51,530 Let's take a look at this one here, this is a pretty fun one. 90 00:04:51,530 --> 00:04:55,560 This is called Objects.requireNonNull. 91 00:04:55,560 --> 00:05:01,140 So if we click into here, we can see that this was introduced in 1.8 or 92 00:05:01,140 --> 00:05:02,500 Java 8, as we call it. 93 00:05:02,500 --> 00:05:06,300 So it's a helper method that you can use to make sure that your parameters 94 00:05:06,300 --> 00:05:10,600 are not null and it actually throws a null pointer exception for you. 95 00:05:10,600 --> 00:05:12,680 It kind of wraps up all that ceremony we do, right? 96 00:05:12,680 --> 00:05:16,610 Like if object is null, then throw a new illegal argument exception sort of thing, 97 00:05:16,610 --> 00:05:17,840 kind of wraps that all up. 98 00:05:17,840 --> 00:05:21,060 It's a customized null pointer exception. 99 00:05:21,060 --> 00:05:22,270 So it's pretty straightforward, right? 100 00:05:22,270 --> 00:05:23,590 You just give it an object, and 101 00:05:23,590 --> 00:05:27,300 then you give it a supplier, the second parameter, right? 102 00:05:27,300 --> 00:05:31,560 This is similar to how the forEach method expected a Consumer. 103 00:05:31,560 --> 00:05:35,590 This requireNonNull method expects a Supplier. 104 00:05:35,590 --> 00:05:37,450 So let's use it, right? 105 00:05:37,450 --> 00:05:39,280 Let's flip back to our code. 106 00:05:39,280 --> 00:05:41,490 And let's do it in this yell method here, right? 107 00:05:41,490 --> 00:05:47,340 So make sure that words comes in always non null, right? 108 00:05:47,340 --> 00:05:48,855 And actually let's do this. 109 00:05:48,855 --> 00:05:51,520 Let's imagine a feature request came in. 110 00:05:51,520 --> 00:05:57,320 And the object here was to create an issue in our bug tracker system every time that 111 00:05:57,320 --> 00:06:02,470 yell is called with a null value, so that we could try to stop that from happening. 112 00:06:02,470 --> 00:06:05,380 You don't want anybody to yell without any words. 113 00:06:05,380 --> 00:06:10,250 So what we'll do is if it is null we'll open up an issue in a bug tracking system. 114 00:06:10,250 --> 00:06:11,080 Sound good? 115 00:06:11,080 --> 00:06:11,810 So let's do it. 116 00:06:11,810 --> 00:06:17,646 So we will say Objects.requireNonNull. 117 00:06:17,646 --> 00:06:20,713 And we're gonna check here on words first. 118 00:06:20,713 --> 00:06:23,334 We'll see that it wants a Supplier. 119 00:06:24,891 --> 00:06:26,630 Cuz it's an overloaded method. 120 00:06:26,630 --> 00:06:29,070 One takes string and one takes a Supplier. 121 00:06:29,070 --> 00:06:33,080 Now these Suppliers are great because they're what's known as lazy. 122 00:06:33,080 --> 00:06:37,920 The Supplier will only be called when words here, when this is null. 123 00:06:37,920 --> 00:06:40,570 Otherwise it's just a function waiting to be called. 124 00:06:40,570 --> 00:06:44,330 But it's not going to do anything just yet because it's lazy. 125 00:06:44,330 --> 00:06:48,110 So we need to add a Supplier here, so let's put a Lambda in place. 126 00:06:48,110 --> 00:06:52,220 So what I'll do is I'll open the parentheses like we know, now. 127 00:06:52,220 --> 00:06:55,930 [SOUND] It doesn't have any parameters, so what do I do? 128 00:06:55,930 --> 00:06:59,270 Well, the answer is this, you just leave the parens. 129 00:06:59,270 --> 00:07:01,760 Just like when you call a method that doesn't take any parameters. 130 00:07:01,760 --> 00:07:04,070 It's just opened and closed, just like that. 131 00:07:04,070 --> 00:07:06,720 Okay, and then we need to do the body, right? 132 00:07:08,150 --> 00:07:11,910 What we want over here, is we want to return a string that will be used for 133 00:07:11,910 --> 00:07:14,750 the null pointer exceptions message, okay? 134 00:07:14,750 --> 00:07:18,600 So what's gonna happen is when this is missing it's going to try to 135 00:07:18,600 --> 00:07:19,760 get this message. 136 00:07:19,760 --> 00:07:22,090 So we'll just keep this on a single line, right? 137 00:07:22,090 --> 00:07:25,200 So there's no need for the open bracket. 138 00:07:25,200 --> 00:07:28,500 One more sugary nicety of a single line Lambda 139 00:07:28,500 --> 00:07:31,390 is the return keyword is always assumed. 140 00:07:31,390 --> 00:07:33,940 So I can just put what I want to have returned here. 141 00:07:33,940 --> 00:07:36,640 So, let's see, that would look something like this. 142 00:07:36,640 --> 00:07:44,170 Let's say that we want it to say Created Issue and then we'll make up a method. 143 00:07:45,490 --> 00:07:46,777 We'll just talk about a method. 144 00:07:46,777 --> 00:07:50,421 Andd so we'll say Main., let's call it createIssue. 145 00:07:50,421 --> 00:07:52,379 It'll be a static method. 146 00:07:52,379 --> 00:07:55,430 It doesn't exist, but we'll do that for now. 147 00:07:57,010 --> 00:07:57,510 And let's see. 148 00:07:58,780 --> 00:08:02,020 So we'll create the create method issue. 149 00:08:03,200 --> 00:08:05,600 And in here we'll just fake an API call. 150 00:08:05,600 --> 00:08:09,994 We'll say something like Some 151 00:08:09,994 --> 00:08:15,068 external API call to a bug tracker. 152 00:08:15,068 --> 00:08:18,548 And we could imagine that that would happen, is it would go out call, 153 00:08:18,548 --> 00:08:21,330 create a ticket, and it would return some sort of ID. 154 00:08:21,330 --> 00:08:23,790 So we'll just pretend for right now 155 00:08:23,790 --> 00:08:28,730 that this is some sort of ID to our bug tracking system so we can find issues. 156 00:08:28,730 --> 00:08:33,130 So since this method is expensive, right, tt's gonna go out and do this API call, 157 00:08:33,130 --> 00:08:34,640 we don't want this to happen all the time. 158 00:08:34,640 --> 00:08:39,460 And we're leaning on the laziness of the requireNonNull method, right? 159 00:08:39,460 --> 00:08:43,550 Keeping all of this execution, all of this stuff in here is inside of the Supplier. 160 00:08:43,550 --> 00:08:46,100 It's only gonna happen when this is null. 161 00:08:47,250 --> 00:08:50,810 So if we come down here to the end, we can actually now make it fail, right? 162 00:08:50,810 --> 00:08:54,890 So we'll say Main.yell, now I'm gonna pass in a null. 163 00:08:56,680 --> 00:08:57,623 Then we run it. 164 00:09:00,993 --> 00:09:06,229 And bam, some external call to a bug tracking system and we'll see up here 165 00:09:06,229 --> 00:09:11,137 in the NullPointerException that it says Created issueABC123. 166 00:09:11,137 --> 00:09:12,374 Pretty powerful? 167 00:09:12,374 --> 00:09:15,638 We'll dive deeper into the laziness concept here in a bit and 168 00:09:15,638 --> 00:09:18,646 in fact I'm gonna go park that term just to make sure that 169 00:09:18,646 --> 00:09:21,158 we don't forget about talking about it more. 170 00:09:21,158 --> 00:09:24,220 So let's do that, here we're gonna add lazy. 171 00:09:24,220 --> 00:09:28,810 This seems like a pretty good time to take a little break before we dive back into 172 00:09:28,810 --> 00:09:30,820 the remaining basic function shapes.