Optionals9:56 with Craig Dennis
Optionals help express the absence or presence of a value.
Okay, raise your hand if you ever received a null pointer exception. 0:00 I see, every single one of you. 0:05 Now keep your hands raised if you are ever happy about that happening. 0:07 Nobody. 0:11 Null pointer exceptions happen when you attempt to access a property or 0:13 a method on an object, and that object is in fact not there, it's null. 0:16 So of course you can call a method like, get first name on nothing. 0:21 So a runtime exception is thrown. 0:25 And you track the error through the code 0:27 to find out that it's possible that the object, 0:30 the one that you so confidently trusted in being there, actually isn't. 0:32 So how do you know that the value might not be there? 0:37 Well, that's a great question. 0:40 And the simple answer is this, you actually don't. 0:41 You have to trust your API designer won't return a null or 0:44 you have to be overprotective. 0:49 You see this null protection all over the place in code. 0:51 You know the difference. 0:53 Is this thing null? 0:54 If so, throw in an exception. 0:55 If not, everything's cool. 0:56 Let's keep going. 0:57 Now because some of these terminal stream operations are known to maybe 0:59 not return a value, Java 8 introduced a new class called optional. 1:04 They are intended to be used as return values for methods only, and 1:09 they represent the presence of a value or the absence of a value. 1:13 Now this is a common concept in many programming languages, 1:17 usually it's known as an option type. 1:21 More frequently known as a maybe type in functional programming. 1:23 Check the teachers notes for more information. 1:27 By getting your hands on one of these optionals, you know very clearly that 1:30 there is a possibility that maybe there isn't a value for you to access. 1:33 Let's take a quick look at what we can do with optionals that are returned 1:38 from these terminal operation. 1:41 >> So we've seen that aggregates like max and min will return an option, 1:43 because there's a chance that there are no items. 1:48 Remember what's the max of nothing? 1:51 So using a similar thought process let's write in, 1:53 I'm feeling lucky style search of the job titles. 1:56 Now that's that google style of search where you just return the first result 1:59 whose job title contains a specific word, okay? 2:04 So let's write the search first. 2:06 So that would look like we have a stream, right? 2:08 And we'll just use a simple filter, right? 2:11 So we'll say filter, we'll say where the job, 2:14 where the getTitle contains Java. 2:18 To make that whatever later. 2:26 So there's a terminal operation called findFirst which 2:27 returns the first item that is found. 2:31 Just like it says. 2:34 okay, so let's use the intention action here and let's see what it creates. 2:36 So we'll introduce a local variable, and it creates an option of jobs and 2:40 we're gonna call it foundJob. 2:44 Now let's go ahead and let's print that out, so we'll print out foundJob. 2:46 Cool, so the first job that I found is from Business Intelli Solutions in Frisco, 2:54 Texas. 2:59 It's a junior Java job plus QE role. 3:00 That sounds fun. 3:03 QE being Quality Engineer. 3:04 All right, so see how the job variable is inside of an optional. 3:07 Now that's because the value is present. 3:12 In fact, there is a method on the optional that lets us see if it is in fact present. 3:15 So let's do that. 3:21 We'll say foundJob and this is an optional, isPresent. 3:22 And if you want to get the value out of an optional, you can just call get on it, so 3:28 we'll say .get. 3:32 And there so true, and you'll see that it's no longer wrapped there. 3:36 But what happens if the value isn't there? 3:40 So let's see. 3:43 Java is across just about every industry that I can think of. 3:44 So let's see if I can break it. 3:49 I want the Java job in the trampoline industry. 3:50 So if we run it, boom. 3:56 See how the isPresent is false, and it's attempting to get an empty optional, 3:59 throws a NoSuchElementException. 4:04 Which is more or less a null pointer exception. 4:08 So as you can imagine you can deal with this optional in an imperative way, right? 4:10 I mean I could hypothetically put this get here inside of an if statement. 4:15 And I can check first to see if it's present, just like our null pointer dance. 4:21 But as you can probably imagine by now, the optional 4:24 actually has some great declarative approaches to the problem space. 4:28 So let's do this, let's go ahead and turn this into a method. 4:33 So we probably wanna have a variable, so let's extract this variable out first. 4:37 Let's do this. 4:42 So I'm gonna use the action head. 4:44 I'm gonna say extract variable, [LAUGH] and it wants to call it trampoline. 4:45 Let's call it searchTerm. 4:50 Let's do that again. 5:02 So I'm gonna take this trampoline and I'm gonna refactor and extract the variable. 5:04 I want the variable to actually go outside. 5:11 So let's go ahead, we'll say that that's fine, but I'm gonna move this up here. 5:12 And now we don't need this anymore, we don't need this, let's see if this will 5:16 swing it to single lambda, there we go. 5:22 And it's called, we want this called search terms, 5:25 and then we'll choose refactor rename. 5:30 And a rename code occurrences to searchTerm. 5:35 Here we go. 5:40 And then we wanna turn this whole thing here into a method. 5:41 So let's do that. 5:47 Let's do refactor and we'll say extract method, 5:48 and we will call this LuckySearchJob. 5:54 And yeah it's gonna take jobs and it will take the search term, okay? 5:59 And if we switch this back to Java, I'm gonna do a run, 6:07 cool, see it's still working. 6:11 So now that we're returning this search, we can go ahead and 6:16 we will say, make this an if. 6:21 So we'll say, if foundJob isPresent. 6:24 Now we are safe to use the get here Right, so we can safely use the get. 6:28 So that is what the null dance looks like. 6:36 Because we know that this is gonna be here, 6:38 we can go ahead and chain off of the outside of it. 6:43 So we know because it's present. 6:45 So now I can use getTitle. 6:47 And if I run this, there we go, 6:49 we'll just see that it is printing out the title there. 6:52 So if we take a look at this intention action here, 6:56 it's gonna suggest something that's kind of nice. 6:58 This is the declarative side. 7:00 It says replace optional is present with ifPresent. 7:01 So let's go ahead and do that. 7:06 So ifPresent takes a consumer, right? 7:07 It takes a consumer, a consumer does this, and this returns to nothing. 7:09 See how it takes whatever value's passed in. 7:13 This job here, this will only be called if it's present. 7:15 Otherwise, nothing will happen. 7:19 So again, let's go ahead, let's switch this back to trampoline. 7:21 We run and nothing happens. 7:27 But sometimes you want to return a value like if there isn't a value there at all. 7:30 Like in the case maybe I wanna show no job found for instance. 7:34 So let's look at this imperatively first. 7:39 Let's switch this back to where we were. 7:41 So that's imperatively. 7:46 So maybe, I would like to say, else, No jobs found. 7:47 Let's run that and then let's run trampoline, right? 7:55 And so it's gonna hit the other branch. 8:03 No jobs found. 8:08 So declaratively, options have some really nice methods. 8:10 So here, check this out. 8:14 Let's get rid of all of this and we're gonna print out, foundJob. 8:15 Now this is an optional and optionals have a map method, so let's do .map. 8:21 And it works just like streams. 8:32 So we're gonna pass in a method reference here. 8:34 So it's gonna get the title off of that job should it exist. 8:37 And just like we had before in the else, there's a method called orElse 8:42 which sounds a little over the top like orElse. 8:47 And then you'd have the value that you'd like to show. 8:52 So you say, No job found. 8:53 Cool, so once again if you get rid of this and 8:57 you try to run it It's gonna say optional empty, right? 9:00 Because there's nothing for it to do there. 9:03 But if I drop the orElse, and 9:06 I don't know why this isn't lining up it should be lining up. 9:10 No jobs found. 9:17 There are a bunch of different functional approaches to dealing with 9:22 optionals which make them quite nice. 9:25 But it's also a bit misunderstood. 9:27 Check the teacher's notes for more information. 9:29 So the main trick to remember with optionals is that if you're going to go 9:31 the imperative route and you call get yourself, remember, 9:36 always check to see if is present first. 9:40 Otherwise you'll end up causing the equivalent of that null pointer exception 9:43 that we've all learned to not love. 9:46 All right, so let's take a quick break and 9:48 then swing back to take a look at how to let streams self generate for us. 9:50
You need to sign up for Treehouse in order to download course files.Sign up