A More Functional Loop5:46 with Craig Dennis
Let's explore the new `forEach` method that expects a `Consumer.
One of the more challenging concepts to grasp as you are just picking up 0:00 functional programming is dealing with how to create loops. 0:04 Almost everything we do in programming deals with a collection of data and 0:08 we must process that collection, typically element by element. 0:12 Let's take a quick look at the most basic way to do this and 0:16 further use it to create our first function. 0:19 Sound good? 0:21 Okay so we have our collection here already. 0:22 So for simplicity's sake, 0:25 lets assume that we want to print out each of the ingredients on a single line. 0:27 So how do go about doing that with our imperative style? 0:32 Well, to start, lets just go ahead and I'll reuse some of this code here. 0:35 All right, so we don't need this line anymore. 0:38 And I'll just go ahead and comment this. 0:41 And we'll just loop through each of the ingredients and we'll print it, right? 0:45 We'll print that ingredient that's coming through the list. 0:51 Wanna get rid of this too, here, right? 0:54 That's how we would do it imperatively. 0:58 List them out on each line, right? 1:00 Okay, so all classes that implement Iterable, like our list class here, right? 1:05 It implements Iterable, that's why we're able to loop through here. 1:12 Well they also have a new method named forEach. 1:15 So let's explore that a little bit. 1:19 So if I come in here and I say ingredients.forEach. 1:21 And I'm gonna open and close the parens and then I'm gonna press F1. 1:25 Okay, so if we take a look at the bottom here, 1:31 it says this has been around since 1.8, which is Java 8, all right? 1:33 So what this does is it takes an action type of Consumer. 1:38 All right, so it takes an action of type consumer. 1:43 So here it says, it performs the given action for each element of the Iterable 1:47 until all elements have been processed or the action throws an exception. 1:50 Hey, that's exactly what we need, right? 1:54 So our action is going to be, print out each ingredient. 1:55 So let's take a look at what this consumer says here. 2:00 Okay, so it's in the java.util.function package and it's a functional interface. 2:02 We'll take a look at these here more in detail. 2:07 But for now I just want you to think about a functional interface as an interface 2:09 that has exactly one abstract method. 2:14 It's a SAM, a single abstract method. 2:17 So it represents an operation that accepts a single input argument and 2:20 returns no result, cool. 2:23 So it's unlike other functional interfaces, 2:25 Consumer is expected to operate via side effects. 2:27 That is another one of these terms that we are gonna talk about later. 2:29 And I'm gonna put it in the parking lot, 2:32 so know that we don't need to worry about it. 2:34 Don't let these new terms overwhelm you. 2:37 So, we'll come over here. 2:38 Here's our parking lot. 2:40 I already added Pure from before. 2:40 So I'm gonna go ahead and I'm gonna add side effects, perfect. 2:42 Okay, so we need to add a new consumer, and 2:48 I am going to let our IDE give us a little help here. 2:51 So I'm gonna say, new Consumer, and I'm going to press Tab. 2:54 And it's gonna go ahead and auto-complete that. 2:58 And because it has a single abstract field, 3:00 it's gonna automatically pop out what we need to override, right? 3:03 Cuz it knows that's the only thing we need to do. 3:06 And this is pretty standard, right? 3:09 This is how you would actually do things before Java 8. 3:10 There's nothing new here. 3:13 A single abstract method, this is a common concept for these classes. 3:14 You would say new and it would tell what it wanted to override. 3:18 So inside this method here I think we wanna do just like we did up top, right? 3:21 We wanna just print out s. 3:24 I wanna put a semicolon here at the bottom. 3:29 Okay, so I'm gonna comment out this here and 3:31 I'm going to go ahead and give this a run. 3:35 Awesome, it works. 3:44 So this is the declarative way to do things. 3:47 Now I'm not sure if you saw it, but when I came in here and I chose Help. 3:50 It says, unless otherwise specified by the implementing class, 3:56 it's gonna go ahead and order the iteration. 4:00 What's cool about that, is that this is a great example of the declarative when. 4:02 By stating what we want, but not how to do it, 4:07 we take that problem out of our hands, right? 4:10 Before we were saying, we were talking about how to loop through it. 4:13 This is putting it in the hands of the iterator. 4:19 So that assumes that the Iterable here 4:22 knows how best to loop through its own items, right? 4:24 It's none of our business. 4:27 So once more, the forEach method handles the looping. 4:28 And when it has each single item, it calls or invokes this new consumer here, right? 4:32 That gets instantiated, and it passes that value into the accept method. 4:38 So notice how here it has a specified parametrized type of string? 4:46 So you can read this as it's a consumer of strings, 4:51 and that's just what we did, right? 4:54 We provided a forEach method, a function that consumes strings. 4:56 Now if this seems a little clunky to you, you're totally right. 5:02 Up until Java 8, this is the way to do things with single abstract methods. 5:06 You instantiate a new, temporary, anonymous class, just like this. 5:10 It's pretty ugly. 5:16 I can think of exactly zero people who thinks it looks pretty. 5:17 [LAUGH] So you'll see a ton of this in UI event handlers, like your Android apps or 5:21 Java effects. 5:26 So you wind up sifting through a bunch of code like this. 5:27 Just for a single line, a single method. 5:32 Well, here's some great news. 5:36 The language has introduced a new syntax to make this much more prettier and 5:37 more succinct. 5:42 Let's make things pretty right after this quick break. 5:43
You need to sign up for Treehouse in order to download course files.Sign up