Transcripts
1. 01 Welcome to the Course: Hello there. And welcome to this course, which provides a comprehensive introduction toe working with the job, a platform my name's might speak on. I'll be your instructor. I have over 20 years Experience is a software engineer and code level architect working at various organizations from large global investment banks through two small high tech startups. I'm really excited to person my job, right knowledge, and we're gonna have a lot of fun together, learning about all the fantastic new features that job has to offer. So let's get started.
2. 02 Introduction Java 8 Theory and Examples Section: before we get into looking at Java eight. Since sex and examples, it's we have taken just a few moments to understand a bit about what you are for It is on what it brings to the table. John has been around for well over 20 years. Now 23. In fact, on there's probably being more talk about Java eight, this particular release than any other version and quite rightly so. It's the most significant version since job was launched because it introduces the language changes into the platform. What I just talking new MP eyes and speed and tooling improvements. Now this release of the Java platform gives us new constructs in the job a problem in language itself. So in this section, we're going to get some context and see what java it is, what the men building blocks are and how they relate to each other. And this way we'll have a good, high level overview of the platform and foundation to build on. So let's get started
3. 03 Difference Between Object Oriented and Functional Programming Styles: in this video, we're going to have another view of the idea behind your operates so we can put it all in context. Java. It's a big topic, so it'll do us some good. So now what makes it tick? So what is Javaid and why is it so important? Well, with Java, there's a new big idea in town, and that's the idea of functional programming. This is what job eight is all about. Really. Now, as Java programmers were used to the idea of object oriented programming O R P. This is where the men building block of our programs, the things the problem is built. Town self is the object. We create classes which model some domain. You know, some real world scenario, which is relevant to the application we're designing, create instances of those classes. These are objects, thrown some dead REM behavior, and then we have an application so that so api, which uses objects in its main building block on. We're already familiar with those since we've been calling like that since the beginning of Java. Now in functional programming, the men building block is the function. It's something which takes an input. Does something to it performs some operation on it on returns, an output. So we have two very different programming approaches here. We can use objects in our P world or we can use functions in a functional world. Now you're probably thinking, how does this relate to job eight? Well, how this relates to job is the job of AIDS as functional programming to the platform. This means we now have the best of both worlds. We can use objects and their methods in the imperative way like we've always been used to doing. Or we can create using composed functions, put them together on operate on data in a declarative way that would brief aside, I just use two terms there on I don't want them to just fly past you without understanding exactly what they mean imperative. And the clarity. Just so you're aware, with these men going forwards says they're two very different programming styles on methodologies. So programming an imperative way or programming in an imperative programming language means you're actually defining exactly how something should be done. So this level were concerned with things like how loops accorded with the variables that use the flags we set to check for certain conditions to be able to control the exit from the loop, etcetera. Imperative problem is based on those kinds of best level constructs, so it kind of coding the solution to something from the ground up. You're really Koerting, The implementation blow by blow in the detail allowed by those various standard programming language constructs available to you. That's imperative programming. We're all used to doing this by now, since that's pretty much how we have done things with job for up to this point. Just think of it as regular programming, since it's what everybody is used to doing now in the Java Sea, seekers person dot net worlds programming in a declarative weather, our programming with a declarative problem in language. This means we're not focused on how we do something like we are an imperative programming. So we're not problem in the actual details of a solution. Using those base level constructs like loops, condition, ALS, switch statements, etcetera. No wonder the clarity of style. We're not specifying that how we do things, but instead we're defining what we want doing. So the shift go to specifying what you want to have happen, as opposed to how you want it to happen. We'll see as we go through the course how Java rate allows us to use either style weaken, stick to the traditional imperative way of coding things like we've always been usedto. Or we can use the functional programming features provided by the platform to current our solutions into the clarity of way. We'll see this more when we get to pipelines and streams later in the course. But I just wanted to make sure we understand what those two terms meant going forwards. So now we're on the same page with a different programming paradigms, object oriented in its imperative form and functional in its the clarity form. You can probably imagine that this let's set under the problem in paradigm to the Java platform, which is effectively, what they've done with job AIDS is actually a big thing. And it is. It turns out, it has a massive impact and takes a job, a platform to a whole new level in programmer productivity and expressiveness within card. Put simply, this means that Kurt, written with Java eight, is now easier to write because of this easier to debug reason about adapting men 10 really is a huge advancements of the job of platform, and it's gonna make you a better and more productive developer for it. You're gonna be excited to learn all about it and see what it can do for you. I'm sure I will explain all about it in the next videos.
4. 04 A Quick Look at the Main Java 8 Features: in order for job aid to introduce functional programming to the platform. It's added some new language features. The majority of those features exist, so why that allow you to code in a functional way or they've been introduced to onboard this new functional programming machinery, if you like into the platform. So let's dig in now and take a look at the different pieces of Job eight, which make functional problem impossible. By the way, as we go through these, they might sound intimidating. But don't worry. We'll go to a more in detail and later units. We're just introducing them here so they don't feel so aliens. You, when we come to talk about them in each different section, so hang in there or will become clear as we get through the course and look at them all together. First up, we have lander expressions. These allows to pass behaviors functions, which is a key aspect of functional programming. So what? We mean past behavior. Well, by behavior, we mean a chunk of code that could be executed. Someone does allow us to pass chunks of code around in a nice, easy and lightweight. You can think of them as methods without a name for now, which could be assigned to on red from variables on past two methods. Here's a simple under expression to give you an idea before Java. Eight. You can only pass behavior by creating a class which housed the method. Continued the chunk of code you wanted to pass, but differently. Whenever you wanted to pass code around, you had to create a class for it just to be able to do that. And it will be that class which had the method, which in turn, had the Children could you actually wanted to pass? So with Java eight. We don't have to do that anymore, thanks to a lander. Expressions, as you can see there, nice and light whip. They're not heavy on the hands on. We don't need to type a lot. Compare that with the old school way of doing things in the pre job Eight world. We have to do something like this awful stuff you can see here that we've got to write the enclosing class we just spoke about. We've got to code the clunky method signature to possibly have an interface, since when its past to whatever needs to receive it. The calling card needs to have a way of accessing it. And that's through interfaces, of course, so you can see the pre java eight way is clunky, verbose, and it just feels unnecessary, really. It's not just extra typing. You have to do that. You have the extra files in your project to one for the class and possibly one for the interface. If you provide it yourself and you want to have the mental baggage now of having to deal with two new types, well, the good news is that with blunder expressions introduced in Java, ate, all this is redundant. You just write and pass a lambda on your them lender expressions. Remove the need to create this boilerplate card around the method, and I was too cleanly and concisely passed just the code. Next, we have functional interfaces, which provide a range of so called target times for lander expressions. It's great that we can now pass functions around inch arbiters, lander expressions, but we still need to keep things types. If when storing the lander, expression in variables are passing or returning them from methods, don't forget everything always need to type. Whenever you do these things on Java, it doesn't change. This job is still very much a strongly typed language, so there needs to be some kind of mechanism of keeping things type safe on functional interfaces. Do this for us. Give you a sneak peek, but without going into massive detail. Here. This is a function interface in action. You can see we're assigning a lender expression, which doubles numbers to a so called functional interface defined in Job eight. The inter function, a function we call takes an input on returns an output, and in this case, it takes an inter and returns and ends Because it's pretty common java. It gives us a pre defined function interface for this, which is this in function? You see, you can also write your own function interfaces to, so no need to worry. You'll always have a target site for your Landers. Getting deeper into programmer productivity. There's now a brand new stream verse deploy, which leads a supply functional programming to collections and chain operations together, for example, filtering a list of objects than applying a mapping to access to get on the filtered objects on Finally converting them back into a set, so the result would be a filtered set of the maps type. Here's a snippet of code, which does just that. Nice and concise on the clarity of in nature. So with pipelines and streams, we spend less time saying how we do things and concentrate simply on what we want doing. Using this declarative style, they're easier to use and explain the extremely powerful. So those are the men features in Java rate. But in addition to those, it was necessary to have some other features and concepts to to be able to make it all work nicely together. In other words, not break existing legacy code. What's enhancing it to offer the new, functional way of doing things? So now we have what I call the other features of Jarve. A. These are like the glue which points it all together in order to problem and functionally particular with the changing of stream best operations we just mentioned. We don't want to have to start worrying about checking finals in there. Optionals provide a neat and tidy way of dealing with this. There's an optional zp oy, which is best around providing a type level way of preventing the dreaded nor pointer exception, which fits naturally in a functional context. In fact, there's a whole air p I written around this optional concept, which means you can not only deal with stream programming in a functional way, but also do some nice functional things with conditions to, amongst other things moving on. We have default methods these allows to define implementation called inside an interface. Now this sounds a bit contradictory. After all, we're used to interfaces only having public abstract methods and no implementation. But it's not a mistake. It really does exist. And it's actually an elegant way of being able to evolve an interface that is at a future to it without breaking existing implementations. This is something that was required to facilitate Java eight stream best programming across all collection classes. We also have static methods and inter vs to which again provide implementation but are not specific to an instance of an interface. So it's a good place to put utility methods, for example, which might belong there. Finally, at least in terms of language, significant features, we have method references. These are likely to provide appointed to a method by just supplying its name. This allows us to reuse existing methods we have in functional contexts by treating them like Lambda Expressions and using them in the same places. So, for example, we can pass existing methods around using these and plugged them into our collection processing pipelines. So there was a quick summary of the most important features in the next. Units will look at each in detail to see how it plays a part in the job. A landscape. It's a lot to take in and don't expect you'll understand even a fraction of it from that short overview will be digging into detail in the later videos, but this was just to give you a test of what's to come.
5. 05 Passing Behaviour with Lambda Expressions: so we've job eight, making the bold and exciting move to introduce functional programming into the platform. This means that functions have now become first class citizens in the language. So to clarify what that means, they could be passed on return from methods stored in variables on modified, just like job of Primitives and objects Camp. To support this, Java introduces a new construct which allows functions to be defined. After all, if you're storing these functions in variables and passing them around, you need to have a way of actually creating them in the first place. So in Java, it functions can be created with this new construct, which has been introduced just for this purpose. This is the Lambda expression, whereas we predominantly past data around the no system packaging functions, a pinto Lambda expressions allows us to pass behavior around. Let's just take a quick look at way. We're already used to passing behavior. The most common scenario that springs to mind our event listeners. This is where you pass incurred to be executed in response to a button press, for example. This is common in swing and android. Through action, listeners click listeners etcetera next we have comparative. Here you create a class which knows how to compare to objects of the same type, which defines an ordering between them. You can then pass this to a sore routine, which will use it to order the elements in accordance with the comparison. Then we have the various filters that we might implement, for example, of file name filter, which can filter a list of files. There are lots of other cases, too, where we pass behavior around, but these are some common ones, which you're probably already familiar with. Lender expressions allow operations like these to be expressed very concisely, with the minimum amount of code. This leads to functional Koenen Job eight. Being very compact and elegant as we'll see to demonstrate this, let's remind ourselves of what we'd have to do to get a button to respond to a click event in swing prior to Java. Eight. First, I would have to create a rapid class, which has the method we want executing when the button is clicked. This is our event handle occurred. Swing off was the action listener interface for this on. We can see here we're implementing that interface so that we can plug out behavior one. Then we didn't stanciute that class so that we can pass the resulting object into the method which registers are event handler. This is the action performed with it on Jay Button. Although it's quite simple code, it's still relatively non trivial to put it all together. After all, we only want to execute the method with one line and we have to provide a class providing the action is. The reason for this is that before Job eight on the perimeters are, objects could be passed to methods on, so the best we could do then was to pass an object which had the core but method we wanted executing. We could compacted into less lines there. For example, if we don't need the event listener to be used any other u i component, then we could define the classes Anonymous and pass it in line into the call for the ad action list. The method like this, this saves is creating an additional job, a source file, just a house, our event handler. But ultimately we're still having to write a lot of courage to do something which should be quite simple. Now Java eight enables us to pass behavior around in the form of lander expressions very concisely, without the baggage of having to create an instance. See it a container or rapid class like we saw before. Here is the equivalent example in Job eight code here. We just passed the function that is the lander expression to the method, and that's all we need. So as you can see, Lunder expressions allow us to cut out a lot of boilerplate code, since functions have now become first class citizens in the language, and this is key to allowing us to do functional programming very cleanly and concisely on the job of platform in the next, videos will delve into defining our own under expressions and see how to use them.
6. 06 Lambda Expressions Syntax and Examples: in this video, we're going to look at how to create our own Lambda expressions. So let's examine the Sensex of Lambda expressions now so that we can start using them. Under expression consists of mostly three parts parameters which define inputs to the function, followed by an arrow operator which appears to point to the function body, which could be a single expression on multiple statements. Such general former is like this, but there are variants to make the Sensex exclusive. The as we'll see. It's easier and more intuitive to see examples of lander expressions in order to understand the syntax and it's variations. So let's look at some examples now. This is a Lambda which takes nor parameters has no inputs on Prince. A message to the console. Since it takes no parameters, we have empty parentheses in the Pam's block. That's the bid in front of the arrow operator on always need to provide these, even though the function takes no input. Also, since the function body is only a single statement, we don't need to supply surrounding curly braces. Compare that with this example here we have multiple statements in the function body that's the bit after the arrow operator, and so we need them here. So whenever you have multiple statements and you're not just returning a value or doing something simple, saying a one liner, you need to enclose the body of the Lambda in curly braces. It's just like with if else blocks, really, if we need more than one statement in the F, or else we need them there, too, so nothing should feel that strange with this. Hopefully, so far, we've just seen simple lenders, which don't take any arguments or returning the values, taking it up a notch. We can also pass inputs under expressions, too. Now, this Lunder expression takes two ends and multiplies them. It also returns the value. Although this isn't explicit in the syntax in general, it's accepted that Lambda may or may not return a value on to specify this would have made since act Smart ruling to deal with this probably does feel a bit strange. You know the fact that we don't specify a return type, but it's just the way it is. Don't wear that. You'll soon get used to it soon enough. You'll also see, in this example that parameters are separated with commerce in the parameters list regarding the input parameters. Not that the times are actually optional and don't need to be specified if the compiler canon further types based on the lander expression usage. So we could also admit the types of the input parameters like in this example, the two parameters A and B un prefixed with their types. In this example, the types are always optional if the compiler com'on for them. Based on how the lander expression is being used, the syntax is fairly straightforward and intuitive, as you can see. Of course, we haven't covered the situation where we have three parameters. Two of them are strings, and one is an integer, and it returned to double. But you can probably work out how you might write this any way you want to give the types or done. You don't need to worry about the return type, and only have to do then is to figure out if you need to put curly braces around. Yet if it's a multi line code block, so lender expressions nice, lightweight and easy to use, you can't use them on the run them. In fact, if you just copy paste those expressions we walked through into an idea, just as it's expected to compile. It won't do just yet, and that's because they can't just exist on the run. They need to be either stored in a variable or Pastore method, and to see how to do this, we need to understand functional interfaces and target types, which will do in the next videos, so stay with us.
7. 07 An introduction to Functional Interfaces with Examples: functional interfaces or a new concept in Java eight introduced to support the use of Lambda expressions. So what are they exactly? Well, a function is expressed in the form of a lander expression. This is the encapsulation of the function code into a form that could be passed to a method . Return from the method or assigned to a variable. However, Java is a strongly typed language with a strict type system, and so anything we store passel return requires a well defined type. This means that we need a way of providing a time fell under expressions on this is exactly what functional interfaces do. They provide the reference types for lander expressions. Here's a trivial lander expression. It doesn't take any input parameters and just prints a message to the console. Now let's suppose we want to store this lander. Expression in a variable or placid is a parameter to some method, but with the reference Tybee that we'd use, it turns out we could use a few different types. But for the sake of argument, will use this one, which communicates the idea of running a piece of code, as is with nine puts or return value the rentable. Now we normally associate the renewable interface with the running of threats, but how we're using it here has nothing to do with that. It's just a functional interface, which happens to be a compatible target type for the lender expression were given. We'll get to what functional interfaces really are in a moment, and how we define them will explain all this. But for now, just hang in there with the example and don't give into any thoughts of multi threading because it's nothing to do with it. So we can use renewable as our reference type on the compile. It would be happy. This is because the method signature of the run method in winnable matches the implied method signature of the lander expression. In other words, it takes no import arguments to the function on returns. No value. Not that we can use any compatible method. It's defined in a functional interface. So, for example, if we had a function interface defined like this, we could also assign the same lander expression to that reference. Type two. So this is also legal. This is a short video that has some key points, which we should emphasize function Interfaces exist, so the lander expressions could be bound to a type known as a target type. There could be many different valid types, which a lander expression could be bouncer. All that is required is that the method signatures are compatible. Are you there except the same input and return the same type? They're the glue, if you like, which allow lander expressions to have a type in Java. Now this is great. You now know why we have function interfaces, but that still leaves a few questions. How do we find functional interfaces to use on? What if one doesn't exist already? Can we make up our own? Well, these are great questions on will answer these in the next few videos too.
8. 08 Using Function Descriptors to Choose Compatible Target Types: since Job is a strongly typed language where everything must have a type. Lunder expressions are also required to have a type. Now this is where function interfaces come into the picture on the idea of function descriptors. So let's take a quick look together now at what this is all about. A lender expressions such as this has an implied method. Signature. Look at the syntax. We can see that this under expression takes too intense A and B on returns. It means this implied method signature of a lander expression is better known as its function descriptor. The function descriptor is just offensive way of saying which types to function takes as input on which type it returns its output. It's the method signature, if you will, without the method in them. Now, 13 descriptors are not used in Java code. It's not like a syntax thing or anything. You don't declare function descriptors or anything like that. So it's not something you're likely run into during data development in Java eight. But the our useful way of thinking about types, and they used behind the scenes in compiling the code, but nevertheless the useful to have in mind when considering types of lender expressions. That's the key thing here. So let's take a look now at some sample function descriptors. Here's one that takes no inputs and returns void. This function is swept. It would match a Venable interface. For example, since the method defined in the interface takes no arguments and doesn't return anything, let's just take a quick refresher look at that renewable interface here. You can see it doesn't take any arguments. There's nothing in the parentheses after the method. Them and then return type is indeed void, meaning it doesn't return anything. So yet it definitely matches the function. New Strip, for example. We just saw this function Descriptive takes to insist parameters on returns and in back, you could imagine a lander expression, which performs an ad operation toe and to introduce together that's having this now for the previous example. It was pretty straightforward to think of an interface that would match for this one, though Maybe it's more of a challenge to find one in the existing. Jenny came Well, it would be before Job eight, but thankfully, this release ships with a whole collection of useful. Let's call them start a functional interfaces which you can use. So in fact, there is an interface which does this already knew to Java eight. An interface which takes two items of the same type on applies an operation to them to produce a result. The same type is known as an operator, so Java eight offers the into binary operator interface for this has shown here you can see it does indeed take to wince on returns an end again matching the example function district . So we just gave Now this is our final example. It shows a function which takes no arguments on produces a strings its returned value again Jarve eight functional interfaces come to the rescue offering what's known as a supplier. This is a functional interface which returns some value. Java is a few of these, for example, of Boolean supply will return a Boolean value double supplier returns a double value and so on. So you'd probably be expecting a string supplier to And you certainly would if all we ever did was right. Hello world programs. But for strength er we have to do a bit more work and use the generic interface. But it's useful to have a quick look. This is a supplier interface, which it will much you can see it doesn't take any parameters and just returns the value of the parameter type back, which in our case, would be a string anyway. We don't want to start running before we can walk there, so let's not get sidetracked with generates. For now. The key part is that a lander expression can be described by a function descriptor on that a function descriptor can match potentially many different interfaces. Of course, I'll use one, but it's handed to have that in mind. It's not just like there's only one interface you can never use a type of lander expression or anything, so this brings us on to the next point. Then, to determine if a lender expression can be typed to a functional interface, we consider the functional descriptors of both items. If the function descriptors are compatible, then the lander expression can be assigned to the type of the functional interface. More technically, the lender expression is allowed to have a target type off the functional interface. So now we've seen a function descriptors and know that they're useful till two years when considering which types we can use for Lambda Expressions and we touched upon function interfaces to. Hopefully, these three cornerstone concept Lambda Expressions function descriptors in functional interfaces. Pop. It's all starting to click into place now, probably slowly at first. There's a lot to take in, so don't worry if you're not quite there yet, but you should be able to have a good feel now for how they're related, and we'll see more of these in action as the course progresses.
9. 09 An Overview of Streams, Intermediate and Terminal Operations: So we've seen the core language supports Java. AIDS offers its for writing and handling functions, namely lambda Expressions and functional interfaces. Now that we've seen that, it's time to turn our attention to another brand new introduction to the Java A platform. And that's the streams FBI, the streams. FBI allows you to process collections in a functional way. After all, the language designers went to great lengths to be able to allow us to use functions in our job occurred on. So it's reasonable now that we should be able to use that shiny, cornu declarative programming style in our existing code. And there's no better place our place with bigger bang for the buck, as it were to do that on a play all that good, functional, clean and concise card stuff. Then, when we're working with collections, the collections FBI being something we worked with on a daily basis, of course. In other words, we can now apply functions be right or even functions that exist already to be able to manipulate the collection on. We do this by plugging in those functions into a so called pipeline what it'll on this in a second, but just know that the big headline here is that the Streams FBI provides a very clean and concise way of processing better in a functional wares. We'll see shortly, by the way, not it's absolute to do with processing collections. That's its sole purpose. When you think of the streams MP, I automatically associate in your head with collections. It doesn't have anything to do with the Iowa P I and Java used for important output through their classes in there, with names like Input Stream and Output Stream on. When we talk about the i o A. P, I will refer to stream based IR. But there's nothing in the Java eight streams FBI, which is to do with those they just happen to use the same term in common. Just remember, Java eight streams there p I equals processing collections in a functional way. So now we've made that clear. Let's take a look at what streams actually are. What is the stream exactly? Well, a stream is a sequence of elements from a source that allows multiple functions to be applied to it by chaining together operations into a pipeline which can process the data in some way. It's important to note the stream is not a data structure like any of the job collection. Classes are. In other words, it doesn't allow you to stall the elements but to process them in somewhere. So the streams AP oy enables us to chain operations together on our functions, applying to the collection of the various stages in this chain this circle pipeline. These operations, which had chained together into this pipeline, are of two types. They're intermediate operations and terminal operations. Now a pipeline is built up of typically one or more in some media operations, which are chained together with a terminal operation chain to the end. So intermediates, intermediates, intermediates terminal. Imagine this would be a simple point for an example, so we can see that it's really the intermediate operations which provide the ongoing functional processing mechanism. After all, the terminal operation just finishes the pipeline. It's terminal is it's at the end so we can see that through this pipeline debt second floor between operations. Hence the word stream. In fact, because that's what a stream is, it's a directional flow of data. So that's a flows between these operations being processed in some way by functions along the way. This chaining across intermediate operations is achieved by those intermediate operations, always returning a reference to the stream, which provides the mechanism, which allows a pipeline to be constructed. We'll see this later when we look at the FBI itself in more detail. Another interesting point is that by separating the operation types into intermediate and terminal the streams, FBI designers made Java eight streams lazily evaluated. There's the evaluation means that an intermediate operation is no actually evaluated until a terminal operation at the end of the chain is reached, so they're lazy in that respect. A terminal operation, however, is the operation actually triggers the evaluation of the pipeline that is, the operations prior to the terminal operation. In having this last step triggered the evaluation of the pipeline, the pipeline itself could even be optimized on. That actually happens behind the scenes. For us, this is quite an abstract concept that is beyond the scope of this course. But needless to say, the streams DePuy hides all of this complexity from you and just delivers performance benefits on no extra cost. At this point, though, some example code would be good to look at as this pipeline stuff sounds rather up in the air. So let's bring it down to Earth and get a handle on it together, which will do in the next video.
10. 10 Understanding Pipeline Collection Processing and Stream API Common Operations: Now we've just been through the high level overview of pipelines and streams on. I appreciate how abstract that must seen. So thanks for getting through that. And it wasn't easy on. Let's jump in now and sea some code so we can get a proper handle on what it means. Here's a sample pipeline, which creates a stream of some strings. It does this so they can be processed using the streams. FBI. That's what the streamed off it does. It creates a stream which we can perform functional operations on a pipeline to process. The days were in some way, so we have this stream of strings on. With this. We can process it by utilizing everything the streams, FBI offices, which will cover shortly. First, let's break down what's happening in this coal, though the first thing that stone with the stream is to do a mapping. This maps a string in the stream to its upper case version. They're all stream operations, or rather, all intermediate stream operations return a stream, as we said earlier, so this means we can keep going and do more stream based processing after this map operation. So next up, the upper care string is passed through a filter method. This filters out. Many strings are exactly five characters in length. Then a sort is applied on the stream. Return from that filter method on. Finally, the stream is processed with a terminal operation, which in this case loops over each elements in the stream prints out the value. There's a lot going on here, but the key points to note are that we need to start with the stream in order to use the streams employ, which is exposed through the stream interface. Then we effectively chain operations together to form a pipeline. This chaining is possible since intermediate operations return a stream each time that cold . Then at the end of the pipeline, we get the actual data. And so we do this by terminating the pipeline with a terminal operation. This study evaluates the pipeline on returns, the results to go back to our example again, which we saw before. You'll know that the intermediate operations take a lander expression. In other words, of function. This is where the functional aspect comes into it, and so each operation in the pipeline effectively applied to function to the elements of the stream in order to perform its processing. This begs the question, of course. What is the type of the lander which is passed in for each operation? So in the case of the map intermediates operation, this takes a function of string to string. Remember, a function takes an input on returns, an output. So in this case, it takes a string and returns a string. In the case of the filter operation, this takes a Pritikin. Would you value it to string input to a bully and output effectually forming a gate for elements to pass through? Finally, for each takes a consumer of string, some function which could be passed a string and do something with it, which in this case we pass abound. Instance with reference to the print line method off system toe out, which in turn, prince two strings one by one to the console. Now we've seen the basic operation of a simple point plan. Let's take a look at how we can actually create streams in the first place so you can create a stream in one of two ways, either by calling the stream method on a collection class limited to lists and sets or by creating a stream out of an array with streamed off. Now I did see you can stream on the lists and sets. You're probably thinking, what about maps? And that's a good point. You can still process these in a stream best way. You just do that through, say, working on any of the methods of map, which will return a set, for example, such a new stream processing on all interest in a map, for example, you can call stream from the set, which is produced when you invoked the interests that method on the map. One thing to point out, which is rather cool, in fact, is that default methods were introduced in Java eight for the sole purpose of being able to add a stream method to existing collection classes without breaking existing implementations. So that's the big idea behind default method. Right there in action, you can check out the video on default method, so them or about those on the ideas behind them later. So now we can create a stream. What can we do with it? Or we have quite a lots of methods which are available on the stream interface on these will seem overwhelming at first, but provide a very rich environment within which we concurred functionally. Don't worry about the amount of methods and how daunting it might look. It's quite straightforward once you're used to it. Just remember that we have two types of operations. Intermediate operations return a stream each time so we can keep processing and chain into media operations together to form a pipeline on terminal operations. They won't return a stream. Instead, they'll return void or non stream result, since this is how the pipeline is ultimately evaluated to access to process data. Given that we have two types of operations intermediate in terminal, it makes sense to group the methods in the stream interface by these two operation types. So let's consider into media operations. Initially, when we think of the collections that streams might be based on, we could imagine one of the most important things would want to be able to do is filter the elements the filter method allows. This on actually filters the stream to the elements that matched the predicate past him. We passing a predicate which will recall returns true or false by evaluating the element against its condition. Next, we imagine we'd like to be able to map elements from one format to another on the map. Method allows us to do just that very thing. For example, if we had a stream of employee objects, we might map to get just the names of the employees. There are other intermediate methods to that. We can use the most common one being sorted, which sorts the elements in the stream on distinct, which removes any duplicates within that stream. So that was a look at the most common into media operations. Now let's take a look a terminal operations. As we said before, these don't return a stream on effective because the pipeline to be evaluated so we can view these methods is really being the result site methods which returned the finished results set. In other words, they're going to return the process stream as a collection awesome days for about the elements of the stream. In some way, probably the most common thing you'd want to do with the process stream is to capture its process elements. So imagine we're filtering, mapping grouping. Possibly you started with a collection of the point of doing all that well so that you'd end up with a different collection of the end of it, So the most common methods would result in a new collection of the streams. Elements are the two methods on the collector's class to set, which returns a set of the elements on to list, which would sends a list. The next thing which comes to mind if we think about what we want to get out of a process stream is an observation about the elements in the stream. So to do this, we contest the elements in the stream. And when we think of testing something, we're really invoking a function against an element which will evaluate to true or false. In other words, we're providing a practical so these types of functions take a predicate to be performed on the elements of the stream. All match will return true if all elements in the stream past the supplied critical, any match will return to if any single element passes the critical. Inevitably, this will short circuit and break out of the iteration assumes the first element matching the predator is encountered. Complaining methods to these are also non match where none of the elements matched the predicate supplied. This obviously has to test all elements in the collection, so be very worry of this for large collections, performance wise and first match, which will give you an optional off the first element passing the predator. Also know that this is an optional into the words this might return empty optionally from No element matched a great way to understand the Marina force What we've seen here. It's a takes some time to go ahead and create some collections and write some stream best code using the streams opioid to process them by creating your own pipelines. So in this module we've seen the power of pipelines and stream best processing with the streams employ. As you can see, it provides a very neat and readable way of processing collections, and before long, you'll be adapted to processing collection types in this very succinct, elegant and functional way.
11. 11 What is an Optional and How Are They Used: in this video, we're going to have a look at the new options feature of Java rate, which gives us a powerful new way of working with values that communal as we'll see So Java . It has introduced this new optionals feature, which provides a type safe way of dealing with possibly Newell values. It allows us to deal with those types of values elegantly and functional code without having to resort to boilerplate nor checks. You know, those if such and such is no equal to know conditional is we get everywhere in job occurred whenever we access and objects fields on methods. Now, if you think about how you might do this for a moment, it's not immediately obvious how we can prevent having to do these no checks, since they're so ingrained in our current day today development style. But once you see the optional FBI in action, you'll see that it's quite simple to understand. And above all it's going to make your code cleaner more readable and generally nicer to work with. So let's take a look together now. It's useful to have a quick recap on nil handling before Java eight to put the optional FBI in context for Let's see a quick example. So let's consider this method Here. Here we have a class department, which has a method to get the employee of the month. That method returns an object of type employees, which will assume has the person's name on there and possibly a few of the extra items our program might be interested in using this method each month, we can generate a report, which includes the current star employees like this. This works fine until we encounter a month when nobody worked hard enough to earn the employee of the month title on, we end up with a no point or exception. When we tried to get its name on this occasion, employee was know, as we all know, whenever we try to deal, reference and all reference, in other words, access some field on the objects on invoca method. On it, we get the dreaded nor pointer exception. Now we can fix this by adding a few more lines and checking for the null like this. When we do this, we're now ensuring the superstar variable definitely has a valid object reference in it. Before we invoke any methods against it. The superstars are equal to no expression is sometimes known as a guard. By the way, just so you know, since you might hear that term to from time to time a way back to the code, though, the code with a null check around it is better. Well, at least in terms of it being more reliable now, we definitely won't get in all points or exception when we do this, but it's still three lines of code to do something quite simple. Let's see how optionals in Java AIDS can improve the situation them now. The problem with the method we've been looking up is that it doesn't force the caller to deal with the fact that they might not be a value in there. There's no warning to the programmer that you might get back, and no, in fact, if you think about it, the method reliability just relies on the problem of being a good citizen for checking. It's not know, just in case. Job Right fixes this by allowing you to wrap an object and an optional In this way, you always have to go through the optional before you can get to the good stuff inside the actual object so we could have an optional of employees, for example, has returned. In this. This means that the value of the optional wraps either holds of our IT employees object. Or it holds a Newell reference now bringing this Is it Nolan not aspect into an actual type ? My E class actually now forces the programmer to deal with the two separate cases. In a clean way, there's no way out. Now you have to deal with the fact that it might be no on explicitly occurred the case when it's no on the case. When it's a valid references, we'll see. I also know that because of you having to go through this optional rapper class, which wraps the object you actually wants, it enforces this dealing with no values. Now with a compile time level. This is a nice side effect. This means that the unexpected exceptions you used to get a runtime in production by no appropriately addressing whether a value might be no or not, those exceptions now become compile time concerns when the compiler itself one that you ignore it. This is really good thing. It means we'll end up writing more of US code on not leaving things to chance as much because we're now forced to deal with the possibility of knows explicitly, so no more. Ah, yeah, I forgot the check. It was no. When you cur blows up in production, above all, the optionals provide an airplane for dealing with these no or populated cases in a nice, functional way. For example, this pre job eight code we have been looking at can be re written more elegantly in Java by replacing it with this more functional version. The first example returns an employee on it's down to the program and to remember to do the null checks. And so this is imperative in nature, Remembering the Imperative World recording explicitly. The second example returns an optional of employees on. Because of this, we don't have to write the null checks, weaken just delegate to the optional FBI to deal with out for us and just invoked the function. Notice that this is functional in nature. It's more declarative style. We're just saying what we want to have happen, not how so. Here it's do this when it's not know, as opposed to check if it's not, nor first, then do this. There's a subtle difference, but it's nice to note. So optionals bring an employee to the table, which allows us to interact with values which may or may not the present in a very clean and functional way, which plays nicely with the rest of the job. Eight Concepts as we'll see.
12. 12 Understanding the Optionals API: in this video, we're going to die of furthering and take a deep look at the options appealing. So let's get to it. So, as we said in the last unit, the idea behind an optional in Java eight is that it brings a rapid time to the table, which in effect states that the object it wraps can be a valid object reference or communal . This is done with the optional type in the Java Util package, and here's an example of just that employees might be no or it might be an actual employees object. Now, since optional is an actual type itself, it's an object. In fact, it comes with its own set of methods which allow us to work with optionals. This is known as the optionally appear on. With this, we can do the following. We can create optionals if we're going to use them. After all, we need to have a way of creating them ourselves. If we're going to be able to pass them back for my methods to other callers, we can check their values into the words. See if they do contain a valid object reference or consent. No, we can also, if they're not referring to null object, get their up values. Since there's a level of indirection now, where we get the rap value from the optional, they also allow us to specify default values in the case. The rap value is no. This is another nice benefit that's being able to supply default values aspect. And finally, there are some more advanced uses which time or into the functional programming side where we can conditionally return them on. Map them more on this a little later. But for now, just that, that this feature allows optionals to play nicely with the new pipelines and streams. Concepts of Java aids anyway, enough, intra, let's see them in action. In this video, we're going to look at the 1st 4 first up, creating optionals. If the optional will have a value, don't forget the point of an optional is that it might or might not contender value. Then you can create them by using the static factor method optional off. Take this, for example. Here we have a string which is wrapped in an optional I know that as a user of the factor method, it's expected that the value U Pass isn't no If it is, this method throws a null pointer exception. They spend his own to how to create an optional which doesn't have a value, a so called NT optional. Well, there's another static factory method for them, which is optional the empty. Since we're creating an entity optional, which doesn't refer to a value, we don't need to pass any value to that method. Now, if you want to create an optional out of a reference which may or may not be no, you can do this with the off gullible method. Unlike optional doff this one thrown or points or exception if the value past is no. So at this point, we now know how we can create optionals, which are there. Definitely hold of value definitely have no value on my told the value. This brings us on to how to look inside optionals to see what values they have on. We have two methods for doing this corresponding to the two states, and optional can be in. Are you the state of having a valid reference on the states of having no reference at all? These methods are is present on is empty is a fairly self explanatory. If the optional wraps a valid reference is, presence returns true. And conversely, if the optional does not reference, a valued object is empty returns. True, when you found out that the optional you're working with does indeed contain avoid object, you can think all that get method on it, which returns the actual wrapped value. I know that if you call get on an optional, which doesn't refer to a valued object, you'll get a no point or exception back from the FBI, so always guard the call to get to ensure there's actually a value inside. The optional by testing is present first, like in this example, you can also conditionally execute code based on the presence of a value in the optional. By using the if present method. In this example, let's assume we search for a star. Employees in the current seen by calling Samir P. I. On it returns an optional to indicate that they may on may not be a star. Employees found in the case that there is one found. The message will be printed. No one to the bit about being able to set default values that I mentioned earlier. So default values air supported with two methods these are or else on or else get or else supplies a default value, like in this example, he has. Suppose we have an EPI I call, which gives the user name associated with a post on a message board or social media feed or stream. If no name is present, will default to use a name to the String Anonymous. We used it or else method to supply an actual default value in this example, where using or else get instead of supplying the default value as is or else get allows us to specify the method or function, rather that there will be called to get the default value if it's needed. So let's suppose that the user, when he or she created an account, could define a password they want to use on. If it didn't specify when will generate one for them. In this case, we wouldn't want to hard code the password and so would call out to some password generation service. The key part here is that we use or else get, which enables us to specify, as we've said, not the default value itself, but the method to get the default value. This is good from a performance perspective. In some cases, for example, it can be useful if you have to call a service other colors expensive in some way. You only want the call evaluated if the optional value doesn't exist at run time. Not in all cases, as will be the case. If you put a method calling, you can also choose to throw an exception if no value is given for the optional. And so finally, we have a last example when we want to throw an exception instead of return a value. Sometimes there's nothing else for it but to throw out an exception if we really can't make do without the real value. So in this code we have an alternative design for the user. If the user supplied no password, were no allowing a new one to be generated, but instead just run back an exception back to the front end. To do this, we use the or else throw method as it's shown here, so you can probably start to get a feel for the optionally appear right now on how it leads us down the road of producing nicer, more readable code. We're not done yet, though we still have the conditional map ings weaken due to on. We'll get into these in the next videos, so stay tuned.
13. 13 Mapping and Filtering with Optionals: So in the last unit we had a good introduction to using optionals uncovered a fair bit of ground in this unit. We're going to step things up a level and see a slightly more advanced usage. These air, the mapping and conditional features that they offer so turn into some other useful functions which are in this line. We're going to look at the map method now. This method allows us to map the rats value of an optional to some of the value. For example, we could map in input string to convert it to upper case like this. Notice that the output of the map function is not the map value itself. This map method doesn't allow us to circumvent the optionals feature, so we still get an optional. It's just now it's an optional of them up to have you. This is important and quite elegant, as it means we can change optional FBI course together to do some further processing in a nice, functional way now that we can map to anything on the object pressed him, for example, Suppose we have a class like this to represent a person with a name and age we could map to get just the age of the person like this. This might not seem so interesting on it some, but again, because of the fact that an optional is returned, we can keep going on. Do more processing to see where this might be useful. For this example, this spring's onto filters, so the map method mapped an optional of person to an optional of integer. Since get Ege returned, an end on this is boxed into an interview rapid type so that we have this map value. When it's an end, we contest the age and see if it falls within a certain range like this because we mapped it to an end to get the age, we can now do it in space operations on it. So here we're filtering to only see the values which fall within a certain range. In this case, between 13 and 19 we might have some logic, which needs to know if John, who was 21 is a teenager on. We can do this now, thanks to the fact that the optional allowed us to map the person object to get the age out of it, and then the optional FBI allowed us to check that age by applying a filter. There's other ways of filtering, but we'll leave those for the pipelines and stream section. But for now, you can see there's a fair amount of power packed into such a small air. P i on a lot more to it than optionals first seem to be. It really shows you the power of the optional FBI on how you can use its methods together, which is very clean code. We're almost done now, but just need to look at one last method, and this is flat map. So what's this all about? Them? Well, we've seen that when we use the map or filter, methods that are optional is always returned on. This is achieved by those map and filter methods. This is the key bit wrapping the return value back in an optional or returning optional the empty If the value was no. The reason we've seen is that this enables us to apply further operations to the value passed back. So as long as we always get back an optional, we can always invoke methods on the optional, and this is what allows us to keep going and change those function calls together. So this idea works fine as long as we return the value itself from the method that map Cole's, however, this Channing through always passing back and optional breaks if the method returns and optionally itself the next Jane Cole would break. So this is where flat map comes in. Flat map does not wrapped the return value and an optional, whereas map does. This leads to the following rules. Use map where the mapping method you pass returns the actual value itself and use flat map where the mapping method you pass returns an optional off the actual value. In this way, you'll never accounting the double wrapping issue on never getting optional oven optional. So, to some of them, as you've seen now, optionals give us a powerful way to cut out a lot of the boilerplate code associated with no pointed checking on Make NorthPoint's or exceptions less likely by forcing us to deal with whether an objects can be no or not. The type level optionals also bring with them a useful appearing for dealing with condition , ALS default values, exceptional cases, mapping and filtering in a neat, tidy and functional way. Providing clean occurred along the way
14. 14 Understanding Default Methods: Let's dig in now and take a look at another feature set of job right, which allows us to put implementation into interfaces, namely default and static methods. Now you have to use these judiciously, and you certainly won't be using them every day. But they're useful thing to having your job. Eight. Developer Toolkit She was them when needed, so let's explore what they are together. Up until Java eight, an interface consisted of just public abstract methods on that was that anyone wishing to provide concrete implementation of an interface in other words, an implementation that could be insensitive with a new key word like this was obliged to implement those methods. It wasn't possible for any form of implementation. To appear in the interface on concrete implementations had to provide all the details. Since Java eight interfaces are now allowed to provide implementation in one of two ways through circled default methods on through static methods, we'll see default methods in a moment. These in the most interesting. But for now, let's take a look at the simplest case static methods. Let's consider an interface person like this. This has two methods. Once again, a person's full name on the other to get a person's age. Now we know from the interface that the get full name method returns a stream on, we might have a need to provide a utility method, which returns an abbreviated name. For whatever reason. To do this, we could provide implementation. In the interface like this. This is a static method in action. It's basically a regular method prefixed with the word static here, which is providing utility method, which can take a name is a string on return, the abbreviated version. So not that we're not referring to any instance there to hear on. That's as it should be. We have no instance data, since it's an interface. And so this method is purely just a chunk of code, which operates stand alone on whichever string it happens to be passed. His input. Notice a few things from here. First up, we signify that we're defining a static method by prefix in the method implementation with the static keyword. This is probably obvious, but worth pointing out also because this Methodist static it is bound to this type on this type on them, so it's no inherited. Any implementations are extensions of the interface. We can only call person, don't get abbreviating them, and that's that. And finally, we're not allowed to call methods in the interface itself, which would access instance, data, for example. We couldn't call get full name as this would refer to the state of the object. We can only call other static methods either On this interface on other types, this leads naturally to the question. Where should I use starting methods and interfaces on the answer? You probably guessed by now is they good for defining utility methods, specifically utility methods that don't depend on state since ecstatic so that static methods and interfaces they're fairly self explanatory and should feel quite natural to use ? Let's take a look at default methods next. This is where it gets a bit more interesting with default methods. It's the same concept, really. We're allowing implementation and interface, but this time it's at the instance level. If we consider by a person example again, which had the static method, it was a little clumsy that we had to pass the name into the get abbreviate in their method . The reason was that we were defining a static interface method and therefore one allowed to access any instance states. However, if we define instance interface method a so called a default method, then we can access instance wise methods and so can change the implementation to call an instance method on the interface itself like this. It's a minor re factoring but makes all the difference. Now it's very clear that the method is designed to operate on the get full name field, since we're actually using that method in the default method itself. It's quite nice that we can do this as it makes our intense, much clearer Let's take a minute to notice the differences from the static Inter First method Implementation two created evil method. We prefix the method definition with the default key would. And, as we said, we can now call the get full name with Atsu I. We can call instance methods within the method definition. Also, not that default methods are not only available on the interface type itself, but also available in any extensions of that interface. Are you classes that extend or implement that interface? The key benefits above static inter first methods on D four methods is that they allow you to add behavior to interfaces that are already out there in the wild, on being used by any of your FBI clients without breaking them. In fact, without this, the addition of one of the biggest benefits of Java would have been impossible. That's the abilities of stream collections to allow them to be processed in a functional way through pipelines or collection. Classes now have a stream method added to them in Job eight, which appears almost by magic on that magic is achieved through default methods. There was a way of enhancing all the collection types without breaking existing clients a few other points around default methods before we wrap up. First off because Steve, what methods provide implementation? We don't need to implement them like we do with normal interface methods. This is kind of intuitive since they're already implemented. However, because their implementation, we have the option of overriding them if we choose to in subtypes on a more subtle point, because we could extend or implement multiple interfaces, it's technically possible that we could implement to inter verses which happened to have the same default method. I use a method name returns either method arguments. If this happens, the compiler doesn't know what to do and will require us to provide our own implementation to avoid ambiguity and resolve the situation. This is highly unlikely, but it's worth pointing out, though, just in case. So, as we have seen, allowing implementation interfaces provides a nice way of pushing generic behavior into them without disrupting existing implementations. Who could just benefit from, or even sound on, the ignore the new behavior, which is pushed to them in its buying re compatible way. This is also the magic that enables Java collections to be enhanced with the stream best programming capabilities under the hood. What's preserving backward compatibility with existing code cost of indeed, but probably more for evolving public opioids and day to day carding but a useful tool to have in your Conan took it nonetheless.
15. 15 Understanding Method References and Their Different Types: with job AIDS opening up the door to the functional programming world, you can imagine that they'd already be tons of methods, which you could use in a functional context. Of course, the question is, How do you do that? Well, the language designers have thought of this, too. As it happens on DSO in Java, eight method references have been introduced, which lets us do just this very thing method references or a new featuring job. Eight on. They allow us to refer to an existing method in a lander expression context. Let's have a quick recap of Landers and function interfaces in Java eight so we can put my other references in context. First up, here's a lender expression. This will take a string and printed to the consul when it's invoked. Nothing fancy. It's just a system out print line, which takes the message to Prince. Everything needs a type in Java, and so we have seen that we can assign this lumber expression to a function interface like this. So what we're actually doing here, its packaging up some implementation in this case, a system out print line statement which will print some message on assigning it to a functional interface. We could assign it to any functional interface which matched the employed method signature of the lander that would use one of the standard function interfaces here, which means a function that takes the value is input but returns them output. This is a consumer. It consumes the input parameter. Through this, we have captured the function but not yet invoked it. So we can then do that quite easily like this. We're now applying the function, the consumer bypassing it. What it needs its simple parameter is required by the consumer functional interface on when running this, the message is printed. Now, when you have a Lunder expression which just cause an existing method, you can use a method reference instead. So to take the two lines of code we just wrote together, which looks like this when we see it side by side, these could be replaced by this. So, as you can see, we have replaced this Lunder expression with this method reference. This is a reference to the static method print line defined in the system to our object. Now, this should feel fairly intuitive once you get your head around lander expressions and functional interfaces. All we've done is swapped out the Lambda for a reference to the one and only method call it makes at this stage. No, you've seen how easy it is. Let's dig a little deeper on Look at the different types of method references we have available to us the awful of the same general since sex with the double colon separating the type or objects in the method. But it's worth going over the four times of method references we have now a quick word of warning. If you read any documentation Oracle's website about method references, you'll see that they use, um, pretty confusing and worded definitions. So I'll give these definitions here now in the bullet points will go through. But as we explain each one, I'm going to give a clear and M for each so you can more readily hold it in your memory on understand what it is. So don't panic. These are going to sound hideously complicated, but it's not too bad once we see what each one is on. When we look at the examples, it should become pretty clear that these types of method reference are the obvious ones we should have anyway. So deep breath now hanging there. The times of method references are as follows a reference to a static method, a reference to an instance method on a particular object, a reference to an instance method on any object on the reference to a constructor. There's a lot here, so let's see examples one by one. First off, let's look at static method references for this. Let's consider the static method Parsons on the class interview. This game is represented as a method reference like this. No, since the parson method takes a string on returns and ends, we can use the function of string and interject type to reference it so it could be assigned and stored like this. Also, as a brief side points notice that the parson method actual returns a primitive in type. But we're allowed to use the function, which references that entered your rapid type. Since the result will be alter box for us from the primitive into into the into your appetite reference, it's good to know that the auto box and feature still plays nicely with all this functional stuff which has been added to the platform anyway. Once we have the method reference, we can invoke it like this. Here we're passing in the string, literal 35 on getting back the actual value as we'd expect. So there's a static method references, which we use when we refer to a static method in the class on reuse it in a functional context. Next, we have instance, method references, and there are two times of these bound and unbound, as we'll see now. Whereas a static meta reference refers to a static method on a class, these types of method references these so called instance met the references refer to an instance method in the class. Since we have a reference to an instance method, it ultimately needs to be invoked against some actual instance. Now we can choose whether we create the method reference to refer to an actual instance, when the method references defined. This is the bounded type, or we can choose whether to defer that binding toe letter and not specify the instance. This is the ungrounded type again. Some examples should make this clear. Take the string quest. This defines a method to upper Case, which operates on a string. Instance, It's an instance method. If we have an existing string object, would want to invoke the method reference against We could supply it like this. Not is that we don't use the string class name when we declare the method reference, but referred to an actual variable which holds a string instance. This is why it's lower case s colon colon to upper case now, since we're invoking a method reference against a specific instance, This method references a supplier which returns a string so it could be assigned and stored like this that at some stage it can be actually invoked to get the result like this returning the capitalist version of the string. At this point, you might be thinking, I don't get it. Why is the to upper case method a supplier? It's blatantly a function which takes a string on returns. The uppercase version, which is also a string so surely it should be function of string string. So, yes, you would be right for an instance method reference off the unbounded type where we don't supply the instance when declaring the method reference. In that case, yes, it takes a string and returns a string on DSO is a function of string string, but not, for instance, method reference of the bounded type, since, in this case, where binding the actual instance, the method reference will be invoked with when we declare the method reference itself and so it doesn't take an input, it just returns the output on anything that just returns. Output is a supplier, so in this case it is a supplier of string. So just to repeat that it's pretty important with the unbound instance. Method reference. There's no context associated with the method reference. No object. Just look at it. It's string with a capital s colon colon to upper case. There's nothing about an actual instance in this definition, and so when you invoke it, you need the string to invoke it against, and then it returns the upper cased version. So string in, string out. That's a function then, so function of string string, but with the bound instance method reference. We deal. Have contact start against it. This is provided by the instance it's been invoked against on. So this is like having a function that's already been filled in with its input. So because of this, the to upper case method reference is no longer a function now. It's already had its input set. When we created the method reference. As you can see, we create the method reference by specifying the instance it is to be invoked against, and so it just returns the value on. For that reason, it's a supplier, which is the function interface with just returns. The value on doesn't take any input. By the way, when you partially filling the arguments for a function, technically create another function by binding one or more of its input parameters like we've been here. That seven for this is currying the function. It's fairly advanced are and we don't want to get side rights. But I thought mentioned in case you ever hear this term in future. Now you know what it means. Anyway. Let's crack on and have a bit of a breather now with something that's finally easy to understand constructed method references. So Leslie then we have constructed with references which, as I said, Kim was a Pleasants price. Since they're easy to understand the news, this is just a method reference which expresses a coal to a constructor like when you invoke the new operator to create a new object of a given class type. For example, if you consider the constructed to create a linked list of strings, its corresponding method reference is this. We can assign and store it like this. It's a constructor, so it's going to return as a value, namely the instance of the list being created so we can type it to a supplier of list. On the specifically state returns is a list of string. Finally, we can invoke it to get the list like this. Notice that the fungal inter first for constructive method references is a supplier on this takes no arguments and just return something. So this means that you can only call no argument constructors. In other words, the basic Defoe constructs that you get in Java, which take no arguments when constructing the objects. It's a limitation, yes, but there it is. Well, that was quite a lot of ground we covered in this module. As you can see, method references answer bad. Once you get the hang of them, you just have to consider what targets hope can be on. This is derived from its context. Once you have them, you can use them wherever lander expressions can be used. On. In particular, you'll see them used a lot in pipelines where stream best programming comes into play on with the optionals. FBI, too. Now that you can spot them, they should be easy to work with on as you've seen at an elegant way in Job eight of referencing already existing methods in a functional context.
16. 16 Introduction Java 8 Coding Demos Section: now that we've been through the nuts and bolts of Job eight on the theory behind all the different concepts in this section, we're going to drill down on, have a look at how we actually code of that in our I DS. Now I'll be using intelligent idea to do this, but the examples work equally well in Eclipse or any other idea that you've got were looking through the thought processes we go through as we could on how we can use the I D features to make things a bit easier for us when working with Java write code. Above all, the will be showing the men features in context so we can get a better understanding of exactly how they work. So let's get to it.
17. 17 A Look at the Functional Interfaces API: in this video, we're gonna go a little bit deeper and explore some other functional interfaces which will come across So there are many different types of function interface in the Java that util functional package. But out of all of those, there are some function interfaces which are just core interfaces, which you simply have to know about because of the many different types of financial interface. These air pretty much suppliers, consumers, predicates, functions and operators. So let's explore with huge one is now. In turn, let's just take a quick look at the Java util dot function Java docks to see which function interfaces we actually have available. That's quite a few. So this is the job doc page for Java Util that function on You can see the top. It says function interfaces provide target types for lambda expressions and method references, which is true. That's what we've seen throughout this course Now. The first time I saw this, I feel a bit swamped, to be honest, because there's so much stuff. There are so many different types, and they all seem to have kind of quite confusing names so much. American services are the ones on Andi when you first how it can be difficult to understand or appreciate where you can even begin. So let's just take a look at what we've actually got in here, because it's actually not that difficult when you look at what they've actually provided. Secondly, we got things like consumers, functions, operators, predicates, suppliers. But then you'll see just kind of repeats consumer operator, consumer function, predicate supply, a function function, operator function and so on. So you really just have these five core functional interface types that I've said before, which a consumer supplier predicated function and operator on within this package? Well, they've actually produced are a set of fungal interfaces, which they're used within the Jedi K itself. So these were the most common ones that the Jedi K code itself actually uses on. As part of this. They've either provided type specific function Inter verses, for example, double binary operator, double consumer inspiring operator Double Eun Rhee. Operator. Those kind of things. These are typically prefixed with either double or end those primitive types or they've given us generic interfaces on. That's where we have to provide a type when we using that fungal interface. Obviously, it's not possible for them to predict all of the types of function interfaces that you'll need. So providing the generic first ones gives us a way through generics or gives them away three dynamics, rather or being able to provide the shape of function interfaces if you like. And then these could be reused in other third party projects like our projects, for example, on all we have to do is plug in the actual types that we want to use this conflict custom classes, for example, like Person employees department, that kind of thing. Or there could be other types used in either the Jedi K or of the open source packages. So, for example, string you won't find any string based function interfaces in here. So let's look at each call function interface in turn and talk through how each is used. So first up, we can see consumer here. So consumers, if I click and consumer and if you look at the actual method signature here, you can see its function. Descriptor is such that it takes an input parameter of whatever type dysfunction interfaces involved with on it returns void and also you can see underneath that you can even chain consumers together. So just like we saw when you can chain optional calls together, because in the cases where an optional returns on optional back or, for example, where an intermediate operation in the pipeline and streams framework returns a stream back and you can keep going by changing those method, Cole's Similarly, you can do the same thing with consumers as well, although that's outside the scope of this course. But it's something to look at if you want to take things further. Next that we have is a function, but we'll come to that a second cause. It's slightly more complicated, and instead we shall turn to supplier. Here. We say it's representing a supplier of results, and it's true. So what air supply it is is it just returned something. It doesn't take any input parameter. You just returned something and you can see here. If we click this get method, we can see here that it doesn't take anything. These empty parentheses here, but just returns a value off the parameter type. Now let's take a look at the function function in space. You can see represented function that except one argument on produces a result. And again we see we can compose functions like we saw before with the consumer functional interface you'll see at the top there, we've got this and then method, but we can pass in a function so that they would use to compose functions together. When you're composing functions together, where you're gonna invoke one after the other, you think ring so called higher order functions. It's just a way of having reusability, but a function level which is quite nice. But again outside the scope of this course, this introductory course. But it's something to look into if you want to take it that next step further. Okay, so the men method Hey we're interested in is a ploy so I can apply. You see, it applies dysfunction to the given argument on what that means is take the input and return some output scrolling down further. We have this predicated one here on a predicate, basically is a function interface where it takes an argument to take some input on will return a boolean true or false. So this is the test method here. Predicates used a lot in stream best processing when we want to filter elements. So that gives you a very quick introduction to the function interfaces, which are available in the job that you told that function package and gives you an idea of where to look, to understand how they work so you can use them in your job of projects. On over the next videos will see how to use these, actually in practice in card.
18. 18 Coding and Referencing a Simple Lambda Expression: So in this video, we're going to go through some basics with Lambda expressions and functional interfaces. Now in the previous parts of the course we've introduced under expressions separately from functional interfaces on. The reason is because they're kind of different. Syntax is, if you will, Lambda expressions are basically methods that you can plug in. Two places where functional interpreters are expected on funnel interfaces provide the target types for that mechanism. So what we mean by Target types is that function interfaces can be either the actual types . Do you assign a lambda expression to or the types that you passed under expressions into, Method says those are the two men use cases for functional interfaces, So let's get a look at both of those now on. DWI can see them if we do some coding, and if we demonstrate them at the same time, it'll be easy to see how the how they fit together. So put things in much more of a concrete context. OK, so first up, let's start with the most simplest basic expression. You can have the most basic lander expression, so if we go into the static, avoid amend method, we could just use this for now because they don't have any instance State on this demo class that it's in, we're just show a few things we can do with under expressions and function interfaces, so we don't need it to be like a proper class. So this is perfectly fine. But in the main method, so I can create Lunder expression. Very simple. Under expression like this. Start out with some parentheses, arrow operator and then a hello world statement. So this is the most basic lander expression. We have empty parentheses at the start because it doesn't take any parameters. You recall what we have in the parentheses section of basically the input parameters and optionally parameter types to for the lambs or expression on because we don't have anything inside those parentheses. That means it doesn't take anything. This under expression doesn't take any parameters. Then we have the arrow there, which then points to the actual under expression itself, which in this case, it's just a statement which invokes the print line method on systems out to say hello. And at this point you'll see that we can't just have a lander expression stand alone, so the compilers complaining already. You can see this quickly, red line underneath. So if we hover over here, it's saying that the lander expression itself So this full expression isn't a statement on . That's because it doesn't make any sense to have a Lambda expression, which is just kind of out there. Free standing, not being passed to anything not been assigned to anything just doesn't make sense. So therefore, to make this complete into a proper statement, we need to assign it to something, so we assign it to a functional interface. Now, if we look at this under expression, as we've seen, it doesn't take any input parameters, but it doesn't return anything. So that means that we can assign it to a method which has no input parameters on returns void. As we said before, if you look at the mobile interface, we can just have a quick look Now Then you can see here this meets the bill. This is gonna be compatible. It's a functional interface. It's annotated with its functional interface annotation here, which means it's gonna only gonna have one single abstract method which it does, which is here this public abstract void run on again. The function descriptor of the wrong method matches The function is stripped off the lander expression we've got, because here we don't pass anything into the method is input parameters just like here. We don't pass anything into London expressions, input parameters and similarly, also is returning void on. We're not returning anything here either, So this means I can take this run Herbal, copy him in service reference. And I should be able to do this when I can. So this point, we have a complete statement so you can see here. Got the function interface on the left as a target time for London expression. We've got the lender expression itself, which is here on we've got this assignment to the variable, so f n so at this point, once this lines executed, this FN variable will hold a reference to that under expression. Now, because we've now typed this Lunder expression to the rentable functional interface, this means that we can then invoke the method so effin dot run. And if we do this, we'll see that the behavior which was encapsulated inside this variable which held the Lambda expression, is actually invoked in other words. It's gonna run this chunk of card here unless the entire point of Lambda Expressions were really passing around chunks of card, as we've said before. So just to prove that if I right click and do you run down my men, we should expect to see hello printed or you can see it's printed the string. Hello, So moving on. If I want to make this more advanced, I want to add some extra stuff in here, maybe another line to they don't have to put it inside curly braces and terminate with a semi column. At this point, I have the ability to provide multiple lines inside this lander expression. So, for example, here I could say string name equals mutt on Hello, That's a knife. I run again. We should see Hello. Mapping produced. So that's the way of being able to have multiple lines inside. All under expression. Now, in general, you want to have your lender expressions as concise as possible. So you really want to be leaning more towards expressions like one liners. If you like insight, lander expressions as opposed to having many different statements inside the body of a Lambda expression that's generally considered bad practice. However, it's there if you need it, so it's worth pointing that out as well. So that's a nice introduction to Lambda Expressions, syntax and how we can assign Lunder expressions to function interfaces on. In the next videos will dig a little deeper and take things to the next level.
19. 19 Refactoring a Lambda Expression by Adapting an Existing Functional Interface: Okay, so we've seen now basically under expression. So let's now look at some number expressions, which he was different functional interfaces. So if we are only passing in one parameter, then we don't have to use parentheses. We only use parentheses if either were passing multiple parameters, in which case we have those parameters comma separated like a B c de that kind of thing, or in the case where we have no parameters whatsoever. So it was have to have something there in that case, because of the ways it's not possible by the compiler. However, if we just have one parameter, which is passed, then we don't have to use the parentheses. So let's do this now. Let's pass the name into the lumber expression, so let's get rid of that and we'll get rid of those two. We just have a simple one liner under expression, and you could see at this point that doesn't work. So let's hover over and see why. It says incompatible parameter types in Lambda expression. Wrong number of parameters expected zero found one. And the reason for that is because the compiler is checking this Lunder expression here. The function descriptor of that which it knows it takes a string as an input parameter, and the reason it knows it's a string, by the way, is because of the context within which is used here. So the compiler com'on further type because working captivating strings here, however, that function descriptor, which takes a string, isn't compatible with incredible. And that's because amenable. Be looking here. It doesn't take a string. So if we could modify that and put in string, which we can cause it's his father's read only then it would fix it. So let's do something kind of similar. Let's just copy that. So we copy that writable interface talking to here. Let's call it something else. Let's go a string rentable. It's an awful name, but just the sake of demo and delete the job talk. We don't need that. So if I could be string winnable here, he would get the same eras we got before. But now he'll see if I do this on update that method in the function interface to take a string. That error has now gone on. The air has gone now because indeed, string winnable its function. Descriptor takes the strength on the under expression. Also Texas during which is here is his name. Of course. Now we've got an issue here on the issue here where it's saying run string in string, writable cannot be applied to and there's those empty parentheses. What they're saying is you can't invoke this method now without passing in something in. That's because it does indeed have to taken input parameter. We need to pass in the name. So now we for you typing Matt. Everything compiles. And that's because we're now passing in the string parameter. When we invoked the function which is held in that lumber expression on everything, much is nicely the function descriptors match method signatures match. The parameters were passing in much. Everything is good but a knife. I do control our to run. Then we get the same effect as before, so we get the same effect now. It still says, Hello, Matt, but it's just we've got it in a different way. What kind of reef acted things lightly? All reworked them rather social. We've adapted the function interface to meet the need to the lander expression. In other words, a lander expression took an input parameter, So we adapted the fungal interface to take that parameter. This also shows you, by the way, how to create a function interface. You can see here. We've got this app function interface sanitation just declares it to be a functional interface on We've got this abstract method here, So friendly interface in general only ever has one abstract method of so called single abstract method and optionally. You can pass in this function interface annotation on the interface itself. The functions face doesn't need that doesn't need that annotation. But it's just the search of the compiler can catch any errors. So, for example, if I start to add a method here like so string do greeting, then we'll get this compiler here, it says multiple, none of writing abstract methods found in the interface on what that means, basically is don't put more than one single abstract method in the Fox interface. Otherwise, it's not function interface, so given that that's all fine, so in this video we've seen how we can take an existing number expression refectory to pass in an input parameter and create or adapt existing function interface to provide a matching target type for that lander expression on. As you can see, it's not too difficult to do. And as you become more confident with function interfaces on under expressions, you'll find that it's quite easy to whether use existing function interfaces from the Java Util that function package, aka Iran function interfaces like we've seen here.
20. 20 Providing Alternative Functional Interface Target Types for a Lambda Expression: last thing I want to show you is the fact that the lander expression can actually be used with multiple function interfaces is not just bound to one specific financial interface. You can use it with multiple. So let's see that now Let's recreate what we had before. Originally. You can see we got this simple under expression. Doesn't take any input, doesn't return anything. We decided to run a ball. We know how that works Now. That's fine. If we create our own function interface. Now let's go to execute her and give it a method which has the same function. Descriptor. Let's call it executes and just for completeness. But their function in space sanitation on just a kind of double check it when we've talked to him. Now here we've created a new function interface and he has a different method. So this method is a different name. It is called execute. The one incredible is called Run. However, they've got the same function descriptor. So they don't taken input parameter or any input parameters and don't return anything. So this means, rather surprisingly, perhaps, that I could do this. Execute er he was in the one I've just created now in my package, not the movement job you two concurrent function to equals and then copy this same Lunder expression, and you can see that's completely fine as well. And this is a nice thing about Lambda. Expressions were truly just packaging up a chunk of code, and I give them the ability to pass it into whichever context it fits. So I just wanted to point out the fact that you can assign a lender expressions in many different fungal inter verses. It's not just a 11 mapping between a specific lumber expression needs to take a specific focal interface. It's not that it's a lot looser, as we've seen, and when you're exposed to this when you used to after a while, obviously a bit of a paradigm shift. But when you're exposed to that and you've taken on board mentally, then it really enables you to start thinking about cutting at a functional level, which is one of the great benefits of job as we've seen
21. 21 Refactoring a Lambda Expression with its Method Reference: So in this video, we're gonna have a look at method references on See how we can use them in action, since it could be a bit abstract at times a ceased when you first start to get your head around them. And so we just demo them here will be able to see firsthand exactly how the work. So let's kick off by looking at a simple method reference. Okay, so we've seen the consumer interface before. That's a consumer function interface that is. So if I get now Consumer Hope String, just import that, I will just say this is Greta agree to function now. We've seen before in the sectional under expressions that we can assign a lender expression to the function interface, and we know that the consumer interface except the parameter but doesn't return anything. So just double check that if we hit command and click on the consumer and check out the interface we can see down here. We've got this except method. So it, except a parameter offer given time that it's invoked with on it doesn't return anything, so if you could close it down, we could pass in a string so greeting on the body of the under expression just about print line. I should just point out the greeting itself from pit print, anything else with a semi colon to terminate. So this stage we've seen the lender expression, which could be assigned to a corresponding factual interface on. There's nothing surprising about that. We've seen that kind of thing throughout the course, so using method references, I can actually re fact to this. So instead of putting in the lender expression here, I can simply remove that and change it to this. And this is now the corresponding method reference. So the method reference that corresponds to that under expression. And by the way, if I just typed it out from scratch so system to out calling Colon, then when I put the second cold and there you can see Intelligent gives us a list of methods which are on the outs, objects inside the system class. So then it slides with, like to print line. So however you get to it, whether you type it in directly from the myth of reference indirectly, that is, or if you start with the under expression and then re factory after the fact to the corresponding method reference the effects. The same to the key part here is that we can use a method reference in place of the lander expression and then that gets assigned to the corresponding function interface. So I could then call the method with except passing in this text here. If I run that, we'll see that it's been invoked because he here hello from a method reference. So that's just a demonstration of a very simple re factoring weaken due to replace an existing lander expression with its corresponding method reference. Adjusting these kind of little re fact rings as you go along. We'll make it coat even cleaner says it could practice to get into, but it's more concise, too.
22. 22 Coding with the Consumer Functional Interface: So let's write some current now using the consumer function interface, so came back to the i. D. I can write consumer off string intelligence is suggesting I import that, which is true. That's the function in space time, the job that you told up function package or financial interfaces. Aaron that package, by the way, at least a common set, although there are other function interfaces scattered around the Jedi K like in the Venable interface we saw earlier on. So I do all center to bring the important. So now, if I go to consumer, you can see except an input parameter. So this means that my Lunder expression needs to accept a parameter on. In this case, it's gonna accept a string. So here we have an input parameter fruits, and we just do this this out print line again, which say is my favorite favorite fruits is, and then the promising this past him. So then we know we can know invoke it with. Except this was the method that's defined, rather the single abstract method that's defined on the consumer fungal interface on because we've typed it with the string type you can see above We got consumer of string because of times of the string type. We have to passing a string now, So just say pair, for example. And if we run that that you can see it says yet my favorite fruit is pair, but of a type other. We were my favorite from his pain. Okay, that's the consumer interface consumer. It takes an input parameter nice and simple to implement on a very common function interface which will use as we could.
23. 23 Coding with the Supplier Functional Interface: Now let's see how we can use a supply, a functional interface and how we can use that with a Lambda expression. So we'll recall it with a supply. A functional interface issues to return values so doesn't accept an input. But instead it returns on output instead. So they just called up a quick supplier of interview. For example, supplier. I'm an insurgent. The answer to pull the function interface supplier equals. Now here. It doesn't take anything as an input parameters. Therefore, we have to have the empty parentheses we've seen before, and now we can just return something. So because we don't have multiple statements within the Lambda, it's sufficient to just put an expression here. In other words, we don't need the return key word. However, if we had multiple statements in there, this, for example, so you see here to notice statement to make a statement within the curly braces, you need to put a return in there. Of course, now it's great out on the reason it's great hours because intelligent idea you're suggesting that you actually simplify this and make it better by replacing this whole stemming block here with an expression in other words go back to as we were before, See if I us, Control said. There we go. So now if I invoke this supplier, don't get it will return. We hover over here, we'll see it returns an integer so I can print that out just so that we can see something on the console run again and then we'll see. Value returned equals 42. That's consumer and supplier, that kind of opposites of each other. If you like one sex and in pop one returns an output. But of course, we don't have just those types of method. Indications we actually have proper functions on a function, basically, is something which takes some input and return some output. Let's look at the function function interface next, which we'll see in the next video.
24. 24 Coding with the Function Functional Interface: So now we've had a look at the consumer and supplier function interface is the next logical step is to look at the function function interface on. This actually combines taking an input on returning an output until they see that now. So back in idea, we create a function, have a string and integer, and this is gonna take a string. Let's see a person's name if we little tip here. If you hold down, command or control if you on a Windows Machine command. If your Mac on hover over the variable name, you'll see it's Tony, eventual type of its inferred. Just inferred here strength. So whenever you see a function functional interface, the first argument is always the input type on. The 2nd 1 is the output type, so now we have to return some integer. Let's mix it up a little bit on Let's invert these instead. So we say integer and string. Let's just say we're passing in somebody's age. So now we can see when we hover over, we're expecting an integer, so when somebody passes in the age, we're gonna have an expression here. Age is bigger than 21. That's so you can drive on. If it's under 21 let's say something else. So let's suppose this is some kind of law in a particular state in America where only if you're over 21 that should be the ricotta to anyone. Then you can drive. Otherwise you're not allowed to drive. So if we wanted to print out what the result is game, we could just do since about print line function and apply it pressing in, for example, 17 and we pass it in 17. We expect to see the message. Looks like you're walking a moment Pass in 32 will expect to see you can drive, see if I run now. Yeah, she looks like you're walking and you can drive. So that's the function function interface on. As you can see, it's pretty easy to code. You just have to remember the order off the type parameters on the function interface itself. 1st 1 is the input to the function on the 2nd 1 is the output from the function, but nice and simple as we've seen
25. 25 Coding with the Predicate Functional Interface: so consumers, suppliers and even functions. But now we're getting a good understanding of how these function interfaces work on the next we're gonna see which will demo now is the predicate. So I pretty cut function interface is something that takes an expression and returns a Boolean value based on my expression. So let's see this in action. Now that's a critical off. Let's make this a little bit more interesting. Let's make it a predator of a class. So if I just creates a new class in here person, um, person has a name on an age, let's say it's a pratica off person. We don't always have to pass in J T K types. We can pass in third by types or our on types as well. So here we're passing in person. So what's gonna happen here is what it is doing. This is gonna be a way of deciding if something is true or false about the person. So, for example, we could have a pedicure which is is old or particle, which is is young, for example, or his teenager or whatever. And also for this example, we want to limit credit cup will name it. Something more descriptive. So she was the example. Is retirement age okay on this is gonna take a person so person, and we're gonna say person toe age bigger than equal to, say 65. Begin, hold command down and look at the input parameters. And Lambda. You can see it's of our static class person type and you can see in the body of the lumber here what she accessing a field off of that person type. So what this is saying is if person that age is greater than or equal to 65 If that's true , then the result of invoking this will be true. If it's false, this will be false. We could create a different type of credit card in front of phone directory. So we got a telephone directory of people's names and numbers, for example. And for this particular, we wouldn't be looking at the age. Them will actually be looking at the name. So maybe for this one want to say person don't name sub string 0 to 1. So the first letter two of the case equals a For example, it's all the people whose names begin with a I'm gonna be the front of the phone directory . City name is Adam, for example, you'll be in the front of the phone directory. And if your name is Zoe with that said, you put the back of the rectory in the first case, it would return. True in the second case, it would return false. Let's just try that out. So here just quickly put in a constructive for this just so we can assign the variables easily come out here. So is in front of fun Directory test, that brand new person whose name is Adam. He's 25 untested Zoe, who's also 25. And we should see an Adam's case. It will be true on, In Zoey's case, it will be false. They were not true and false. That's also test Zoe to see, especially a Let's put these together. In fact, it's making a bit clearer, plus the so we Let's see. It is always a retirement age. Is Ari retired on? Let's see is Bernard retired? Amber is gonna be a new person, and he's 67 so that when we run, this is a retired is false. On his Bernard, retired is true so you can see that we can use not just the predicate function interface, but in fact, any function interface with other types. So either the standard JD care types or the rapid types which mirror primitives that we have so in double float of things, our own types from our own from the demand of our own applications. This is due to the fact that there are these generic function interfaces which are present in Java, that you told that function. So anyway, that was a demo about how to use the predicate function interface. And so, by now, you should be in a position we can start to explore the focal interface FBI and the different classes within it to be able to provide the right target types for your lender expressions.
26. 26 Coding a Collection of Domain Classes for Stream Processing: in this section, we're gonna look at pipelines and streams and see how we can process collections using the new job. Eight Stream, FBI For us to do this stuff, we need to have some data that we can actually work with. So in this video, we're going to cut up some simple domain classes that we can throw in a collection so that we can process them using the Stream FBI in the next video. So let's do this now. So first off, let's create a collection class, which holds some data which might be kind of interesting for the purposes of this demo. So that's the class. Have a student with a rounded percentage. The student has a name. Let's say they belong to a particular class on that class is preparing them for a particular exam. So we'll just say it's a reference to exam now. It's also creating exam class, and these some clashes has a name, and that's enough for now. Let's give it a constructor on. Let's get this one a constricted to So I got a very simple demand model we can work with. We've got a student who has a particular name studying for a particular exam and restoring the rounded percentage results. In other words, a number between zero and 100 for what they got on that exam. There are other ways of modeling this, of course, and we certainly wouldn't have these ecstatic classes. But the purpose of this Demmer, that's fine. We just had a couple of static classes here which we can work with. So if we got to the men method, let's suppose we have a list returned back to us from some A p I, which is at least, But his list of students are you thinking about it now? It's really student results, isn't it? So just go down here, which has modified this slightly shift up. Six student college student exam results only just called this results to make it a bit simpler. Okay, linguist, Just imagine this return from so my p I Now we're using a list here with the actual results that is ordered or no, we don't really care about. We're gonna put them in any order so semantically it's a set. But we're using this tear because, for example, when we interact with Jenny BC, we usually get back a list, and the reason for that is because the list come in 10 and order if the results that coming back happens have in order. For example, if you had a sequel statement which have an order by anyway, let's put some students in here. Results that hand Houston exam results. This one got 56. Now we need to pass an exam as well. So let's just go up here. Let's just create a couple of exams. It's good practice, actually, just to comment this out while we do that. So exams se Java certification. Let's see Nathan 101 That's probably not for now, Whatever. Whatever it happens to be, that's okay. So you got to exams? Job certification exam on the Navan 101 So now we can go back to here and say from heaven 101 He got 56 Didn't do so well. Day, but 72 on the Java certification? No, let's just give a mix of a few others as well. A few of the students. So let's just say on a bill. I also got the same result in job acidification. The coincidence Gareth will change here, too, Michael 12. Or maybe went a one. But on his job, a certification he got 88 will throw another as well. Why not one of the one Apache essentials? Still this one. So we've got a reasonable set off data we can work with. Let's just put a two string on these that we can see what's happening if we print the mountain to string. That's fine on a two string on the exam as well, just to keep things tidy so we can see what's going on. Let's extract this out. Re Fekter extract to another method. Get student results. Andi, if we hover over here, they just make it return The list results is that avoid and then returned? Those results means it. Now they have this all student results. Just call it results. Probably keep it simple. Let's just print them out So we know what we're working with and run this man method there . We can see at the bottom we have some data which we can actually work with. And if I put a break point here and just debug it instead, it might be nicer to look in the debug view we can see here. We've got the results. Linguist object with six inside on in here, we have all of the results which were working with Okay. However, if we're putting these demand objects inside collections on, if you want to test any equality, those kinds of things are compared them with each other. Then we should implement equals and hash code as well. So just go to here equals and hash code. Next. Next, let's do the same thing to yeah, it's not gonna equals in hash code, which means that these demand objection. Now behaviors are supposed to behavior because we expect inside the collection classes. OK, so now we've got these demand objects counted up and placed into a collection. They see how we can process them with the streams. FBI, which will do in the next video
27. 27 Coding with the Streams API to Process a Complex Collection: So we saw in the last video that we built up a collection of some simple demand objects. So in this video, let's look at how it can process that collection using the streams FBI. So let's think about what we might like to do with these results. I don't want to find out all of the people who got more than 70% because they can go through to the next course. So to do that results is a list on the least weaken goal stream you could see here we get back a stream of student exam YSL, which means that now if we look inside stream, it returns this stream method command of 12. At this point, we have all of these methods which we can call to process the streaming somewhere all much any match count distinct. Find any fine first for each map, those kinds of things. So if we want to get the students who got over 70% then already to do is to filter and we're gonna pass in a predicated on the predicate you'll see needs to take a type of student exam results or one of its sub classes. We don't have any surplus. It's here so soon exam. It'll it's fine. And the predicate is gonna return a Boolean. Somebody's going to the filter method just that we're on the same page. We can see him when we filter. It's taking in this pretty cup on the project has this function here test which takes a single parameter, and he can evaluate whatever you want to evaluate on that parameter. So he will be evaluating the rounded percentage inside a student exam. Result on it returns a 1,000,000,000 which is gonna be true or false. So let's right the predicate for this. Let's just same result. And now when we have this result, we can access methods are properties, right? So he will say around it percentage and we're gonna filter where the rounded percentage it's greater than or equal to 70. So we go to filter again, holding down command, hovering over the filter method. Here we can see the stream chaining in action. So we've called Filter, which isn't intermediate operation on because of this is returning back of stream of the reason for that as we've seen before you so that we can keep going and we can carry on doing other processing if we need to. So let's just do that. Let's find the names of people who go over 70. So to do this we can do a dot map, which is another intermediate operation on Now. When we do, a map will see its accepting function, which accepts the student exam, Russell and some of the type this question mark extends our on its doing nights capturing that because it's going to turn then a stream of our So, for example, if we return the name that it's gonna be a string so that it would return back a stream of string, and from then on you can only access anything applicable to a stream bounty to the string type, as we'll see. So this might look kind of complex now. I think it was getting a bit complex inside the map method. We've got this function question mark Super student exam. Russell Question. Mark extends Our stream are, but don't forget that's just a functional interface on the function interface. Don't faze you at all. It's all you have to do is personal under expression, which matches that functional interface. So to break it down a function we said or other function function interface has two parameters to that. The first is the input parameter. That's what we're passing in to the function to the lumber expression in this case and the second parameters. What we're passing back from that function from that landler expression so we need to do now is pass in this map a function on the map, a function you'll see here, Function, function, interface. You recall the function has two arguments to it. The first thing is the input to the function, which in this case is a student examines all on the second argument is the result from that function. So the output of the function This means we can write a lender expression like this. That's a raise for results. And we're gonna return back rays don't name. Obviously, here I'm accessing field directly. It's a demo class can access the fields on the static in the classes, but similarly is well, you can also go by the actual method instead. So, for example, if I happen to add, get someone here for the name. But I could also do not get name like that at this point is getting a bit unwieldy. It's a large, long line. So what I liked to do his results topped stream on the unbelief there, half the individual invocations against the stream object. So don't feel too here. Don't map here and now we're gonna use a collector. We're gonna use the 2nd 1 which knows how to assemble this into a set. It's a sign that to assess as well. So now we're and have a set of string. Pam will be able to print that out. Let's do for each, which now takes a consumer consuming, you'll recall just to function, which takes a parameter, and we can use system out front line as a method reference. So if we run that now, it's quite a lot of code. I appreciate that. Glad that you bearing with us to be able to get through it. If I hit run, you could see top students are Gareth and Annabelle. My last thing as well. Speaking of method references is that we can now go up to here on. This is a London expression, but I can't replace this with a method reference now to the student exam results. So here we go. Student exam result. Common colon getting them and we run and we have the same effect. I'm finally what we can do, if only to order that, um, we can just do assaulted on here on. Then sorted, you'll see prices back upstream again because it's an intermediate operation, so it's not a Terminal one. So then we still need to have this collect. But this time, instead of it being collectors to set which intelligent ideas automatically put in for us. And then it's saying why using sorted Because it's set it doesn't depend on the salt water . So there's no point which is true but intelligent idea in natural fight jump the gun there . If we put a list in there instead, which does respect order, then we could just do to list and now we should find The top students are listed in alphabetical order. So, in other words, Annabelle should come before Gareth, which is true. That said, the Gareth came top in a few of the things that you actually have a few repetitions of Gareth now which maybe we don't want to have happen so we can also plug in another one here , which is the dot distinct on this will trim out any duplicates. So now we control our you can see the top students are animal and Gareth, so that's a good introduction to how you can use pipelines and streams. Don't forget. Whenever using this kind of stuff, refer back to the Java doc. Don't be afraid to click into the individual stream methods the intermediate or terminal operations and also to use Intel, Ajay or eclipses type on reflection recommendations to be able to figure out what to do and gets a nice, clean, concise, functional code. And that's how you process collections were. The streams appear.
28. 28 Coding with Bound and Unbound Instance Method References: So in these next few videos we're going to go through and have a look at method references in more detail on Compare the different types, which we have on the first type of method references that we're gonna look at our instance . Method references. So let's start off by looking at the method reference that we came to when we look to re factoring a lander expression into its corresponding method reference. Let's just think about what type of method reference this is for a second. You remember. We have different types of static method references, bound and unbound. Instance, method references and constructed by the references thinking about what type it is. Let's just break it down here. So a system that out, if we're just going to hear, we'll see you systems out. What actually represents is a static print stream on the system class because what it really is, it's a print stream on the system quests. However, if we click into print line, this isn't static, so that is actually an instance method on its an instance method on the print stream itself . You can see here print stream, so close those two again so This is kind of the same if we had just a variable here, which would bind in the instance method, too, in the form of a method reference. So this doesn't represent the static method invocation, but actually represents an instance. Method invocation. However, because we're actually passing the actual instance, it will be invoked against which is this print stream reference by out in the system class . This is there for abound. Instance method reference because we're binding the instance that we want the method to be invoked against inside the method reference itself. So don't be too confused or foxed by the fact that what happens to be a static variable in the system class that might seem a little confusing. Just ignore that. Pretend it's not there. Obviously it is the otherwise it won't compile what Pretend it's not there and just focus on this part to determine the actual type off the method reference. So it's abound, instance method reference, Which is why, when we run it, it already has a proper prints dream to go to, which is what can print the string that we passing when we invoked the except method. Now that's a bound instance. Method reference. As we said, it's on Prince Stream. So here again, click out. We see it's a print stream. I never click. Interpreted Stream Command of 12. We can see we have these print line methods on These aren't static. There's no s here. These are just instance methods on the print stream object. So cancel both of those. So what? We could do them. His reference to print stream directly. Colin Colin Print line. Now, in spite of the fact that this looks like we're somehow invoking print line, statically were no, it's just allowing us to select an instance method actually, any method, in fact, from a particular class. So this is just saying Select the Method print line from the Prince Dream Class. Now the compiler knows internally that that's not a static method. It's an instance. Method on intelligent idea knows it's a swell. So if we leapt to the front of this, we'll see we have this little help her, which would allow us to make it into a proper statement or, by the way, is what The reason this is, ready it saying it is not a statement because we haven't assigned it room. But we can't have Lambda expressions, which is just out there, not being assigned or passed to anything return from anything and simply as well. The exact same rules apply to method references, just not a statement of the minute. But you can always do, even if that little exclamation mark thing goes away is his ultimate enter. And then you get these so called quick fixes, which you can employ. So it's interesting now to look at what happens when we want to introduce a local variable . So this is a little quick fix of intelligent will give us to be able to assign that method reference to a variable of the corresponding type. And this is actually quite a nice little power tip for you that if you're ever unsure of what the type might be, you could just go to this quick fix on your selected, and it comes up with a few compatible functional interfaces, which matched the function. Descriptor off that method reference, with the first most one being the preferable one, the one that's most compatible on in this case. It's a by consumer, so it's suggesting a print stream and a char array. If we click into print line, copy that. 12. Let you see the riff You here so you can see there's a print line which doesn't take anything. They're putting lines which take various various primitives on the one that we're one about . Here is a print line, which takes the string. That's the one that we've already used, so we'll just stick to that. Will stick to print line of string. See if I escape off that Kimanzi to get it back. No going the wrong way That's better so I could just go down here now take up The Ciara rakers have no intention of passing in a char Ray can instead put string and give it may be a better name. Rita function to Isabella. Maybe at least it separates it from the original one. Now then, this is interesting. So by consumer. So what does that do them? Well, just like a consumer ticks one in poor argument except a single argument by consumer, you probably guessed, can accept to arguments. And the reason we need to make it except to arguments, is because the first argument is actually the Prince Stream. We're gonna invoke it against. And the reason we need to pass the Prince Stream is because when we've constructed this method reference here, we haven't said which instance it's going to go against. And so therefore, the type of this instance method reference in this case is not bound. Instance method reference like above button unbound instance. Method reference. So this means that when we call greets a function to, except we now have two arguments. You'll see where we need to supply as the first argument. The prince dream it will be invoked against I'm looking just reference system to out is that it's public and it's static, so it's accessible to us. It's available off of the system class on another string. I'm gonna bound instance method reference on this one just to make it clear, you know, from abound, method reference and that we do control our to run. We can see that it's involved correctly. It says I'm an unbound instance method reference. So that was it. Nice and easy. As you can see, the difference between bound and unbound method references isn't that difficult to understand. Once you just realized that the bound method reference takes an implicit parameter, which is the instance that it's invoked on anyway, so that should give you a good understanding off instance method references, which you can now use in your job. Eight. Cutting.
29. 29 Coding with Static Method References: So now we're familiar with instance method references, which we've seen in the last video. Let's turn our attention to its static method references. So to create a static method reference, let's think about some static methods, which are probably quite familiar to us. Thread dark current threat. Okay, so that returns basically the current thread in operation. So this is a static method on the thread class, and so we should be able to construct a static method reference out of it, and we can do just by replacing dot with a double column removing theme parentheses. But again, it's not a statement. We'll see. So we need to assign. It was before we give a consumer which accepted one or more parameters. The corresponding function interface for this is a supplier which is going to return a value instead of accepting values. So it's a supplier off thread hold answer to import that. Now we know it's a supplier of thread because if we command and hover over this method so it turned into a hyperlink, we can see the quick info here. It's saying that current threat returns a thread object, and again I could invoke it so we mazel printed out so we can see what the value is. So says out print line, Fred function don't get and they should give us quick We're to access What? The current Freddie's control I now I should say the men thread you can see here it's given us a reference to the main threat. So that's a static Met the reference. Just put these in just to make it kind of explicit what we're doing here. This was bound instance method reference. This waas unbalances met the reference, starting with the reference. So therefore blast we're gonna have is a constrictor method reference and we're gonna see construct him at the references in action in the next video.
30. 30 Coding with Constructor Method References: in this video, we're going to look at constructive method references, So let's pick up from where we left off before. But we're looking ecstatic references. So for constructing method references again, this is a supplier because we're returning an instance off the class and returning a new object. So it's really a way off its declaring a factory method. If you like to manufacture instances of the class and for this, we just have to give a reference to the new key would after the double calm. And in doing that, the actual default constructor, or rather than no argument constructor could be encapsulated in that method reference. So, for example, we could have a supplier, Calenda, and I saw him that construct about the reference to create a new Gregorian calendar. So then, when I am folk that you can see here, it's the return the Gregorian calendar in terms of its calendar super type. That's the interface type recording calendar extends. So I do to get there, count. No, If I run If I printed as well. No. If I run, you can see here. We've got back an instance of a Korean calendar, So notice here as well. And this is the reason why we chose this example that when you're using the method reference, we can also assign it to a function interface of a compatible type on the compatibility. Here is the fact that Gregorian calendar extends calendar, so if we look inside Gregorian calendar, we can see it extends calendar here, so that should be a nice introduction to method references, and you should be able to use them in your own applications now.
31. 31 Well Done and Thanks: Well, that's the end of the course on I just want to say how well used them to make it to the end . There's a lot of tricky concepts in Javari, as you've seen, but through perseverance and hard work you've got there in the end, Well done. That's really great stuff when you should be proud, you know, in a position to be able to take it further and delve deeper with the knowledge you've got . So have fun doing that. And don't forget, you can always reach out to me from any questions. All that remains essays. Have fun with it all. Enjoy applying a newfound knowledge and have a great day ahead.