1 00:00:00,000 --> 00:00:04,849 [MUSIC] 2 00:00:04,849 --> 00:00:09,347 A common task in programming is to process an entire list of elements to produce 3 00:00:09,347 --> 00:00:10,930 a single value. 4 00:00:10,930 --> 00:00:13,040 For instance, you might have a list of numbers and 5 00:00:13,040 --> 00:00:15,210 you wanna know what they all add up to. 6 00:00:15,210 --> 00:00:17,558 That would return a single number. 7 00:00:17,558 --> 00:00:20,730 Maybe you wanna find the smallest number in that list or maybe the largest or 8 00:00:20,730 --> 00:00:22,000 the average. 9 00:00:22,000 --> 00:00:26,420 The point is you can reduce a collection of things to a single value. 10 00:00:26,420 --> 00:00:27,540 Now unfortunately, 11 00:00:27,540 --> 00:00:31,640 the job postings we've been working with don't have salary information. 12 00:00:31,640 --> 00:00:32,980 Get used to that during the job hunt. 13 00:00:34,050 --> 00:00:37,000 So we'll have to come up with something else to count. 14 00:00:37,000 --> 00:00:38,160 We'll find something to reduce. 15 00:00:39,650 --> 00:00:44,230 Okay, so you can actually have more specialized streams. 16 00:00:44,230 --> 00:00:47,010 So instead of before we had just a stream like this, 17 00:00:47,010 --> 00:00:50,960 well there's actually one called an IntStream, all right? 18 00:00:50,960 --> 00:00:55,300 And so then, of course, you can add primitive ints here in the varargs. 19 00:00:55,300 --> 00:00:58,910 So we'll say IntStream.of, we'll just give 1, 2, 3, 4, and that is IntStream. 20 00:01:04,910 --> 00:01:11,210 And this new stream gives you some handy terminal reduction operations, like sum. 21 00:01:11,210 --> 00:01:13,190 So that will take everything and add that up. 22 00:01:13,190 --> 00:01:19,455 So let's do this, I'm gonna go ahead and wrap this in a print line. 23 00:01:19,455 --> 00:01:20,829 We'll just move this up here. 24 00:01:23,650 --> 00:01:26,990 Let's get this in here, like so, there we go. 25 00:01:26,990 --> 00:01:30,345 So if I run that, it will add that up, 10. 26 00:01:30,345 --> 00:01:31,861 And so because it's a stream, 27 00:01:31,861 --> 00:01:35,374 we can add whatever intermediate operations we want in here, like so. 28 00:01:35,374 --> 00:01:40,697 We could say filter and it's gonna get a number and 29 00:01:40,697 --> 00:01:46,180 that number is going to be that number less than 4. 30 00:01:46,180 --> 00:01:47,850 So that will add up anything less than 4. 31 00:01:47,850 --> 00:01:50,210 So 1 plus 2 plus 3 is 6. 32 00:01:51,212 --> 00:01:55,590 So there's also a way to find the minimum value in the list. 33 00:01:57,900 --> 00:02:02,760 Now this is interesting, it returned what is known as an Optional. 34 00:02:02,760 --> 00:02:06,080 And that's because, what if this stream was empty, right? 35 00:02:06,080 --> 00:02:08,060 What's the minimum of nothing? 36 00:02:08,060 --> 00:02:13,070 So optionals provide a way to state that the value is either present or absent. 37 00:02:13,070 --> 00:02:14,630 They help avoid null pointers, 38 00:02:14,630 --> 00:02:18,510 so let's focus on that after we finish exploring reduction. 39 00:02:18,510 --> 00:02:24,008 So as you can imagine, there's also a max that's also gonna return an optional. 40 00:02:24,008 --> 00:02:25,971 Because what's the max of nothing? 41 00:02:25,971 --> 00:02:28,770 And you can also very quickly grab an average. 42 00:02:30,750 --> 00:02:35,884 Now notice that this returns a Double to take care of the half here, right. 43 00:02:35,884 --> 00:02:40,200 And again, it's an optional, because what's the average of nothing? 44 00:02:40,200 --> 00:02:44,088 So what happens if you wanted to take advantage of these powerful reduction 45 00:02:44,088 --> 00:02:45,763 operations in a normal stream? 46 00:02:45,763 --> 00:02:50,214 Now since we don't really have any great numbers, let's try to find 47 00:02:50,214 --> 00:02:55,291 the average number of letters in these potential employer's company names. 48 00:02:55,291 --> 00:02:57,700 Sound good? 49 00:02:57,700 --> 00:02:58,798 Okay, so I'm gonna get rid of this. 50 00:02:58,798 --> 00:03:03,180 Let's do jobs.stream. 51 00:03:03,180 --> 00:03:06,320 And let's get the title of the company, so first we'll get that. 52 00:03:06,320 --> 00:03:11,132 So we're looking to use a method reference to get the company, right? 53 00:03:11,132 --> 00:03:14,128 And streams actually provide the way for 54 00:03:14,128 --> 00:03:19,076 you to specialize your stream and they come in the form of .mapTo. 55 00:03:19,076 --> 00:03:21,650 So see there, it says mapTo, and we're going to do a mapToInt. 56 00:03:23,230 --> 00:03:26,720 And then inside here there's just a normal mapping function, right? 57 00:03:26,720 --> 00:03:30,457 So we'll do companyName, right, cuz that's what's coming from above. 58 00:03:30,457 --> 00:03:34,604 And we will do companyName.length. 59 00:03:38,095 --> 00:03:39,060 And look at that. 60 00:03:39,060 --> 00:03:41,640 It is suggesting that we go ahead and 61 00:03:41,640 --> 00:03:45,070 use a method reference, right, cuz we're just taking in a value. 62 00:03:45,070 --> 00:03:47,590 And then we're calling a length on it, so let's do that. 63 00:03:47,590 --> 00:03:50,400 So it's just String::length on the company name that comes through. 64 00:03:50,400 --> 00:03:53,830 And so now we have an IntStream, right, like we just had. 65 00:03:53,830 --> 00:03:56,740 And so now I can do a thing like average. 66 00:03:56,740 --> 00:04:00,360 Let's see what the average company length name is. 67 00:04:00,360 --> 00:04:02,660 I should have left that print there. 68 00:04:02,660 --> 00:04:03,917 Get that back real quick. 69 00:04:08,879 --> 00:04:10,320 There we go. 70 00:04:10,320 --> 00:04:15,430 So on average, the employers have 15ish characters in their name, that's cool. 71 00:04:15,430 --> 00:04:17,200 Let's see what the longest one is. 72 00:04:17,200 --> 00:04:21,328 So I'm gonna say, what's the max of those company names. 73 00:04:21,328 --> 00:04:24,430 71, what? 74 00:04:24,430 --> 00:04:27,370 Now, I totally wanna see what that is, but how would you do that? 75 00:04:27,370 --> 00:04:30,250 Since we converted that to an int, 76 00:04:30,250 --> 00:04:32,590 we're only getting the numbers through the stream. 77 00:04:32,590 --> 00:04:34,410 So let's back that up a bit. 78 00:04:34,410 --> 00:04:40,530 So streams themselves also have a max and they require a comparator. 79 00:04:40,530 --> 00:04:43,330 So let's do that, so let's instead of getting the length right here, 80 00:04:43,330 --> 00:04:45,080 let's do this max. 81 00:04:45,080 --> 00:04:49,020 So see, max is now asking for a comparator. 82 00:04:49,020 --> 00:04:50,650 So it's asking for a comparator. 83 00:04:50,650 --> 00:04:52,190 And you'll see that the one that it suggests, 84 00:04:52,190 --> 00:04:56,200 actually right off the top, is this Comparator.comparingInt. 85 00:04:56,200 --> 00:05:02,430 So let's do that, and Comparator is looking for one of these toInt functions. 86 00:05:02,430 --> 00:05:05,870 So it's looking for something that will return an int. 87 00:05:05,870 --> 00:05:08,100 So we just looked at one of those, right? 88 00:05:08,100 --> 00:05:10,380 That's exactly what String::length does. 89 00:05:11,750 --> 00:05:14,340 So this is gonna get the company with the longest name. 90 00:05:14,340 --> 00:05:15,042 Let's see. 91 00:05:17,752 --> 00:05:21,910 So it's Newtek Technology Solutions, a branch of Newtek Business Services Corp. 92 00:05:23,270 --> 00:05:24,860 I see why that's why so long. 93 00:05:24,860 --> 00:05:27,680 Now, that seem to little magical, didn't it? 94 00:05:27,680 --> 00:05:29,450 If so, I feel you, right? 95 00:05:29,450 --> 00:05:31,992 So let me show you a harder way of doing this right now. 96 00:05:31,992 --> 00:05:36,124 So might have seen comparators before, probably you have, right? 97 00:05:36,124 --> 00:05:38,410 That's how you end up sorting things a lot. 98 00:05:38,410 --> 00:05:41,480 So the way that comparators work 99 00:05:41,480 --> 00:05:44,410 is you do something that it takes two objects, right? 100 00:05:44,410 --> 00:05:48,443 So in this case, we're gonna have company1 and 101 00:05:48,443 --> 00:05:51,760 company2, that's what it's gonna use to compare them. 102 00:05:51,760 --> 00:05:57,510 And here in the body, what we'll do is we need to compare these two. 103 00:05:57,510 --> 00:06:02,600 And the way this compare method works is that if it returns anything negative, 104 00:06:02,600 --> 00:06:04,710 the first item is considered smaller. 105 00:06:04,710 --> 00:06:06,890 If it returns 0, they're considered equal. 106 00:06:06,890 --> 00:06:10,560 And if it returns anything positive, it's considered greater. 107 00:06:10,560 --> 00:06:12,550 So imagine one of those scales, right? 108 00:06:12,550 --> 00:06:16,670 If you imagine putting the length of each company's name on each side of that, 109 00:06:16,670 --> 00:06:17,680 that's what we're doing. 110 00:06:17,680 --> 00:06:20,640 We're weighing which one of these is longer. 111 00:06:20,640 --> 00:06:25,170 So with some mathy thoughts, if I subtract the values from each other, 112 00:06:25,170 --> 00:06:29,100 that should cause us to get the right positive, negative or equal, right? 113 00:06:29,100 --> 00:06:38,094 So if I say, company1.length- company2.length. 114 00:06:40,574 --> 00:06:43,989 You'll see if we run it, we'll get the same answer. 115 00:06:43,989 --> 00:06:48,900 And an even cooler, if we go here and we take a look at what IntelliJ's suggesting. 116 00:06:48,900 --> 00:06:50,900 It says replace with a comparingInt, and 117 00:06:50,900 --> 00:06:52,860 it figured out that we're doing the string length. 118 00:06:52,860 --> 00:06:53,880 Pretty cool, right? 119 00:06:53,880 --> 00:06:58,460 So this method, this comparingInt here, takes a function and 120 00:06:58,460 --> 00:07:01,140 returns a function to max. 121 00:07:01,140 --> 00:07:02,210 Pretty cool, right? 122 00:07:02,210 --> 00:07:06,495 So functions that do just that are called higher order functions, 123 00:07:06,495 --> 00:07:08,801 which we already have parked here. 124 00:07:08,801 --> 00:07:12,222 But you can actually write these powerful functions, too, and 125 00:07:12,222 --> 00:07:14,448 they're so expressive, aren't they? 126 00:07:14,448 --> 00:07:16,330 And that is so nice. 127 00:07:16,330 --> 00:07:17,010 Okay, so 128 00:07:17,010 --> 00:07:21,140 now that you've seen some of the out of the box terminal reduction operations, 129 00:07:21,140 --> 00:07:25,130 why don't we explore how to deal with the optional values they sometimes return.