Professional Java Part 2 - Mechanics | Kenneth DeLong | Skillshare

Playback Speed


  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x

Professional Java Part 2 - Mechanics

teacher avatar Kenneth DeLong, Java and Groovy Programmer

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

12 Lessons (5h 34m)
    • 1. 01 Introduction

      3:48
    • 2. 02 Packages

      24:35
    • 3. 03 Object

      25:22
    • 4. 04 Statics

      38:20
    • 5. 05 Collections

      42:17
    • 6. 06 Exceptions

      37:39
    • 7. 07 Enums

      19:38
    • 8. 08 JavaLang

      30:07
    • 9. 09 JavaUtil

      15:55
    • 10. 10 JavaTime

      30:34
    • 11. 11 IO

      61:57
    • 12. 12 Conclusion

      4:00
  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels
  • Beg/Int level
  • Int/Adv level

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

21

Students

--

Projects

About This Class

In this second part of the three-part series, we move beyond Java's object-oriented features to examine some of the mechanics of the language. We examine core parts of Java like packages, the classpath, and enums, as well as the basic packages like java.lang, java.util, and java.time. We dive deeper into the Collections framework, review static methods and attributes, and how exceptions are used for error handling in Java. We wrap up with a deep dive into input and output with java.nio and java.io.

Meet Your Teacher

Teacher Profile Image

Kenneth DeLong

Java and Groovy Programmer

Teacher

Class Ratings

Expectations Met?
  • Exceeded!
    0%
  • Yes
    0%
  • Somewhat
    0%
  • Not really
    0%
Reviews Archive

In October 2018, we updated our review system to improve the way we collect feedback. Below are the reviews written before that update.

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. 01 Introduction: Okay, welcome to part two of the professional job. Of course, this chapter is overview of what we're going to be covering. The objectives of the professional job, of course, are to take someone who's know something about programming. But they're kind of a newbie to the job environment and try to give them all the tools that they need to function in a professional programming environment. So, in other words, that means there's a lot to cover for myself. My name is Kendall Long. I've been programming in Java since about 1997. My day job is still using Job A and groovy, which is kind of, ah, job a derivative to build back end services for my company. So I've been around this job ecosystem for for quite a while. Let's take a look at where we are in our professional job class, so it remember it's divided into three parts. This is part two in Part one. We talked about sort of a basic introduction to Java and also about the object oriented features of the language, objects, classes, polymorphism, etcetera. Java is an object during in language, so you do need to understand that stuff to be proficient at it. In Part two, we're going to cover a bunch of the other core language features that are there, but they're not necessarily object oriented per se. But they are very important things to understand about Java and also will cover some of the core libraries that Java ships with. So when you install Java, it comes with probably tens of thousands of library files that come with it to allow you to do things like, uh, input output, multi threading date and time collections, all these kind of things. And we'll look at some of the more important ones. We obviously won't have the time to look at them all. That would take half a lifetime to go through all that. And then in part, three of the class will go into some of the more modern features some of the things that are more inspired by functional programming like Streams and Lambda as. And we'll look at some of the recent additions to the job ecosystem like the module system and annotations and other sorts of meta programming constructs like that. So again, the objective for this particular part is really to review the core features of the language that we haven't talked about yet. And to look at some of the most important libraries that we're gonna be, uh, dealing with in job and still more specifically, we're going to talk about packages and class path, which we didn't really talk about in part one. Samora about collections we did do. We did work with the Rays in lists in part one, but we're going to get a little deeper into collections here. We're gonna be looking at static methods, and attributes will be looking at job exceptions and exception handling. And then we'll go into some of the libraries. Like the time and date libraries. Thean put output libraries, the logging subsystem that comes with Java, some of the capabilities around multi threading and some more things on top of that as well for the class project. For those of you who went through Part one, you know that we build a board game simulation that we built up step by step during that part, and that will be our starting point for part two. Now, if you didn't go through part one, don't worry. I'll bring the ah, the finished version of the project from Part one in as the starting point for Part two. Now, not all of the code really fits nicely into the project that we have into the game simulation project. So we will probably in this course be writing some ad hoc could to demonstrate some of the other library features and things like that that don't really fit into the project. Okay, with that said, I think we're ready to get on and start looking at the next chapter, which is all about packages and the Java class math. 2. 02 Packages: Okay, welcome to Chapter two all about Java packages. So when this chapter we're gonna talk about the physical layout of Java code and how that intersects with Java packages will talk about package and import statements will look at how packages give you another level of security and access control. And then, of course, we'll talk about the infamous job A class path. So if we're making a small project, 10 dozen files, it's fine to put it all into one directory. But what if you had 1000 or 10,000 files in your project? You'd like to arrange it somehow so that files would be easier to find than just having them all glom together in one giant directory and in job. But this is kind of the, uh, the idea behind the idea of packages. So here's a screenshot from the file system of one of my open source projects that I have on get Hub. So at the top, very top life do you can see a directory called Java. That's the, uh, the top level source code root folder. So all my source could let's underneath that Java folder, and then you see a series of folders underneath that calm can belong you till etcetera and the actual source code lives for the most part in those lower directories. So, for example, http is where all the files that deal with HDP stuff are located. So in Java, this becomes the first class construct in the coat. So look at the first line of the source code on the right hand side, which is Ah, shot snapshot of one of the files in that particular package. You see, this statement says package com dot canned along that you tell that htp and that is actually the physical location of the file underneath the job. A folder, right, Calm canned along. Util http. So the package statement and the physical location of the file on the folder match each other. And that's the first part we have to understand about packages. So every class file has to have as its first line of code a package statement that denotes what packed that declares what package it's living in. So it has to be the first line of non comment line of code. You can always book comments above it, but you can't have any other job. A compiler recognized code above the package statement has to be the first active line in the file, and it describes it, the compiler like what this sub directory path is to find that class file and in the package statement used dots to denote the different levels of subdirectories. Now in Java, class names have to be unique, but only within a package. So that means classes in different packages can have the same name. So in this sense, besides declaring where the packages live on the folder packages also provide a name space for Java classes. So if you have a class called Dog in one folder one package and the class named Dog and Little Package, that's okay. They don't clash with you with each other. Here's a real world example for you. So there are these two classes. They're both called http response on one of them lives in the package or doubt Apache. That http and that's a project from the Apache Foundation. And another one lives in a package called Combat Amazon need to be asked at http. And that, of course, is part of Amazon's STK for accessing their Amazon Web services offering. So both of these classes have the name of http response. But they don't get mixed up with each other because to the job of run time system, the name of the class is actually in the top. Case calmed at Apache that HDP dot HDP response. And in the bottom case, it's comment. Amazon invested HDP that HDB response. So those are two different http response classes and to the Java runtime. The name of the class is actually the package plus the class name, and that's called the fully qualified class name of the class. So usually as human beings, we just want to deal with this simple name like HDP response. We don't like to type out this big, long calm that Apache HTTP at htv response. But internally to the Java runtime, that's what it thinks about the fully qualified class name. Okay, so fully qualified Class name is the name the package name plus the class name, all separated by dots. That's kind of the official name of the class that the formal name of the class and within a Java virtual machine that has to be unique. You can't have two versions of the same class. That is the unique name of the class. No. So we see that packages are a way to physically organize our code and to logically name space, our code. But it's also a way to a group and isolate coat from each other. So let's see what that looks like. So here we have two packages on the left. We have a package called fish with a class called trout in it, and on the right, we have a different package that's called mammal, and there's a class called Cat, and the cat would like to have the trout for dinner. But if you just say private trout dinner, the compiler will break here and say, I don't know what you mean by trout. There is no such class as trout because the trout classes in a different package. So what you need to do in order to use the the class name trout in your code, you have to say import and then put the fully qualified class name their fish dot trout, and that makes that class of visible to the code in that class. Now, if you've ever programmed in the language like C When you do an import statement, it actually physically imports all the code into your file. When you compile, that's not what's happening here. All that happens in Job is your declaring that in this source code, you're going to be using the class called fished trout. And basically you're just telling the compiler, Hey, if I say private trout dinner, the trout I'm referring to has the fully qualified class name of fish dot trout. And based on that, now that the runtime has the fully qualified class name, it can go and search out that class file. Now. One thing to note here, when Cat needs to use trout, it has to import the trout class from because it's in a different package called fish. But you don't need to import classes that airing your own package. So by default you can see your own class. The class is in your own package. So, for example, in the mammal package, if there was another class called Dog, you could have a another attribute in the cat class called Private Dog Enemy or something like that. Then you wouldn't need to do any imports for that. Now, suppose your fish package is teeming with fish like carp and trout and perch and bring, and you want to use them all. But you don't really want to write four import statements. It's starting to get a little bit boring. You can just say import fish dot star. And what that does is make every class from the fish package visible to your cat class. So then you don't have to bring them in one by one, and you do get some imports. Be free for free. Besides your current package, which is always important for free, there's another package, which is called job a dot lang, which has the core implementation of Java in it and thats imported into every class for free. You never have to write import job without lying that star or anything like that, and we've been utilizing this fact already. The class string is actually java dot laying that string, and we've been using strings all over the place. It's one of the workhorses of Java, and you don't need to import strength, okay, because it's in the job. A doubt line class. So you get that one for free and thank goodness or else we'd have so many import statements , we wouldn't be able to manage them. Okay, now you might have been thinking Wait a minute with this star import. What if I import the same? Have to two different classes with the same name. So here's a real life example for you in the package java dot You till there's a class named list in the package job of that A to B. T. There's a class name list. If you have these two imports where you import Java Util star in Java LGBT star into your class and then you try to declare an attribute like private list things. Well, that's bad news. The compiler is going to say I don't know what you mean by lest because you've imported two different lists and you haven't given me any clue to figure out which one you're talking about. So in this case, there's really ill. If you want to maintain your import statements of where they are, you have only one choice, and that is to use the fully qualified class name as the type of your variable. And that way the compiler knows. Ah, you mean job that you told dot list. OK, that's fine. In fact, if you hate import statements, you wouldn't need to use them at all. You could type out the fully qualified class name for every single type that you have in your code instead of string you could. Well, string is important for free, but instead of list, you could say Job that you told that list everywhere you use list. But that's really unwieldy and hard to read. So generally everyone uses import statements unless they absolutely have to use the fully qualified class. Name. All right. Another thing you might be wondering about is what's the relationship between the package and a sub package? So here we have my stuff, and then we have my Steph dot utilities. So we know that on the disc physically, the utilities subdirectory is a subdirectory of my stuff. But does that confer it? Any special relationship or privileges toothy my stuff package, and the answer is no. There's no relationship their job, but she eats those as two separate packages. And in particular, if you import my Steph dot star, you do not import my stuff, that utilities, so you have to import that separately. all right. There's no special relationship between these two packages. It's merely for your convenience of ah, if it makes sense to make it a seven package or a subdirectory on the disk, then you can do that. But from jobs point of view, it doesn't matter. Okay, packages. Besides the name spacing and the physical organization that we've seen so far, they also offer you another level of access control. So here's a class in package my stuff called some class, and it's got two attributes ones a public, a variable named name, and the other one is variable Anat Tribute called age. But it has no access level modifiers, not public. It's not private, it's not protected. It's just sitting there into age. So what does that mean? Well, that's called package level access. So what that means is that if there's a different class in the same package, you can access that attributes. So first of all, we can see that we can create an instance of some class in a different class without an import statement because we're in the same package package my stuff right? So remember we don't need to import classes that are in the same package is us and because we're in the same package, weaken directly, access the age attributes from a some class object, right? Because it's even though it's we can access name because it's declared public. But we can access age because we're in the same package. If you were in a different package, here's yet another class that's in a different package called your stuff. Well, first of all, we have to import my stepped out some class in order to use it. Then we could write the same code. But when we tried to do s dot age, that would break in. The compiler would tell you Hey, you don't have access to that code, okay? That's only for classes in the same package. Okay. And the same thing goes for classes. So normally, we've been writing our classes like public class some class. Well, if you don't want, you know, code that lives outside of your package to see the class that you're writing to be able to manipulate it and create instances of it, then you can just leave off the public modifier. And now that class is only visible to other classes inside the same package. This was intended as a way for people who are writing, you know, redistributed libraries and things like that to kind of hide their internal implementations . It turns out that this mechanism really isn't that convenient for doing that. And so in job and nine, they introduced something called The Job a Module system. We'll talk about that in part three of the class. Okay, so now we've seen that packages tell us how to navigate to our class. So if there's a class in the package, calm down my stuff, then the Java runtime knows that it needs to look in a subdirectory called com slash my stuff to find that class file. But a subdirectory of what? A subdirectory from where? Where do I start looking? What's the root? So when the job of runtime goes searching for classes, the place is the place or places that it starts is known as the class path route. Okay, let's talk about the job a class path. So the class path route can either be a directory on your file system or it could be a jar file or a zip file, so you're probably familiar with Zip files. It's an archiving utility where you can take a bunch of files and zip them up into a single archive, and they live inside that compressed archive. A jar file is exactly the same thing. The only difference between a jar file and a ZIP file is that a jar file has to have Ah, one extra directory of meta data directory with a file in there. That's kind of a metadata file about the contents. But, uh, jar files in Zip files can both be class path routes. Where. The jbm concert for classes. From now, when you execute a Java program and that includes the Java compiler or the Java virtual machine runtime, you can pass it until, as as an argument and give it multiple class path routes to start searching on. So if you have code scattered all over your hard drive or using a lot of jar files that you downloaded from the Internet, you can pass all of those to the execution of your program and say, Hey, I'm using classes from all of these. Search when you're looking for ah class, these air, all your search start points. So, for example, for command line code. We have jobs. See the compiler at the top and Java the jbm command line at the bottom. And for both of these they have an attribute called Dash C P, which is class path. And for both of these, the class path we're giving it is the current directory, which is dot and then semi Colon is a separator. And then helpers dot jar is presumably some other jar file full of classes that we'd like to use when we compile and run our code. Now, this could get a little complicated and in the early days of job, But this was a big stumbling block for people because it was just difficult to keep ah, track of where the class path routes were and, you know, make sure they were all set up correctly. Um, when I used to teach Java back, saying the year 2000 we would actually do a whole chapter just on class path and have an exercise on it so people could get used to it. But nowadays, with ideas like intel, Ajay and Eclipse, they abstract that away for you, and they take care of it. So you really can do a lot of work without thinking about your class path anymore. Um, it is good to know that it's there as a as a professional programmer, you should know about the class path and how it works in that it exists. But again, you're going to be working in an I D. And they're going to take care of it for you. All right, Another thing you might have been wondering about. What if I don't put a package statement? Because for those of you who did part one of this course, we didn't write any package statements. What does that mean? So if you don't have a package statement at the top of your class, file your classes, then in the default package Now the use of the default packages discouraged. And in fact, when we started our project, I'm pretty sure Eclipse threw up some warning, saying the use of the default packages discouraged and it gave you some more encouragement to do something different. Um, but why is it discouraged? While number one those classes can't be imported into other packages. So once you start putting classes into the default package, they kind of live in their own separate universe that they're not useful to anybody else. So that's not good. And really, it's only suitable for, like, quick and dirty demonstrations, test code, etcetera. You know, um, a proof of concept or something like that for very small projects. You can go ahead and throw some things into the into the default package. But it's not something that certainly if you're gonna redistribute code and you put it in the default package, no one could actually imported. They couldn't use it, so that would be kind of a disaster. Okay, so that is the scoop on packages. We're going to go into our project now, and we're gonna move our code into packages. We've been using the default package so far as I just noted, and that's not good. So at this point, what you can do is pause the video, pull up your instructions for this, uh, exercise, and go ahead and start working on the exercise. When you're done, you can start the video again, and I will do the exercise with you on the project, and then we'll just summarize and set up the next chapter. Okay, so go ahead. and pause your video and do that exercise now. Okay, Well, hopefully that was pretty easy, because I think that was the easiest, uh, exercise we have. So the motivation just talks about how we put everything into the into the default project . And now we're going to actually create a project called Game to put the our game into. And just to get a little bit of practice with sub, uh, packages, we noticed that we have a lot of classes that surround the concept of carts. We actually chose to make the card a fairly complex concept. Remember, with the reverse cards in the forward cards and things like that, there's an interface, and there's an abstract class. So we're gonna move all of that into a sub package called game dot card and the instructions air right here. But this is easy enough to do Whoops. Sorry about that. So in there are project here the sorry game project. I'm gonna put my mouse on the source package, and I'm going to say new package. I'm gonna say game. Okay, So notice how eclipse gives you this little icon, which looks like it wrapped up package right very cute. And now what I'm gonna do is I'm just gonna Oops what I'm doing here. I'm going to, uh, shift, select everything, and I'm going to drag it down into the game package. And Eclipse is gonna chew on that for a while, and it's gonna go boom. And so now, see, the default package has gone away now, Bye bye. By default, Eclipse won't show you the default package because you're not supposed to have code in that anyway, So if you look through your classes, you'll see that the package game was added to the top, right, which is kind of nice. It added it to the top of each file. All right, so this is one of the advantages of using a i d. E over just a text editor eclipse. And until a j, they both understand the concepts of packages. And when you move things from one package to another, it will alter alter the package statement for you so that you don't have to keep track of that because it understands what a packages it knows that it's not just another seven directory, Okay? And then the second part of that was to move the cards into a new sub packets so I can put it here and say, Game uh, car. Oops about that game dot A little trouble typing game dot card. Okay, and then let's see. What do we want to move there while the reverse card go ahead and do that. Let me controls that. The abstract hard the card interface, the forward card go ahead again. So eclipses offering to look through all your other files and saying, Hey, let me check If there's somebody who is using, say, the card interface, I'll update their import statements. So let's take a look a card Now it says package game dot card. OK, notice that we're using the piece here in this interface, so you have to import gamed out peace just because we're in a sub package. Remember, that doesn't mean that we can see the classes in the in the parent package. We don't have any special visibility that they need to be imported, right? If I look at, uh, player, notice that it's important for us game dot card dot card. So when I say card here, it knows that that's nce Eclipse even highlights of where you knows that. That's the card I'm talking about. Okay, now there's an argument to be made here whether the deck should go into the card package as well, because the deck is the manager of cards. Uh, either way, it's not gonna make a big difference to our project. I don't think Let's make sure that we can still run our project now. So run job application. And yet let's take a look. Looks like it's still working. We don't need to examine the output closely, but that shows us that we didn't break anything. So the big lesson here is that you can see the packages in eclipse, and there are different views you can use to to show it. I like this flattened view of the packages like this. You can fold them and unfold them. And if you if you just drag and drop classes from one package to another, Eclipse will manage all the import statements not only in the class that you're dragging but also the classes that refer to the one you're dragging right, Like when we drag card down into the game dot card class, it changed the import statement for us in the player class, right? Which is not. We weren't manipulating that class at the time, but it found it and changed it. So naturally, that's really helpful. So that's really all there is for for this exercise. Just putting things into the packages and making sure they still work. Let's go back to our slides here and let's just summarise up. So in this chapter, we learned that packages are a way of physically and logically grouping source files in Java. It's also a way of giving them a name space so that if I write some code with the class cult list and you write some code with the class called list, we don't collide with each other. If if we ever end up quite up combining our code into a single project in order to use classes from other packages, they need to be imported. There is such a thing as the default package, where you don't use package statements, but that's strongly discouraged. It's very limited in its capabilities, and the packages air always discovered off the route of the job a class path, so the class path is where Java programs go look for classes. All right, that pretty much summarises up our work on classes and important state. I'm sorry. Packages and import statements. In the next chapter, we're gonna talk about the class named Jabba Lying object. We'll see then. 3. 03 Object: Okay, welcome back to Chapter three, where we're going to talk about the class java dot lang dot object. So jumbling Object is the ancestor class for all classes, and as such, it provides a bunch methods that are accessible from any class that you write in any of your projects. So it's important to know what these methods are. So let's go take a look. All right, You might think that your class that you just wrote has no super class, but think again. So, for example, here's a class book that's just written public class book, and then the body of the class. There's no extends keyword there. It doesn't say public class book extends library resource or something like that. And so you may look at that and say, Huh? There's no super class to book, but that's not actually true. What it looks like to the compiler is like this. So the compiler role extend book from the object class. If you don't have any extension, keep word. If you don't have any extends keyword. Any explicit super class in your class so you can't write a class that does not extend object okay, and one of the up shots of that is that you can use the type reference object for any kind of class. So here we have uptick day equals new object. Okay, of course, that works. But you can say object. B equals new book Object C equals new player Any class that you can instead she ate can be held in a reference of type object. Okay, not that useful, but it's an interesting point. There is one exception. The primitive types that we talked about back in part one. So, like a little lower case Boolean into long float double, etcetera. There's there's a few more of them those air, not objects. And in fact, Java has been criticized a lot because it's not a pure object origin language. We have these funny things like EMTs that are not objects that air inside of our object oriented language. But that's a design decision made a long time ago. That ship has sailed, and this is what we had to deal with. Okay, there are a handful of methods on the class object. These are the ones that are going to be most important to you in your day to day program in life, so probably by far and away. The most important one is three to string method. This turns your object into a string, or, in other words, it creates a string representation generally that's supposed to be suitable for printing out into your logs or as a debug tool or something like that. It's nice that every object can be printed, So if you're logging something or debugging something, you can always get some sort of the character based representation to look at. Okay, the class objects. So this is It starts to get a little bit mind bending the first time you go through it because we're talking about the object class, and now we're talking about the class object, right? So in Java there is a class called object, and there's a class called Class, and the object, which is the subject of this chapter, is the super class of all the objects you will ever create. Whereas the class is kind of a metadata metadata representation of any class you might author, we'll talk about it a little bit more detail later. On Clone is a method that was created to create copies of objects the equals and hash code are methods that are used to deal with the equality of objects. And what will go into all these methods in a little more detail on the slides here and then notify Notify all on weight that has to do with multi threading. Those are some of the original primitive, multi threading messages that were put in our methods that were put into Java. Don't use those, please. Okay to string. So here's a class ah player class that has one attributes the color. And then there's a two string method. You see that we've overridden the method from object. Then we're returning player space plus color. So if its colors blue, it'll stay player blue. So now you can do something like this with your printout method. So you say player is new player green And then you do system that out that Perlin I am plus player And what will happen here when you have string concatenation between a string and another object, the runtime will automatically call to string on that object turning into a string. Okay, so what this will print out is I am player green. If this is the two string method for that class. Okay, the get classmethod returns the class object, which has a lot of interesting methods on it. You can find out. What methods does my class have? What attributes does my class that Is it an interface? Is it an array? What? What is, you know? Tell me about this. All the information about this class annotations, fields, etcetera. You can even create an instance of the class. It's basically calling a constructor. Um, this falls into the area of job of reflection, and it's a complicated thing that we're not going to tackle on in this class. But just know that there are more classes like this. There's a class called method. There's a Class A class called Package. There's all kinds of things like that that you can used to introspect your Java code as it's running, but that's a much more advanced topic clone. So when Java was first created, they thought it would be useful to have a standard method to make copies of objects. Uh, as it turns out, it's a very fussy and painstaking thing to write a really perfectly done clone method, and in fact, in my experience syllables. Nobody uses this. But if you ever find yourself needing to write a clone method, I would highly highly recommend you get Joshua Blocks book Effective Java. He's That's the one place where very details in very much, uh, explains in very much detail exactly what you need to do. A proper clone method, okay, equals in hash. These two are quite interesting in and of a lot of use. So a lot of times in programming, you need to determine if two objects are the same object, so you might have a collection of objects. And you're asking, Is this object already in this collection? Or maybe it's in a less thing. You're saying, What's the position of this object in the list? And you need to know whether the object you're looking at is the one you're interested in. So you're asking about the equality of of two objects and in Java they anticipated this early on, and and the methods equals in hash code, which are on job pulling object are involved in this idea of object equality. No, we're talking about whether two objects were the same. What does that actually mean? I mean, these air constructs in a software program. What does it mean for two objects to be the same? So this is actually uninterested discussion. So here is an object, a player. A is new player, Red. Okay, And then we have a second reference player B, and we just assign that to a All right, So what it looks like if you diagram and L We have this reference say that points to a player object and then be is actually pointing to the same player. Object. All right, there's only one object in memory here and is a equal to be Yeah, of course, right. They point to the exact same object like there's no possible difference between the two. You just have to references to the same object. But what if we have something like this player? Is new player Red Player Be his new player? Be? What that's going to look like is a is a reference to one player in memory, and B is a reference to a different player in memory. So they're not the identical object in memory, as they were in the first example. But are they the same? Are they equals? That's a good question. Uh, both players have the color have their color set to read. If that's the only thing that's interesting about players, then you might want to say yes, those two are equal. Okay, so let's take a look at how we how we write this in code. So here's the first example again, we have to references A and B, and the 2nd 1 is just initialized by saying B equals a. So they point to the same object. And now you can write an expression like a equal, equal Be okay. And that really tells you are these two references am be pointing to the same object and the, uh that that's what's called equality of Reference. So the reference a in the reference be both pointing to the same object. And then, in this case, the value of the Boolean. Same would be true because a equal equals b will will evaluate to true in Java for this kind of ah, 22 references pointing to the same object now for equality of two objects. Let's go to the second example where you say play, raise new player player, be his new player there, pointing in two different objects. So obviously if you say a equal equal be that's going to be false now because they don't point to the same location and memory. They point to two different objects. But depending on our, uh, business rules for the application, we may want those to turn out to be equals or not. And so what we will be have now is this job a method on that's from job allowing object called equals and so toe ask if the two references point to the same object you say equal, equal be. But to ask if there equals in a programming sense, you say a dot equals b all right and in this case equals could return true or false, depending on how you've programmed it, Right? So you, as the programmer get to implement equals in this would be in the player class. You can override the implementation from javelin object and you decide whether to players with the same color are considered equal or not. So here's, uh, example you run into all the time so you two strings s one and s two and they're both initialized to hello world. Now, when you say s one equal, equal as two that's going to turn out to be false. But when you say s one dot equals as to that turns out to be true. And that's because the equals method in the string class looks at, you know, do these two strings have the same, uh, string of characters inside of them not let me step back here for a second. Now, one copy out here. If you try to write this code in your in a project and compile it and run it, you might actually find that s one equal equal as to actually returns. True. So Jabba has this feature called Interning of Strings, which is completely internal to the virtual machine. You can't affect it. You can't make anything happen. But it will look at code like this and say, Oh, these two strings are the same. Hello world. Okay, let's just make s one and s to share the same implementation, so that will make them point to the same place in memory. So you might actually see that s one and s one equal equal as to returns. True, but in general, it's not going to okay, so by default equals the one that's implemented in the object class, java dot lying That object uses the same implementation as equal equal. It just returns. If you say a dot equals B, it just returns a equal equal. Be so out of the box. When you call dot equals on any class, you get the same behavior as equality of reference as if you didn't unequal equal sign. But you can, of course, override the equals method like you can override any public method. And if you want a different behavior, you need to you should. You're supposed to override the equals method. Okay, now, before we go any further with equals, there's a companion method called hash code, and this is a method that returns an integer for a given object. So you say any object at hash code, it returns in it. Why would you want to do that? Well, it's generally for grouping objects into quote uncle buckets. So as as a made up example here, suppose I had 100 players. I want to divide them into 10 buckets. It would be very nice if each player just randomly returned uninjured between one and 10 and then that would be its bucket number. And I could drop it into those into that bucket. Right? So there are some data structures that use logic like this, in particular hash maps. That's why this is called a hash code. Um, and there's lots of places where, especially data structure classes like collections, will use the hash code of the objects. So that's nice. But if two objects are equals, in other words, if a dot equals B returns true, then the values returned by their hash code methods must be identical. So if if a dot equals B is true and a dot hash code is 33 then be done has good must be 33 or else all kinds of things they're going to go wrong in these data structure classes. So well, that's not that encouraging, right? This starting to get hard to keep track of. It's like Wait, we need to hash codes and if they're equals and it has to be the same like that really starts to get a little bit difficult to manage. And so ideas to the rescue. So it's so difficult to write thes proper hash code and equals methods that they've actually encoded them into the i D. So here's an example from Calypso Eclipse until a J would do very much the same thing. What I did here was just created a player class with one attributes string color. You see it in blue on the top, left there and then I just right clicked. And I said, Generate hash code and equals taking into account the color of the string. And this is the code that came spewing out. Now this code is correct, and that's good, because you can see that if you just let it sit down and write this by yourself, it would be hard to get this right, especially the Eagles class, which is equals class. There's also many cases that you need to keep track of in the hash code method. Uh, there's these weird things, like, you know, starting with the number 31. Why 31? Well, there's actually some computer science behind that, where they when One of the things you would like out of your hash codes is that they're pretty randomly distributed across the whole the instances of the class and for some obscure reason that I don't understand. Starting with 31 is a great place to start to get that behavior. You can go research that if you like to. So if you ever need to write equals and hash codes, I would say Use your ideas generation facilities. In this case, if I have two players that have the same color, then I can generate unequal, and I want to consider those two players with the same color as equals. Then I would use the generate equals and hash code, and I would check the box to, say, Use string color in the comparison, and then it would generate this kind of, uh, code here. If you ever find yourself in the position of needing to write your own hash code and equals once again, I strongly referred to you refer you to Joshua Blocks book, Effective Java. He goes through probably 15 or 30 pages of exactly how and why to write hash code in and equals. How you do it properly, how you make it bulletproof, how you make sure it works exactly the way you want it to, and it's very I mean, looking at the code. It's clear that it's not very obvious, Right? So, um, please take advantage of his book if you ever I think you need to write, equals and hash code, okay? And that leads us with the threading methods. Wait, notify and notify all those air for managing programs that use multi threaded execution and job A is by its nature, multi threaded. So that's a big feature of job that you can have many threads running. However these air primitive methods on I don't mean that in the sense of imager into and double and things like that. I mean that in the sense that thes air, very low level building Brocks building blocks for building concurrent execution frameworks and like what I mean is don't use these like this is really hard to get right. You have to be kind of a genius, that concurrent programming to make this work on and work correctly as of the versions of job. But we're talking about now again, this class is using Java 11. So, um, you know, we have much more sophisticated and much, much safer concurrency libraries that we can use much higher level constructs that have been written and debugged by the top people in the world. And so you really want to take advantage of those if you find yourself needing to write explicitly multi threaded code. But if you do have to do concurrent programming, I'm going to give you three rolls here. So rule number one don't do it. Um, Rule number two, see Rule number one. But if you really do have to do it before you start read Java concurrency in practice by Brian gets Okay, this book is from from now it's probably more than 10 years old, but it's still like the number one reference on how to do proper Java concurrent programming. I had programmed multi threaded programs, probably for about a decade, so I thought I was pretty good at it. When I finally read this book, and after I read the book, I just felt like, Oh my gosh, I knew nothing. I had no idea what I was doing, like I had no business writing multi threaded programming because I, uh, multi threaded programs, because I really didn't understand a lot of things that are key to understand. And it helped me find a bunch of bugs that I was never able to track down prior to understanding that. Okay, so those are the main methods on Java lying object for our project. We're just going to do something easy. We're gonna have some to string methods so you can look in the instructions and and see what that says. Um, so you can, ah, pause the video. Now, do your exercise. When you're done, come back and start the video again, and I'm going to go through it with you. Okay? So go ahead and run the exercise now. Okay. Well, hopefully that wasn't too boring for you. Um, I'm going to go to my, uh, to the instruction book here. It basically says, Look, we were printing out the names of the player, the square, the peace and the card, and we're kind of constructing strings on the fly to print them out. Why don't we had two strings to make it a little bit easier, and so we don't repeat code all over the place. And really, the instructions just say, go through one by one and look at the two string methods. So let's, um, see if I can find my eclipse here. There we go and we'll start looking at that. So Well, I'm here on one. Right. Right here. I have a system out print. Lynn player plus color is starting its own turn. Now, this is inside the player class, right? So it's actually printing itself. It's referencing its own color attribute. So let's do this now. Here's another thing I don't know if we've talked about this and eclipse that were intelligent. I'm just gonna type two s t. I'm gonna control space and it says, Hey, you want to override the to string method and object, don't you? Yes, I do. Thank you very much. You put some helpful comments in there for you, but it looks like what we're gonna do for players. It's good player plus color. Okay, so whenever I print a player out, it's gonna say, player, blue player, Red player, this player, that and now I can get rid of this piece and I can just put Do you guys know what reference this should be? This. So this is the player talking about himself. So he's putting in this now. You could certainly do this. This dot to string. That's exactly the same thing, but you don't have to. The compiler understands that when you're contaminating to a string, it should call two strings, so you can just do that. And that's typically what people do. Okay, so what else? Let's see the card we said had a handsome print out. Uh, sorry. That's the card interface. Let's go into the implementation. Okay. Card of value. Something is how we call cards. Right? So go right down here and go to string. Take out this annoying thing and say, Looks like this is lower case card, uh, value and then add to it the value once again, the card. This print statement is printing out information about the current object. So once again, I can just do this great playing this card, which is going to return card of value something. All right, The square or let's see. Where would we be? I guess we would be in the peace class. Yeah. Here we go. Piece number. Something is on square something. OK, so first, let's take care of peace. And again, Two slips to string. Luckily, fixed my spelling areas there, and I'm going to say this is just peace. Books, capital p plus. No. So I can say this. So almost all of them. So far, we've been using this, right? But now we're going to say on square. And then, uh, the square is the position, right? So let's go into square. It has a number. So we'll do this again stringing grid of this well intentioned, good annoying thing. And now we're going to say, see, what did it look like? It said square, lower case square. Okay, fine square plus number. And then back here, we're going to say is on position. And then it's the position that get number. We would say position not to string. Or, of course, we can just take the shortcut here and say this is on position to string are his own position, right? So even reads a little bit nicer. This is on position. Kind of Sounds like what you think it would be, um, running this application. Let's see if it works or do we get exception? Hope it works. And let's see what the up what looks like starting ground zero Player blue is starting its turn and playing card of value. One piece one is on square one etcetera. OK, so this is working pretty well. Um, we did cheat a little bit here in the capitalisation because player came first. You know, if player came later on in the string, Now we have the capital P for player, but you get the idea of how these how these two string methods were used. And again, you could say this dot to string plus is on plus position not to string. But you don't have to, because the compiler understands that it should call to string. All right, so that was our little exercise that overriding some methods from javelin objects. So notice like this class here, peace does not extend anything, but we know that it actually extends object. And therefore, when you write a two string method, you need an override because it's overriding from jumbling object lips. Let's go here. Okay, So just one last like quick summary javelin object is the ancestor of all classes in Java. And what that means practically is that there are some methods that you have access to in every class that you write, we looked at to string and details the next most important ones are probably equals an ash code. And then there's some other things, like get class, which you might use if you're more advanced and then clone and wait notifying Notify all. You probably won't ever have to use those. Okay, so that concludes the class of the chapter about traveling object. In the next chapter, we're gonna talk about static methods, so we'll talk to you that 4. 04 Statics: Okay, welcome back. And welcome to Chapter four, where we talk about statics. So statics solve the problem of when we have attributes or methods that don't really have a home in any particular instance. Or maybe they actually conceptually belong to the class as a whole. But not one particular instance. Statics is, ah, language construct that helps to solve that problem. We often use statics as constants as utility methods, and there is a special pattern will be looking at called the Singleton Pattern, which is a statics. So one motivation for statics is to think about data that you could conceive of as belonging to the whole class. So here we have our player class and we want to have an attribute called The Total Number of Players. So total players and where should we keep that? Well, it doesn't really belong in a single player instance, because each instance is only one player. We don't want to appoint one player in charge of counting all the other ones. It really is Anak tribute that kind of belongs to the whole class and so we can make that attribute static. So we use the static keyword and we write public static into total players and then to complete the thought here in the player constructor, weaken increment the total players we say total players. Plus Plus that which means add one to the variable total players. Whenever you create a player that calls the constructor whenever you call the constructor, it increments total players. So you have kind of a bulletproof way of counting the total number of player instances that have been created throughout your whole program. Execution. Okay, so let's see how this works. If I create a player and I call that player Alice and then I say, uh, printout Alice dot total players Prince one. Of course, we've only created one player when I create a new player, Bob. And then I say print Lynne bob dot total players. What's that gonna print? Well, that's gonna print, too, because it's the same total players variable that Alice uses right? There's only one in the, uh in the jbm. And to underscore that point, if I go back to Alice and I say Alice dot total players at prints also number two because it's the same attributes right, shared among all players and in fact, therefore, it's a little bit goofy to use this kind of notation where you're using an instance reference like Bob or Alice. Too Deep reverence. Total players. That's not usually the way we do it. The way we do it is normally like this where you would say, player dot total players and that's Capital P player of the class name dot total players And that's the standard way to do it. And if you did this, if you created Alice, created Bob and then printed out player dot total players, it prints, too, because it's the same attributes as all the others. It's only what right? So static attributes of shared among all the instances of the class, and they could be d referenced through the class name rather than one of the instances. Okay, you can also make static methods. So here at the bottom, we have public static and get total players. So it's just a getter for total players. But it's static, right and has to be static because the attributes static and now they can act like a getter just like anything else. Um, notice that we turned the total player reference to private from public because it doesn't need to be. Ah, now that we have a getter, it doesn't need to be public anymore. Okay, now, static methods are not like instance, methods they can't access. Instance data. So here I've cut kind of a goofy class where I've changed the get total players get her to be a non static methods, and now it's an instance method, and it's trying to return the value total players. Do you think that would work? Take a look at that and think a little bit And the answer is, Yeah, it's weird, but it's OK. It makes the makes it look like get total players. It makes it look like like total players. Is an instance variable belonging to that particular instance when it's actually static so that it's a little bit, you know, confusing to the deceives a little bit. The client programmer and then at the bottom. I've got to get color method, which I changed into a static, and I said, OK, just return color. It's ah together for color, just like before. Does that work? What do you guys think about that? OK, no, that's not going to compile you can't have a static method accessing instance data. OK, and in fact, if you think about it, it's kind of nonsensical. What would What would it return if you said player dot get color? Right Color is an attribute of an individual player, like in our board game simulation. We have read player, Green Player, Blue player, Yellow player, right? Eso if you just say player class dot get color What? How could it possibly choose what color to return? The colors belong to the instances not to the class, all right, so always remember instance, members can access static members because statics belonged to everybody. But static members cannot access instance members because the static member doesn't know what instance you're talking about, all right, I hope that makes sense, all right. Another use for statics is utility methods. So let's just invent this problem here where we have a string that we need to format. We have a name and an age, and I want to format it out to say the age of so and so is something. And let's imagine for some bizarre reason that I need to call this kind of code from many different places in the program. Lots of different classes, lots of different locations. I don't want to copy and paste that string all over the place, right, because if I ever need to change it, it's a disaster. Uh, so I want to put in a method like this, right? Can pass in the name in the age. But where would that method live? What class shouldn't go in if it's being used everywhere in the program, That's a little bit tough to solve. And so, ah, common solution here is to use the utilities class and make that method static, right? So now it's available to everyone in the program, and the way you would use it then, is let's say we had a name and an age, and then I would say string utilities dot format string and I can. As long as that class is public and the method is public, we can see it from anywhere, and we can just call this from all over the program. All right. Um, same thing for Constance. Let's say I had a constant like the value of pie. I can create a class called math constants and I can put public static double pie in there . And now I can use that anywhere. I need the value of pie by reference referencing at his math. Constance, that pie now having the math constants in front. Oh, let's talk about the final first, uh, you don't want anybody going in here and changing the value of pie in this solution here. Someone could say math, Constance, that pi equals seven. Okay, And that would probably throw off your calculations. So when you make constants, it's almost always the case that you make them final. Okay, So what is the final key word mean? Foran attributes. It means that the value can never be changed. All right. Ah, remember, from part one of the class, if you have a final class, that means it can't be sub classed. If you have a final method, it can't be overridden. But in this case, if you have a final attribute, that means the value can't be changed. All right? Said a slightly different meanings. So then if someone tries to do something devious like this, that will fail to compile, all right, and again when people make constants and job. But this is the common way they do it. You make invariable that public static final, and then the name of the variable is going to be in all caps, and it's going to use Snake case with the underscores. That's just a programming standard, all right. Now, if we're tired of writing math, constance dot pie everywhere we do have this construct called a static import. Okay, by adding this static keyword to an import statement, you can do something like you see in the bottom right hand side there import static, math constants dot star. And then now you can just d reference pi as pie. You don't have to say math constant Stop I anymore. So it makes it look a lot better, and you can do the same thing for methods to. So here's a static import on the bottom right of string utilities dot format string. So we're bring in that one particular method and now, in the code below their Aiken say, just format string. And because I've imported it, it will call this static method on string utilities class. All right, so that helps to make your code a little bit easier to read, especially for using a lot of these statics. Okay, Now, on that note, um, kind of try not to overuse statics. It's practically global data and global methods, right? And those air dangerous, because if you can see the class, if it's public, then you can see the statics. And so and the public method is visible from anywhere and it causes. It can often lead you to have spurious couplings from all over the program to these places that maybe shouldn't be coupled to. That should have been solved in a different way. So you can end up with the proverbial spaghetti code. And you don't want that because it really becomes a maintenance nightmare and your life becomes very unpleasant at that point. Now there's another solution we can use statics for. What if you have a class that should have a singular instance? There should be only one instance of that class. Well, there's actually a pattern for that. It's called the Singleton pattern, and it uses statics. So how does this sports like? Let's say we have ah, class called universe and way want to live in a place where there's only one universe. So what we do first is we create a private, static, final variable of type universe called instance, and we initialize it. And that's going to be the only instance that we're going to allow okay and so and its final so it can't be changed or overridden or anything like that. And how do we prevent other people from creating universes while we make the constructor private? All right, That may seem a little bit weird at first glance, but you can make constructors private, and that means no code outside the universe class file can ever create a universe. If you tried to say U equals new universe, the compiler would say sorry, the constructors private, it would fail to compile. All right, so now we've got this Ah, single singular instance called instance. And we just ride together for we could write, get instance that has to be static because the instances also static and that returns the institute. So these three things together Ah, static instance variable a private constructor and a getter static getter for the instance that comprises what we call the singleton pattern. And it ensures that there's only one instance of this class ever created. Now, when uses Singleton. The economical way to use it is something like this. If you wanted to tell the universe to expand, you would say university. I get instance that expand and that syntax their universe dot get instance. That's nothing official. That's usually the way people do it. And when you see that, you should immediately think Singleton OK, When you see that get instance called on a Class a static get instance, Method called him a class reference That should be ah Singleton, All right, just like static. Singleton's come with some problems, so generally you want to try to avoid this, and I'll tell you why. Here. First of all, you can't control the visibility of a stink Singleton, because it's a static, get her to get instance. Method is a public static method. It could be called from anywhere in the program, and ah, you can't control. You can't hide it from people, right, And therefore you can't control the life cycle because anyone, anywhere in the program could be calling your singleton. And so what would happen if someone tried to call it before you created it or after you disposed of it? That would be kind of a mess, right? And says, since since it's visible from everywhere, it's visible from any time and so you basically has to live eternally like an immortal, and it's hard to stub out for testing. If you've got a method that you're trying to write a unit test for and it calls a singleton , there's not much you can do about it. And that's actually true for static methods as well. Hard to stub out so you end up whatever that single tender, static method is, couple to which you know, could be a database or an external network connection or something like that. You can't get rid of it in your unit, tests them without a lot of kung fu eso. You got to be really careful of these Singleton's. And also I've seen a lot of programs where people make, you know, every subsystem into a singleton, and they just reference each other from all over the place and once again at least two that spaghetti code and really becomes hard to peel it apart and try to isolate the subsystems. So a better solution than making everything Singleton's is to use something like a nap lic ation, micro kernel framework or a dependency injection framework something like spring or juice. And they will manage the life cycle on the visibility of the of the objects for you. You don't really need Singleton at that point. Okay, so now let's get on to our exercise. So what are we gonna do here? Going back to our board game simulation, we're gonna add yet another requirement, which is another special kind of card. This again modelled on the game of sorry when the value is 11 instead of moving forward or backwards 11 spaces, the player exchanges their piece for an opponent's piece on the board. You know, it says a different piece, but it's got to be an opponent speech. You don't exchange your own piece, so we're going to create a new swap card class to make this happen. If you did Part one, you'll remember we have a forward card and reverse card for moving forward and moving backwards that we're gonna have a new card called Swap Card. Let's talk about what we're gonna do here. So remember when how the plate proceeds, the player draws a card from the deck and passes its peace into the card and says, Hey, move my piece. Whichever way an amount, you know, you demons correct. The peace knows its location on your position as it's, ah square that it has a reference to. So the card knows the position of the peace, but now it needs to exchange it with the position of an opponent's piece. So we're gonna need to get an opponent from somebody so we can get their piece, which then will tell us what, uh what position they're at, what square their own right. And then we need to do the swap. But we don't have access to a new opponent. We only have the piece that's passed into the card. And so who in the diagram would be able to tell us who our opponents are? And in the end, it turns out it's only the sorry game. Who has? They're the ones who control the light. That's the one who controls the list of players. And so I could say, Hey, find me an opponent for this player. All right, so that's what we're gonna do here as we go into this. This is actually something of a complicated functionality. Ah, a little bit of ah involved project here. So if it's a little bit confusing for you, better use the worksheet or the instruction sheet that we have in the project section. But right now will be the time where you would go ahead and do the exercise. Pause the video. And then when you're done, you can, um, pause the video. And then I'm going to go through it with the one screen and kind of talk you through it. Okay, So go ahead and pause now and then when you're done, come back and we'll work on it together. Okay, I hope you got through that exercise. Okay, let's work on this one together. Here's the instruction sheet and it goes a little bit deeper into the motivation. Here. We talked about how we're going to create a swap card, but that is a little bit of a already a little bit of a design problem here because in the abstract card that are other cards subclass, we have this really a fairly complicated move method, and that's predicated on stepping the player either forward along the array of squares or backwards along the array of squares, but we're not doing anything of the sort. Now we're switching with an opponent, so that move method is is useless to us, right? And so, if we subclass abstract card will have to completely override the movement, that which would be totally fine. Except there's also that abstract hook method called Find Following Square, which we'd have to sort of stub out as a no up. And that's kind of goofy. So, uh, option number two is say OK, forget abstract card. Let's just take swap card and implement card directly will write everything ourselves, and that's fine. Except now we have to copy code like the two string method and the value in the get value, uh, get her method that has to basically be copied in tow into the swap card from the abstract card, which is also kind of goofy. Um, really. The right way to do it will be to split the abstract card into two classes. You know where the top level class would have the common code, the two string and the get value, and things like that, and then the move method would be in ah, a new intermediate class in between the current abstract card and the forward card reverse card. That just seems like a lot of work, for we're not really trying to build a perfect oh, system here. What we're trying to do is learn about statics. So let's just go with number two, All right? We're gonna just implement this the card interface directly. All right again, we need to know who the opponents are. So we're gonna talk to the sorry game to ask for an opponent. But this is where we get into trouble. We don't have a reference to the sorry game. And this is where we can solve this problem with the singleton pattern. Okay, so there's only one game instance that has to be true. If there's two or three or four games running simultaneously, that's gonna be really confusing that that would be a bug, right? And the game object is as long as the program. It's an eternal or immortal object. And that's true of the game, right? Like the game. As long as the game is running, the game object is there. So we have a pretty good candidate here, So let's go through this exercise and what kind of ah, will go along with these instructions. So turn the sorry game into a singleton and we got those three things that we need to do. Great. Let's get on the sorry game. Hello? All right. So do you remember what you need to do? Firstly, make the constructor private? All right. Good. And then I'd like to put my statics at the top. That seems to be fairly common for a lot of programmers. Teoh, statics first and then instance methods. So let's follow that. Remember the invocation? Private static final. Sorry. Game instance. Vehicles new. Sorry game. Okay, there's are single instance. And now we need to get her a public static. Sorry game. Get thistles. Just a regular getter. Except it's static rate because instances static, you just say return instance. Great. Okay, now it's a singleton just like that, and it says, Ah, step number two says, Hey, don't forget, we actually have someone called someone else calling the constructor. And that's our main method, right? We decided to put the main method into the game. If this had, if this main method had been in a different class, like a runner class or something like that, then we have a compile ever right now, But we do need to get rid of this because we don't want to call if we're using a singleton pattern and we have two constructor calls were in trouble, right? So how do we fix this? We would say sorry Game that get instance, and that would fix it. Now this is a little bit unusual syntax to put the game into a local variable and then just to call one method on it. So generally I think the more common way you'd probably see it. It's just like this. Take that out. But the other way is fine. If you were going to call multiple methods on the game in a row like 3456 methods, you may want to store the very reference variable the way it was a minute ago. So you don't to go get instance, like, six times, But anyway, this will do the trick. Okay, create a swap card class and have it implement card. Okay, we can do that, so that will obviously go into the card package. So let's do that. New glass swoops swamp card and we're going to add the interface card. All right, there we go. And we're gonna have to implement our move method. No, it does say okay. Before we do that, we need the value and the two string and to get value method that you'll see over an abstract card. So sort of annoying to do this, I'm just gonna go ahead and grab all of this and put this over here. Now, part of that's gonna break because we've got the wrong name here. But that's OK, you need to fix I don't know why Get value was formatted this way. Be a little more consistent. So it looks nice. And then the two string method, which is probably down at the bottom. So once again, this is not a design I'm gonna claim. Is a good design just kind of doing this for expedience? If we hadn't had this abstract method that we need to override in our concrete classes, I would have said let's just subclass abstract card and override move, but it just feels doubly goofy. Toe have to provide a implementation for an abstract method that's not even called in your class. That just seems like weird. So this is not good either. But anyway, there we got it. So we got that. I got the bad part out of the way here. Okay, let's implement the move method. We're going to swap with the opponents piece. What? We don't know who our opponents are. So we want toe. Ask the sorry game to fetch an opponent for us. But in order Teoh for the sorry game to calculate an opponent, we have to tell it who the current player is. So let's see, what we have is the peace. But I need to know who the player is. So let's see if the peace knows who. It's players because the peace only belongs to one player. Right? Let's call it a current player because piece that get player and there's no such method. Alright, Whips. Okay, well, I wanna have again. I want to have a me fix the important There we go. I want to have I need this player. So I mean, I can do this. I can just have eclipse create that method for me and saves me some typing. Now what? I want to turn return. I want to return. I don't have a player here either. So I'm adding a requirement to the player. I mean, sorry to the peace to remember, It's player, basically its owner. So what? It says here in number eight create a new attribute called Owner s. So we have a little bit of plumbing to deal with her before we can finish this use case. All right. And now down here when someone says get player weaken safe return. Um, another thing really is generally to string. Put that at the bottom again. Not not a rule of job A but it seems to be sort of convention. Right. Okay, so now we can return the owner, but owner never get set. So how are we going to find out who are owner as well? If we want that attributes to be initialized, let's have it passed in through the constructor. And then we have to do this stance of this study owner equals Okay, great. So now the player works, And if we go back to our swap card, But you haven't said yet, Okay, Now what? Now we have no more red lines. However, if you look on your problem tab, there is a problem is that we change the constructor for peace. But we didn't change where the constructor was called, and it's called in the player. So remember what we're supposed to pass in now to the new piece of data for the peace. Constructor is the owner of the peace. Well, this player is the owner of the piece. He's creating it, right? So we just need to pass in a player reference. And remember this keyword this which refers to the current instance. It's a reference, the current instant. So now the warning goes away. So we're back in back in Plano so we can get back to our implementation of the movement. Okay, so we said we got this. We got this. We got that. We get a current player. It was piece that get owner. All right. Now we're going to use a singleton pattern to ask the sorry game for an opponent, all right? And they show you the number 13 there. They show you how you how you should invoke that. So we're gonna say player opponent, people's sorry game. Get instance that find opponents of pines for pine opponent of I guess the current player. So this is nice program naming right opponent equals fine opponent of current player. So it's like, OK, that's very clear what it's doing. That method doesn't exist. And as they tell you, down here and so again, if you want to save some typing, you can say, Yeah, just go ahead and create that for me. It puts it down below main, which again, I'm going to say, like static method, like the main method should be the last thing in the class again, not a new official doctrine. But that's pretty standard, all right, and now we have the conundrum of Okay, great. How do we find the opponent of the player? And it talks about the algorithm here? It says, Well, sorry. Game has a list of all the players, and so what we'd like to do is just randomly pick one of those players, but not us, right? I don't want it to return myself back to me as as me as my own opponent. So what I'd like to do is get a list of all the players except myself. So that's easy to do. You can always remove elements from a collection But we can't do this to the economical collection of players that the sorry game owns. Because that's what it used to take the turns and go through and keep track of score and everything. If we start changing that list, we're gonna mess everything up. So what we can do is make a copy of that lesson than mess up the copy. Right? So there is a way to make a simple copy of a list. So if we look up at the top, we have listed players. A list of player called players sets duplicate that, Mr. Player, I think they called a player list. And a way to make a copy we're gonna use member list is an interface, right? Remember, From part one of the class, the rial implementation class is a rail is just like the way card is an interface. And then we have forward card, reverse card slot card. All right, So, uh, and what we can do here is pass in players. Oops. I'm wondering why it was red because you say new, you're crawling constructor. Okay, so a ray list has a constructor where you can pass in another collection and it will take the elements out of that collection and add it to its own collection. I mean, it won't remove the elements from the original collection. Just copies the references into its own collections. So now we have two lists of players that point at all the players, but they're independent lists, and the players are, you know, off by themselves. So what we want to do now is remove ourselves. So we say, Play our list, remove the all right player. All right, so now I have no. What's left in player list is all the players who are not me. So let's shuffle them. And if you remember in the deck from part one of the class, we shuffled the cards. And so there's this method called collections, which has a shuffle method where you can pass in player less than that randomize. Is it right now? Noticed something here. What is shuffle? It's a static method, right? It doesn't stay static in this, uh, in this, uh, dubbed doc Your bet. Eclipse Also italicize is it to show you Hey, that's a static. How do I know it's static? Because I'm calling it on the class reference right? I didn't create any objects here. Java Util Collections is a class of saying collections dot shuffle and then, uh, you know, put it passing in the player lists that will randomize the order of things in the list. And now let's just take I don't know the 1st 1 right return player list dot Get zero. There you. That's how you would find in a random opponent. Um, one thing to notice here. There's a little bit of danger here taking player. Let's not get zero. If that list was empty, that call would blow up and crash your program, all right, but we're making assumption here that there's always at least two players, right, And generally there's gonna be three or four who knows how many players. So we're gonna just say for our little simulation game. Yeah, this is OK, all right, but if you were really writing like production code for your company, you probably want to make sure that the list is not empty before you do something like that . Having said that, there's probably a lot of places in our code that are not 100% safe, but let's keep going Okay, So now great. Now we want to get the locations of these are the positions of these two pieces. So the position is a square, right? So we square the current position of the current players. I'm just gonna call it current. Position equals the piece, right piece that's being passed in dot get position. And then the opponent's position opponent opponents position equals the opponent. It's not The opponent. Doesn't know what his location is. Only the peace does. Right. So we actually need the opponents piece. Forgot about that part. So we're gonna say peace opponents peace because opponents get peace and we don't have to get peace method. Here we go again. So again, I told you this was a little bit of an involved exercise. So let's go and create that method in the player class. And again, it put it below the two strings. So I guess if I'm gonna be consistent, I'll move that. All right. So what's gonna do? What are we gonna do when we say get peace? What? We're gonna return the piece. We already have a piece here. And luckily, the player only has one piece. If you wanted to extend this game to be a little more exciting where the players have multiple pieces. Then what you could do this getter would be. You want to probably return a random piece. So maybe you would change the name to get random piece, and then you would do the same thing. You'd have a list of pieces here, you could shuffle it, and then you make a copy, shuffle it and then return the 1st 1 and then you would have a random piece that you'd be swapping locations with right in the swap method. So that's an easy way to extend it. I'll leave that for you guys. Teoh Play with if you want to do that. Now, we got this. Okay, so now opponents piece got get position. All right, So now we got the current position, our current position, the player who's taking the turn and one of their opponents positions. And so what we'll do this will say peace set position to the opponent's position and will say opponents piece, step position to the current position. Uh, we call it that we not call it current position yet. We call the current position. I'm not sure how we got that? Yeah. Okay. And again, notice how we're using, like, really good names here, so you can keep track. Is this even though we're just swapping two references here like, it can be a little bit, um, you can lose track, even this little 10 line method, so use good naming in that way. It reads very nice. Opponents busies opponents piece set position to current position. Peace. That's have position opponents position like, yeah, that that's what we're trying to do. All right, so here we go. Going through all this stuff. Let's swap. Um, yeah, we're almost there. Um And then there's a note here at at step 21 saying, Hey, we're relying on abstract card right now for some output. So if we don't put any print lines here, it's going to go silent when we draw a swap card. So let's go back to abstract card and see what they've got going. So they say before, as the move method starts were saying, you know, I'm playing this. Okay, so let's put that at the top. So it looks the same as giving this space there so we can read it better. And then at the bottom were asking the peace to print its location. Okay, Makes sense. Print, location. And maybe I'd also like to do this and say, uh, I'm gonna print a special note here that we know what's going swapping. Ah, let's just say I hope we say don't do too much. Something current player. Okay. Sorry. But sane with appellant, right? And so that will Prince Amat like swapping green with blue, swapping red with yellow. Something like that. It will print that out and will be able to see it. Okay. And then the last thing we have to do this one's easy to forget on number 22 we haven't actually created any swapped cards. We built two down and build all this complicated functionality and all these methods all these getters all over the place to get the data we need. We don't actually have any of them. So cards were created in deck so we can go over here and see if the card is a four. We do reverse card, otherwise we do a forward card. So now we have a new case else. If value equals 11 we say card because near swap card of Okay, so now we should get And you know, we needed important. So, uh, by the way, what I'm doing for imports and eclipses control shift. Oh, that's a shortcut that says, Clean up the imports and it will look. And if there's classes that it doesn't recognize that it doesn't have an import, for, it will go find it. And since there's only one swap card in our class path that knows to import that and if you have extra imports statements lying around that you're not using, it will get rid of them for you. Okay, so that's a nice thing to do now and then Control shift. Oh, takes care of that for you, All right, so that should be it. We go back to our instruction sheet here, and it's like, OK, run the game and let's see what happens. Let's see if we can find some of these swaps. Ah, run as job application. Well, I can't see it here. There we go. We've got to swaps here already. That's kind of interesting. So let's see what happened in this game when we started round number one. Ah, player blue went to 13 and player Green went to 20. And then player Blue started pulled in 11 and then swap with player greens and a plate. Now, Player one is on 20 and so, presumably, player Green is on 13. But then player Green pulled in 11 card. And so it's swap green with blue and it's back on square 20 right? So they actually this round two cancelled out. They both swapped with each other to swaps, so we should be back on 13 and 20. So player blue draws a 10 which takes him back to 20 up to 23. So he was on 13 player Green pulls a six, which takes them up to 26 so they were on Square 20. So it's working pretty cool. All right, let's just go back to finish our chapter with a little bit of ah summary. So we looked at static members, static attributes static methods on, 5. 05 Collections: Okay. Welcome back, everyone to Chapter five. What we talk about collections managing more Bunches of objects. So collections are a type of class that enable us to hold references to multiple instances . And we've already seen lists. But there are other types of collections as well. There are sets, there are maps, they're accused and some or specializations of those. So we'll look in this chapter, will look over the different types of collections, will review how to iterated over collections. Ah, and we'll look at how you could add primitive values to collections, even though they're not objects by using something that's called rapper classes. So as a refresher, a collection is an object that can manage a set of references to other objects, kind of like an array, the objects that are inside a collection or generally called elements. So that's the terminology that you'll hear. And this This drawing here represents a collection with two elements Player number one and player number two. Okay, this is the, uh, class hierarchy of the basic set of collections. All of these air interfaces, So there are lots of different implementations, and we'll look at some of them as we go through this chapter collections fall into two basic categories. There's the collection side, and there's the map side. So let's look at collections first. So at the top there in the collection interface, we have all the methods that are common to everything on this side of the of the class hierarchy. And that would be adding an element, adding all the elements from a different collection clearing the collections that we're back to empty asking a poke collection contains a new element. Asking a collection if it's empty or not, asking a collection to remove an element and asking the size like how many items? Aaron A collection. Now, this is not all the methods that's on the collection interface. There's a lot more, but these are the ones that are kind of the most commonly used. That would say so. Subclass ing the collection interface. There are three more interfaces down here and list, so we've looked at list before, and this is a collection that holds elements in order. Right? So you put them in 123 They come out 123 so you can say get an element given an index to a list you can ask to remove the element at a particular index. You can replace an element at one indexes in the SEC command, and you can get a sub list like let's give me 0 to 5 or something like that, or 5 to 6 or something, because the items are in order, their indexed. And remember, it's zero offset index, just like with that race. So the first item is called zero, and the second item is one. It's unfortunate, but that that's the way it is. Sets don't really have a lot of extra interesting functionality at this level, but what's interesting about a set is it does not allow duplicates. So if you try to add the same object multiple times, it only gets added once, and we'll take a look at that later in the chapter. A Que is a slightly different kind of a beast. Uh, whereas a list or a set is generally a set of items of a collection of items that you're keeping around for the whole program. So, for example, in our project, the list of players okay, we populate the list at the beginning of the program and it stays for the whole length of the program. We don't expect to be adding and removing players all the time. A que kind of signals, the intent to do just the opposite, like it's a place to hold a bunch of items temporarily. And the typical use case for a Q is when you are creating work items and you're putting work items onto a Q and then later on, you're gonna pick them off and process them. And so it really is meant to have a lot of Adam remove activity. And they have since specialized method names. As you see in the in the diagram here, we'll talk about those later now. On the right hand side, we talk about maps and maps are another different thing altogether. They don't just hold a list developments. They key them by keys. So these air key value pairs, and we'll look in more detail how that works later on. But there's some methods that are the same, like uh, size and clear and is empty those air common. But when you put on object into a map, you have to give it a key, and the objects itself and the value. So, uh, and if you get try to get something out of a map, you have to supply a key. Um, you can ask for the set of all the keys. That's called the key set. You can ask for a collection of all the values that's called values again. We'll look at all these implementations a lot closer in the upcoming slides, But let's start with basic collection methods. Let's say I have ah, collection of players, and it's just typed as collection. Okay, so I'm going to create It doesn't really matter what type of collection it is right now and then. I have two players I created Alison, Bob, and I add those to the collection. So I say players not add Alice players that at Bob. So how many elements do I have now? Well, I should have to. And if I print out players that size that will print to at this point, I can ask the collection. Do you contain Alison? So, yes, we added Alice up above, so Alice is contained. And then I could clear the collection and then print the size again. And now it would say zero. So it would know out all the references internally and be like a fresh collection again. Okay, let's take a look at lists. So here we go. We create some kind of list. We have our players, Alice and Bob. Again. We create a list of players. We add them, and now what we can do that that's unique to list is we can get them out by a ended your index so we can say, Give me number zero. Give me number one and zero will return the reference to Alice. I can also say, What is the index of Bob? And that would return one because Bob was the second item at it. Remember, it's zero. Offset to the second item is one. And then I can even do something like players that set one comma Ellis. So I'm replacing whatever was that reference number one with the reference to Alice. Now, that was a reference to Bob. So now we have only two references, Alice and slot zero and one and Bob is out of here. Okay, The different types of list. This is basically what the class hierarchy looks like. Not exactly, but the workhorse is a Ray list. This is generally what people are going to use. Unless they have some specialized requirement. It is actually backed by an array. That's why it's called a rainless. So in addressing by indexes really easy. So if you have an array of 1000 items and you say I want to go to Item 356 you can do that in a constant speed operation. It doesn't get slower. As the array get slower, Ansari gets larger. I'm sorry. Um, on the other side, we have linked list, which is a set of nodes where each node holds an element, and it knows the has a reference to the following note. And so, if you work through the, uh, project with us, remember how we did the squares each square knew about its its next square. That's kind of like a linked list that's essentially a link list implementation. So looking for Item 356 is a little bit slow because he kind of walk through the listing count. 123456789 10. But if you want to add or remove an element like if you have a reference to an element you save. Remove it all. It's very, very fast to remove it, as opposed to merely ray List where you might have Teoh free position, the following elements. Having said that about faster, slow, it's really not going to matter unless you're up in a large number of elements, like tens or hundreds of thousands. And even then, um, there's probably not huge amounts of difference here. But, you know, poor follow your system. Make sure you know that you got the best implementation. Okay, sets sets are a different type of collection. And to show this good, we, you know, create some set implementation. And then here we only have one player. We just have the Alison. We try to add Alice three times What's going to be the size of this collection when we're done. Okay, remember, this is a set. It's going to return one. The second and third ads were going to be rejected because the set is going to realize, Hey, I've already got Allison here, and you can't be in here twice, right? So that's what the unique, uh, functionality of a set is. Now. Sets have some. Very. There's very interesting variations on set. So you see this a little bit more complex hierarchy here and again, This isn't the entire hierarchy, but this is enoughto cede our discussion. So, uh, the workhorse in this side of the house is generally half set. So when you create a set, unless you have more specialized requirements, you usually just use the hash. That. And when you put items into a hash set and then you iterated over the set, they come out in some random order. But it's not, actually, you know, random nothing in a computer is truly random. But to the program, it looks like the the order that you inserted them is completely unrelated to the order that they come out as opposed to the link hash set where the iteration order is the same as the insertion order. So if you go to a linked Hachette and you add Alice, add Bob, add Charlie and then you iterated over the set, they're going to come out. Alice, Bob, Charlie in the same order that you inserted them. All right, On the other side of this page, we see the sorted set, which is just as it said the items were sorted in some kind of order. So, for example, if they were numbers and you added 123 then they would sort themselves 123 Even if they were added in a different order, like 312 they would still sort themselves into 123 Or if they were strings, they would sort themselves out alphabetically. Okay, And then because the set is sorted, you can ask for these methods use here like headset or tail set. Um, head means the beginning of this set and tail means the end that this is kind of computer science terminology. And you could say Let's say you had ah set of strings and you would say Headset of dog that would say, Give me all the elements that come before dog All right, so would be the A's to B's. The seas and the D's up to D O G. Right or tail set would be the ones following etcetera. Navigable set takes that set of methods and add some more things on like floor and ceiling and higher and lower. And the implementation on this side of the class hierarchy is something called a tree set. So again, when you iterated over tree set because it is a sorted set, the elements will come out in some sort order now numbers and strings. That's easy to understand what this order is. What if it was players? Well, that's a good question. We'd actually have to teach the compiler how to sort players, because by itself, it doesn't know. And Java has a whole little couple set of classes that we used to do that called Comparator . There's a new face called Comparable, and we'll be looking at that in a later lesson. Okay, then onto cues. So same thing we created a couple players. We create a Q. And then we add Alice, add Bob and then to pull them off the Q. Now we would use a method, for example, like remove and generally because queues are thought of not so much as generic elements but as work items. Eso Then you would pride like I'm gonna process these players. So as players need processing, I add them to the Q. And then at some point later in the program, I come back and I just go through the Q and I keep removing items till it's empty, and I process those items right. That's kind of the the, uh, the economical way of thinking about cues. Now. How did the items come out of the queue? Well, there's different implementations, of course, and there's first in First out. There's last in first out right, which is kind of like a stack. And then there's also a thing called ah Priority queue, which is basically sorted, and the sorting attributes is what we call priority. So the queues looks something like this. There is the main que interface, and on the left hand side we go down to the part. The priority queue, which uses sorts, the queue on attributes and that attribute it's called the priority. And so the highest priority items that you had, they go right to the front of the queue, and the low priority ones go to the end, right? So it helps you to to process work items in the proper order. A Deck D e. Q. U E stands for double ended. Q. You can add things and remove things from the head or the tail of the queue. And then there's two implementations here the array deck and the linked list. Both the which are by default, are first in first out federation order. Now for Q operations they generally have. There's there's three general types of operations which is insert a night, um, removing item or just examined to see like what is the next item? And there's two different families of operations for each of those intense. The ones in the middle are the ones that will throw an exception if it fails. So, for example, you're trying to add another item to the to the Q. And if use the ad method and the Q is full will throw an exception. If you use the offer method, it will return false or no or some other special value that you need to test for right. So if you don't want exceptions, so the exception throwing methods are add, removing element and the ones that return special values typically, no or maybe false would be offer pole and peak. And I do realize we haven't spoken about exceptions yet. That's next chapter, but basically an exception is something in Java that's used to signal on an error, and this will become a little more clear next chapter, okay, and the deck is pretty much the same. But you can pick the head or the tail of the queue so you could say add head, add tail removed, head removed tale element head elemental, etcetera. The same thing for offer Poland peak so you can pick whether you want to put them at the at the beginning or the end of this list of items. Okay and queues just to say accused. When we looked at the class diagram here, I had three implementations Party Q Ray Radek, Sorry and link list and, uh, Queues. However, there's there's many other implementations of queues index, but I didn't really put them. I didn't put them up there because they're generally used for multi threaded programs. And a common paradigm in a multi threaded program is like one threat is producing work items, so it's reading a file or reading in socket or something, and it's creating Bunches of items that need to be worked on, and it throws them onto a Q and then some worker threads come later on and take items off the Q and then go process them right. That's a very common paradigm or the other way around a bunch of threads of producing work items. And then there's one processor or many to many could be anything but Java has quite a few implementations for cues index that are specific to different that have different concurrency models. So, like, do they block? Do they throw exceptions, etcetera? And when you get into writing multi threading multi threaded programs, you'll want to look at that library very carefully to decide which one is best for your application. Okay, lets go onto maps. Now, remember, maps are not They don't, uh, their collections, but they don't implement or inherit from the collection interface, right? They have their own inheritance hierarchy. And so you create some map here called players again, and now toe add items to the map. You don't just add them, you have to put them in the map, and you have to use a key. So here we're putting ah, the players Alison Bob into the map. But we're using as the key their names. So we use the string Alice and the String Bob as the keys for the map. Uh, for the items that go into the map. And then when you try to retrieve items, you can retrieve them by key. So you can't. They're not sorted. You can't. You don't get them my number or anything like that. You get them by the key that you put in. So this is a really super helpful data structure. When you look at maps, it looks very much the same thing at sets. And that's because the keys inside of a map are held as a set. So, uh, depending what kind of ah set implementation is used for the keys, then that will determine what kind of the behavior of the map. So hash map is typically the workhorse of the of the map family here that you're sort of default map implementation. Then you have assorted map, which is another interface that has just like sets are, um, head map tail map, etcetera. Then there's Navigant map navigable map, which is ah, sub interface of sort of map and has this floor key ceiling Keeve. Higher entry, lower entry. Ah, whole lot of methods like that. These are just samples, and then the implementation of the site is the tree map. That's the one that Is that implements or yeah, that implements both sorted map and navigable that. And again, there are some map implementation that air specific for concurrent programming. Not gonna go into those here. Okay, When you use on object as a key in a map, this is where it's super important. That hash code and equals are correctly implemented. Okay, we talked about this several chapters ago, and this is where it really matters. And if you don't have a proper implementation of equals in hash code, you might lose your object forever. So you may put it into the map and then try to retrieve it, and it won't come out like you'll say, get using this key, and it will always return null. So you have to be really careful. Um, a vast majority of maps. I would say you string an imager as the key string or integer as the key type. And because those air J t K types, you know, they've equals in hash code or properly implemented on those two classes, so you don't really have to worry about it. Eso eso if you're using strings or integers or something like that is keys to your map Piece of cake. Don't worry about it. If you're gonna make your own custom class for a key, you better make sure that equals and hash code are overridden precisely the way you want them to be. Okay, when you iterated over collections, they all work the same. You just do this kind of This is called the implicit for Loop. And let's say I have a collection of players and it could be a list a set Q a deck, whatever it is. But you can just do this. You can say for Player Colin players and then talk to the player. And when you that statement is red. As for each player in players, right, that's what the colon and that notation, that's how you read it. Um, and you can do this because all the collection classes also implement an interface called it a rubble. And that's what you need to use. That's what you need to implement in order to use a statement like this. But that's a little more esoteric. We don't need to worry about that. Too much maps are a little more complicated. There's actually three ways to generate maps so on the top left here, you see using the method key set. So remember I told you the keys in the map are held in a set implementation. You can pull that set out by saying key set, and then you can generate that set like you would any other set like on the previous slide below that, uh, you can get all the values out of the map by saying that values and that returns a collection of your values. And so you can do for each player in players that values, and you can generate over the values in the in the map. Or, if you want the key and the value, they turn your attention to the right hand side. You can say the entry set and entries in map language are objects that contain a key and a value. So think of it is like, Well, it's one entry right has the key to the object and the and the actual object itself, the actual value. So for our map of string to player, we see that when you say get key, it returns a string. When you say get value returns, a player note the class of the variable entry right? It's called map dot entry. That looks a little bit odd. We haven't seen that syntax yet. That's called an inner class entry is an inter class, and we will discuss in her classes at a later point in the course. So don't get too freaked out about that at the moment. Okay, along with the collection implementations, there are some helper methods in this class called collections. These air, all static methods. We talked about statics a few chapters ago and these air static helper methods that that you might end up using from any wearing in your program. And so they're all gathered together in this collections helper class, and I just pulled a sampling out here. There's many, many more than this, but here's an interesting one. Um, we didn't really have a implementation of cues that were life. Oh, cues. In other words, a life. A last in first out queue as a stack, right? And there are no there's an old class called Stack, which we don't use anymore. But how would I turn like my radek into a into a que Well, you would do this by saying or into a stack. Rather, you would say as life o que and that changes the semantics of it to be a last in first out queue instead of a first in first out queue. If I'm looking for an object in the list, some element, I confined it. Using a binary search, I can copy one list into another. I can get an empty list or an empty map if I need to start. If I just, for whatever reason, I need a new implementation of an empty list on empty map. I confined the max and men of any collection that has items that are sort herbal, you know that have some kind of order, like numbers or strings or something like that. I can take a list in reverse, the order of a list. I can take a list that I can randomize the list by using show shuffle, and we saw that method right. We use that to shuffle our cards in the deck, and we use that when we were trying to select a random opponent for the player when we implemented this singleton pattern, right? So we've used this class multiple times already um, if the elements air sort herbal, you consort the list, and if you want to make it so that nobody can add or subtract from your list like or your your set or set list collection, there's there's overloads of this method for all the different types. But what's written here is set. If you don't want anyone to be at our adding or removing to it After this, you can create an unmodified hable set and then pass that around. And if anybody tries to add or remove elements from that one modifiable set, they get an error. They get an exception because that's the way it's kind of a defensive programming technique . Okay, back in the day, Java one shipped with a handful of collections that were, you know, not the best. And when Job A to came out, one of the big selling points was this new collections framework. So they adult all the ones we've been looking at or the new collections, but they didn't remove the old ones because, you know, people were using them, and here we are 20 some years later and they're still there. So we have on the left hand side of this table are the old Java one collection types. On the right hand side are the current equivalents that you should use instead. So unless you have some riel ah, compelling reason to use any of these dictionary hash table vector stack, you should instead use one of the more modern ones. Okay, short cut creation. We don't have a literal collections intact, so what I mean by that is in a lot of languages, in fact, they'd probably most languages. You can do something like list equals and then square bracket. And then, let's say it's numbers one comma, two coming. Three come before and then closing square bracket. And that's a shortcut. Notation for list, which is a lot nicer than saying list equals new array list and then saying list dot add one list dot Add to you list out at three. That that's quite annoying, right? So we don't quite have that in Java yet, but we do have these factory methods, and so on. This came out. I believe in Java 11 Like on the list interface. There's a method called of and you can say list out of and pass in. Ah, list of elements there and that will create a list. Or you can do the same thing with sets. With maps, you have keys and values, so you have twice as many arguments to the methods. You go key come a value comack aecom a value, and it puts them in like that. So this is a lot nicer than what we have before. If you're only doing one of these like, let's say, your class only uses list that up, you could do a static import on Let's start up and then you could just say of and you wouldn't have to do list dot So it it's almost literal syntax, but we still have to use methods. Still used friends and stuff like that. Okay, the primitives. So that takes us through the general types of collections. Like I said, there are a lot more implementations. And if you're really a data structure hound or if you need something really specialized, I encourage you to go through the Java doc and see what other implementations air out there . I did not put everything on the slights because there's way too many, but those are the main ones that I showed to you. Now we come to this problem of primitives like little I ent long double etcetera These air , not objects. Remember, these are like data types that trace their ancestry back to C programming language. Right, So they're not objects and therefore they can't be putting collections because, remember, collections take objects like and I'm talking capital o objects. So that seems to be a real crushing defeat because you can imagine there'd be a lot of times we would have a list of numbers or something like that. But all of our numbers are these primitive types. So what job provides you is object versions of every primitive. And these air called the primitive rapper types. So what are they on the left inside of the primitives and on the right hand side, er there rappers Generally it's the same word capitalized because it's a class. So we use the capitalize one, except we spell out imager. We spell that character and things like that, but so they're not hard to remember, and six of them are numeric types. So bite short ended your long float and double they all subclass the intermediate class cult number So this is in the java dot lang package, and what number provides for you is the ability to do conversions, right? So if you have, let's say a float and you want to turn it into an ent, you can say float dot into value, and then it will return it as an integer. Obviously, if you have, you know, if you have the number 3114 and you try to turn that into a bite that's too big to fit into a bite, so it will be narrowed down to fit into a bite, with probably surprising results for you. So you probably don't ever want to do that. If you do want to do that, if you're doing something really bit twit Lee, make sure you read this speck and understand exactly how those narrowings work. So, um, other ways to convert. So that's going from the rapper class back to the primitive to go from primitives to rappers. All the rapper classes have these factory methods to convert from primitives and from string representations into the rapper classes. Depending on the class, there could be more specialized parsing methods available, and they will also let you know what the minimum and maximum value is. So what am I talking about here? Let's let's look at some code. So here's these value of methods. There are these value of methods on all of the primitive rappers and one of them, like the 1st 1 you see taking a little I ent because I've written 17 That's a literal int in Java, and I say imager dot value up and that converts it into an integer object, right? So I is an object. The other value of is the one that takes a string, and I put in the string 18 and that will be sort of unwrapped, parsed and turned into the into your object for 18. Right? So it knows how to take the string representation of objects. Oh, are of imagers and parse them out and convert them to endure objects. That's very useful, uh, imagers, one of those types that has special parsing methods. And here's one of them called Decode. And what is decode mean? Well, we didn't really talk on this before, but Java has multiple ways of representing imagers literally, and it recognizes natively four different bases. So if you have a string 123 okay, that gets parses based. 2010. That's 123. OK, but if you have a strip, if you write a string that 0123 job because of leading zero Java will parse that as base eight, assuming there's no there's no eights or nines in it, right? If there's an eight or nine, I think, then it falls back to base 10. But if you go 0123 it's gonna it's gonna parts at its Octel as a base. Eight. If you go zero X and then numbers and letters. After that, that's based 16. That's hex. OK, so you go 0123 ff be right, and that will be parses based 16. And then you can even do binary. You can go zero be. And then, of course, you could only use ones and zeros. That's that after that, but that would be parsed as based. Two. So zero B 11010 whatever number that IHS right So those can be decoded by the integer class and turned into and an imager object right and then if you wanted just the little into value, you could say, What could you say? You could say k dot into value, right? Because it it's sub classes number. So it'll be ableto change the mat, all right. And then what we see here is ah, the energy class will tell you that max value that an aunt or an imager can hold right. And for imagers because they're signed in their four bites, it's like two billion something. I forget exactly what the number is, but you don't have to remember either, because they have Max value. They have men value, and they have that for floats and doubles and shorts. And all the other numeric types will have a maximum in all right now. So we saw how to convert from primitives into the the rapper types and how to convert and how toe, you know, call methods like value to go back to primitives. But there's you don't have to do that. We have this thing in Java called auto boxing, and so up here we see how to box or auto box something. So we have a little i n to primitive and say I equals 17 and then we say energy J equals I . Now, at first glance, that looks to be illegal, right? Because ones and intend ones and editor, you can't just assign them that way. Right? But in Java, this is legal because the compiler looks at that and realizes they're compatible and does what's called auto boxing. And basically, what it does is called ended your dot value up by right And it does it inserts that call for you without you having to type it, which is very nice. And it works the other way to So here I have a capital I imager end. Then I say into M equals end. It will unbox it at that point and turn it back into a primitive and, you know em will be equal toe 33. So this is super valuable when you're dealing with collection. So here's two sets of code that used to be really problematic. So I have a four loop and I'm looping over a little I ent So the variable I in both kick both code snippets goes from zero dear to 10 or from 09 right, good. But there's a loop of 10 times, and I'm trying to add those numbers into my list. Uh, but I is a primitive. Before we had auto boxing, which I think was Job of Five, you would have to convert the little I primitive value into a capital. I ended your first and then add it to the list, which was just a lot of extra typing that didn't really, um, it's just wrote right. It doesn't really add anything to the meaning of your program. It's just extra work that that Java makes you do. And so now, with the auto boxing, it will automatically convert them to an integer. And if you iterated over your list and assigned the value toe a little I ent, it would get that and it would unbox it into the little I ends for you. So you don't have to worry about creating and unpacking these rapper classes anymore, so that's super useful. All right, so we're ready to go do the exercise because we've done a lot with collections already. We're not going Thio Thio, a super complex up exercise here, but we haven't used maps yet and maps are very important. So let's do a little bit of fiddling with maps and see how that works. So you know the drill by now. Get the exercise sheet ready. Go and pause the video. Go ahead and do the exercise. And when you're done, come back and start the video and I'll walk you through it. Okay, so pause the video now and we'll see you in a bit. Okay, I hope that exercise went easy for you. Let's go find the exercise sheet. So again, at the beginning, it's just saying, You know, we've already done. We've already added elements. We've removed elements. We iterated list. We've shuffled elements like we've exercised collections a fair amount already, simply because it's so hard to write an interesting program without any collections at all . Generally, you always have collections, so let's do this. Let's have the sorry game. Besides, its list of players that it uses to run the game turns, you know that it loops over. Let's store the MIT players, also in a map that's keep by their color. And then at the end of the game, we're gonna pull out player green and print their score or, you know their location. I guess maybe a little more accurate. It's not really, Ah, brilliant requirement, but at least it gets us to play with maps a bit. So it says in the sorry game. Add the new attribute. We want to create a map that uses a string index players. So let's go over here to Sorry game A new attributes. Let's put it right after the list. Thank you and call it players by color. Right? That's what they asked for. Bring the important. So again, this this sharp angle brackets in tax is just saying this map has the keys or strings and the values air players. We are going to de mystify this syntax later on, but probably not until part three of the class. So hang onto. This is called generics, and it's a little bit complicated, so don't worry too much about that. All right, let's make this a little smaller. Okay, then it says create a hash map in the constructor. So right after the array lists, we'll do this stuff. Play players by color Pickles. New Cashman. For whatever reason, we still to put those little angle brackets to make it compile. We got players by color. Okay, and now it says, All right. Now, every time we create a player right now, we're adding it into the list. But we also want to add it into the map. Is starting to be a lot of work every time we create a player. So let's create the helper method. Right? Just like we have create squares constantly. Private Boyd three player. And we want to be passing in the color, right, cause we're gonna dio blue one and a green one. And if you want to do more colors, you know, feel free to do more colors. So what we're gonna do first is we're gonna create the player there was new player with that color and squares of zero starting square. Great. So we have to add it to the list. So, uh, players, that ad player, all right. And now we also need to add it to the, uh, to the map. Civil say players by color, put with color as the key of what changed to compute on the white. Did that put? I said, color is the key player is the day. All right, That looks good. And then it says in the constructor Now we'll call this instead of doing what we were doing before, which is a little bit. You know, this is kind of we've got this value repeated start sq 6. 06 Exceptions: all right. Hello, everyone. Welcome to Chapter six. All about exceptions. Exceptions are the mechanism built into job, a Teoh handle and signal errors. So we'll take a look at the main syntax, which is the try. Catch. Finally, block. We'll look at how to throw exceptions, and then we'll look at some other syntax like multi catch. Try with. Resource is and then we'll go into the very important distinction between checked and unchecked exceptions and will close up by just looking at a handful of the built in exceptions in Java. Okay, so first thing to realize is exceptions or just objects, but they have a special designated super class that they need to extend. And because they extend this special super class, which we'll see in a moment, exceptions can be thrown in quotes. And what does that mean when an exception is thrown? The code stops executing at that at that point and then proceeds to some error handler. So what in the world am I talking about? So here's some code. Do this, do that, do the other. And let's just say that the second method do that throws an exception. And in the next few slides out clarify exactly what that means. But if that line throws an exception, then the following line does not execute. So the that stream of execution there that whatever that is that method that's executing when it hits do that, do that throws an exception that it ceases to execute. That doesn't follow down below that line. All right, so the main Syntex we used to control this behavior is the try catch blood. And so here I've taken that misbehave code from the previous light, and I put it inside a try. But try block. So try and catch our keywords in Java. And again, if the second line do that throws an exception, then the threat of execution skips do the other, doesn't actually execute that and said instead, it will jump into the catch block, which is basically the cleanup block. Okay, that's where the, uh, the whatever messes created by the error that do that through you got to clean it up there or at least put in the logs or something so that somebody knows it happened. And then once the catch black is done, it just program proceeds as normal on with the next task down through the rest of the method. Okay, so try catch. Blocks are going to be probably the most common exceptions in tax you'll be using because there are a lot of methods in the job libraries that you'll be using that throw exceptions that they will need to handle. And this is how you handle now. What does it mean to throw an acceptance of the other side of this coin? What's going on in that in that terrible method? Do that that's causing it to throw an exception. So here's some some pseudo code you get into this method, you do some work, and then if something terrible happens, you throw a new exception. So look at this line through a new exception, new exception. That's just creating an object. That's the normal new operator that we've used to create players and cards and, uh, squares and things like that. So you create this exception object and again, exception is a class in the job, J. D K and you say, create this new exception and you take that object and you throw it. And so what happens when the execution hits that line? If a terrible thing has occurred. It throws a new exception. It doesn't finish the method after that. It doesn't go on to finish the work or do anything else. In that method, the sequence of execution jumps up to the previous slide, which was like this to the do that method. It pops out as an exception and because it's in the try block, then it goes on to the catch block of that try catch blood, Okay, and we call that unwinding the stack. So it's like if a called be called C and then see throws an exception, it pops back up to B. If B throws an exception, it pops back up to a etcetera all the way at the top. Now you don't have to catch exceptions. If you don't catch it, it propagates up to your caller. So if a calls B call see and you don't catch it, then it's gonna pop up to be and then pop up to and keep going all the way back up. So here we are with this. That and the other again do. That throws an exception, But I'm in a lazy function here, and this lazy function doesn't actually have a try. Catch block. So now lazy function is going to admit this exception is gonna throw it up to its caller. All right, so whoever called this function my lazy function now has the burden of dealing with the exception. And of course, they don't have to deal with it either. They can let their calling method happens. So what happens if nobody wants to catch it? It's a hot potato. It goes all the way up. Well, if it reaches the top of the call stack and actually kills the thread that started this operation, right? So if there's no catch block anywhere, it goes all the way up. Eventually in job, everything starts with the thread, and that thread dies. If it's the main thread. So if the exception escapes the main method on the main threat, then the whole JBM will terminate. So, for example, for the class project we've been working on, we have a single threaded application that starts with the main threat in the main method. If one of our methods, through an exception and we didn't catch it anywhere, our program would just crash, it would end okay, Now there are some subtleties about this when you're doing multi threaded programming that let's leave that for part three of the class. All right, so the other part of Try Catch finally is finally so the finally block is a block of code that you want always to execute, and that executes, no matter whether it's a neck section or not. So in the case that there is no exception, this little programming construct her will go like this. It will execute all the statements in the try block. It will do this, do that, do the other, and then it will jump to the finally block and do the important task. All right, And then after that, of course, it continues down the method to the next line. If there is an exception and let's say again, it's do that, that's emitting the exception. You say, Do this. You start on, do that. It throws an exception. You skip, do the other, and you go to the catch block and you're gonna run cleanup from error. So you execute all the methods in the catch block and then you go on and execute all the code that's in the finally block. Okay, so the finally blocked gets executed whether or not you have an exception or not. And in fact, you see weird things like the catch block can actually throw exceptions. And even if the catch block throws an exception, so there's there's an exception in the try block, which sends you to the catch block. The cash block throws an exception. The finally blocks still executes. Okay? And actually, you don't even need a catch. You can just have a try finally, and it's very similar with there's no exception. Same execution sequence. You do everything in the try block, and then you do everything in the finally block. If there is an exception again, you start in the try block. You skip all the statements that come after the exception got thrown in this case. Then you go on to the finally block and you execute all the code in the finally buck. But then, in this case, the exception was never handled. There was never it was never caught, so it propagates up to the caller in this case to keep. We'll keep going up the stack until it finds a catch block that can handle it. Okay, we use it. This is an interesting thing to be aware of in Java. We always talk about throwing exceptions and catching exceptions. But it's actually not really exceptions that the special class that I talked about in the first light is called Throw a Ball, which makes a lot of sense. Throw a ball, are anything that that subclass of terrible is an object that can be thrown and caught. Okay, exceptions air just one subclass of throw a ball. The other sub classes called errors. Errors are generally nasty things that the JV M, the Java virtual machine is having some terrible issue that it's not gonna be able to recover from, and your program needs to be shut down. Generally, exceptions are more like the normal kind of day to day. Oh, I was reading a file on the contents are corrupt or something like that. So even though we often say, Oh, yeah, we used try catch blocks for exceptions. Actually, they can be used for any throw a ball, okay? And so now that we started to see this exception hierarchy, uh, let's say more properly. The throw a ball hierarchy Now we can start talking about the types that we use in the catch block so you can create a catch block that catches throw a ball that will catch any kind of object that's thrown because only throw balls can be thrown, of course. And but you could do something like this and then the same try catch block. But you've changed the type that you're catching. Two exception, and now it will catch exceptions. But it won't catch errors or there some classes, and it won't catch. Like if someone created an actual instance of throw belonged through, that this would not catch it either. It would only catch exceptions and, uh, sub classes of exception. All right, so that lets us do things like this. Now I have, ah, some dangerous operation that's throwing lots of different types of it of exceptions. I can catch them separately. I can catch the illegal argument exception first and then do whatever my cleanup is or I can catch the end of file exception and deal with that the compiler will not righteous. It's the runtime will match the type of exception thrown against the catch block. And if if the exception object is a sign able to this kind of reference polymorphic Lee. Then it will execute the first matching catch block. So, in other words, if the exception is an illegal argument exception or a subclass of illegal argument exception that will match the first block. Otherwise it skips the next to the next to the next catch block. If there are no catch blocks, then it bubbles up to the calling function. Now this kind of syntax is really useful if you're going to handle the different exceptions in different ways. But a lot of times, as we see here, the cleanup codes exactly the same for all the different types that you wanted to catch. And so for that we have this new Syntex called Multi Catch, where you put a single bar for a logical or and we're saying you can catch illegal argument exception or into file exception and then run cleanup. So if this is the kind of requirement you have this in Texas nice and of course you can do more than two. You can say illegal arm exception or U F exception or no point exception or, you know, whatever the exceptions are that you think you need to catch here. Any other exception will skip. This strike will skip this catch block and be thrown up to the calling function. Okay, now, one thing we haven't really talked too much about yet is dealing with the exception object . So when you when you enter the catch block, the exception is given to you as a as a reference E here because I have set catch Exception e. And it's just an object like any other objects so you can call methods on it. For example, throw balls all have a method called print stack trace, and it will print out like what the call stack is at the moment the exception was created, and you can also do something called Re throwing the exception where you just say, OK, throw e, I'm going to throw it again. So even though you've caught the exception, which which means that the virtual machine considers that exception handled like okay, it's done, somebody handled it. You can throw it again, which kind of active reactivates it, and now he will go up to the calling function, and they're gonna have to have a catch, catch block somewhere to catch this. All right, so that's a very interesting thing. So a lot of times, people do this for logging, so I'm going to catch the exception. I'm like, just like here. I'm gonna print the stack trace. I'm going to write something that longs. And then But actually, at this point, I don't really know how to recover from this. I'm just gonna throw it back up and let somebody else deal with it, okay? There's some other syntax with try catch the more events in text. So let's take this idea of a resource. And here I'm saying I'm gonna open a resource, and it could be something like a file or a database connection or any anything like that. Um, Just to be clear, there is no class called a resource in the jade in the Java sdk. So I kind of made that class name up, but, uh, let's just take it is something like this that that can be open like a file could be open. You can read, write it, and then you can close it, right? So I try using that resource, whatever it is. Uh, and let's say I'm reading and writing to it and I have a catch block just in case something is something goes wrong. But when I'm done, I definitely want to close it right. If I don't close my files, if I don't close my sockets, if I don't close my database connections, I'm gonna end up with the resource leak and probably crash my program. So I want to have a close statement there in the finally blood. Now, this isn't so bad, but a lot of these methods, like when you're closing certain kinds of resource, is and job, the clothes method actually throws exceptions as well. And so you have try catch blocks inside the finally block, which really starts to become kind of maddening. And so now we have this new way of dealing with it. So we have a try block and a trite statement. And within the Forenza of the try keyword we can create, the reaper can open the resource. So we say resource R equals open some resource, and we conduce this if the if the resource implements the interface job without laying that auto close herbal. Okay. And what that that interface if you go Look at it just has a single method on it called close. But what this guarantees you, then is it basically generates a finally block for you and then make sure that these research that that resource is closed properly, whether there's an exception or not. All right, so this is really nice. It's a lot cleaner syntax, a lot more compact than the one on the previous line. Catch block here would be optional if you want to catch the exception. If not, the exception will propagate up. OK, this is called Try With Resource is. So if you go to look at look this up to look into it a little bit more, you can just, you know, search job. A try with three sources, and I'll take you right to some pages that explain in great detail how this works. All right, let's get into the exception hierarchy here. This So this is a small fraction of the exceptions that come with Java. Remember we had we had throw balls, and underneath Roble was exception and errors. So we're just looking at the exception side of the house right now, and on the left hand side, you see things like interrupted exception, which which has to do with multi threading and, uh, concurrent programming. We see Iot exception, which has to do with any kind of input output, as it says, files, database connections, etcetera. This is probably the exception you're going to run into the most because it's all over the place and underneath Io exception, it comes with its own menagerie of sub classes, and a couple of them are malformed. Your L Exception file not found exception, and it goes on and on and on. On end of file exception, we saw that one a little bit earlier. On the right hand side are runtime exceptions, and runtime exception is a special thing in Java. It is the root of the unchecked exceptions, and we'll talk about what that means in just a second. But two of the more common runtime exceptions are the no pointer exception, everybody's bane and the illegal argument exception, which is a useful thing. Teoh for ah, function is signify Hey, you passed me an argument I don't like. I'm throwing it back at you, Alright. And just to be clear, there are dozens and dozens and dozens of exceptions in the job STK so you can go look at them, but it's it's kind of mind boggling. So these are some of the ones that you might run into more commonly. But there definitely are many, many others. All right, let's talk about this concept of checked versus unchecked exceptions, because this is really important. So with a checked exception, you have to either catch it or you have to declare, I'll show you what that means in just a second, whereas unchecked exceptions that extend runtime exception or not subject to this restriction. So all exceptions are checked unless they extend runtime exception. So what? I mean here. So let's say I have ah method here, do work and it's calling that troublesome method again called Do that right and we know that Do that throws an exception here. I'm catching Io exception, but, uh, so here I have a method that throws an exception. I'm catching it, and this is one way of dealing with the checked exception. Just handle it right? So that's one thing. The other option is to declare it. So what does that mean? We haven't seen that yet That means you add it to the method signature so I could change that first block a code into the second block of code this do work method, and then I just right there throws. I am exception. So that signifies to the people who call this method. Hey, you're gonna have to handle Io exception. Or if you don't handle it, you've got to declare it right. And so this way the compiler can check that everybody's properly handling their exceptions . By the way, I'm only showing one exception here, but that could be multiple exceptions. You could say throws Io exception comma and to file exception comma, malformed your L exception comma as many as you like. So why do we have these checked exceptions? That's kind of interesting, and there's a little bit of history here. So C language programming, which was, you know, the big thing in the eighties and most of the nineties. The way error handling was done then, or air signaling, I should say, was by return coats. So you call a function and it returns an integer if it zero everything went fine. If it's non zero, that's an error code. And so Every time you call the function, you're supposed to check the return value. And if it's non zero, do something interesting. It was very, very difficult to read to write, and it was very, very easy to forget. Teoh, check those air coats. And so when Java came out, they had this idea. Let's use the compiler to force programmers to handle. Exceptions were changing from ever return codes. Teoh actually an exception, which is something that can be thrown sort of around the return value of the function. And everybody thought, Wow, what a great idea. Now we're never we're gonna cut down on all our bugs. We will have programs crashing all the time. This is gonna be great. But the way it worked out was not so great. And most people don't like checked exceptions anymore and kind of consider the experiment of failure. Why is that? Why not checked? Exception seems kind of like a good argument, right? The problem that comes out in practices that exceptions that are often thrown at very low levels of the code. So maybe you have some code that's reading a file, and then it goes to read the next you know, buffer, birth worth of file Onda file has been deleted or its corrupt. Or somehow I can't get it or the sockets been closed or something like that. So now ahead needs to throw an exception. Well, it doesn't know how what to do about their it's it's low level. Reusable code has no idea what the context of reading this file or socket is, so it doesn't know what to do to recover from the error. So the exception is to be thrown up the call stack until it gets very close to the top level. And that's usually where you have enough context to understand. Oh, here's what I need to dio I need to do this in order to recover from this error. And generally people find like the answer. A lot of the times is either will retry or just aboard and return. Ah, error signal to the client. For example, if if your server is serving Web services, you return HDP 500 you say Yeah, it broke. Sorry, Couldn't do it and then put the claim. Handle it right. If this is your option, if this is your ah what you need to do to handle the exception. Well, that can be written as generic could. We don't need dedicated try catch blocks all over the place doing the same thing everywhere , right? And this makes it really painful because let's say you're working on the code that reads a file and you realize, Oh, I need to throw a different checked exception and it's 10 levels down from your top level code. Now you've got to go through 10 levels of code and and throws clauses everywhere until you finally get up to the level where the exception can be handled. And if those methods air called by other methods in your code, then they all need throws, clauses that propagate all the way up to the top level. And pretty soon you seem to spend half your day adding throws clauses to like method signatures that you don't even know anything about. You just like throws, throws, throw throws. And it turned out that the checked exception experiment is worth is more trouble than it's worth right These days, it certainly seems to me that most people just make their exceptions unchecked. In other words, they extend runtime exception and then they have some top level, catch all error handler that's generic and does the same thing. For all exceptions, usually abort were retried, so checked exceptions were a great idea. It was a wonderful experiment. For a couple of years, people were so excited. But after a few years of struggling with these pain points, people looked at it and said, You know what? Actually, and maybe this isn't the best idea. Let's try it this other way. And that seems to be a much more robust way of dealing with things. All right, so that's exceptions. Let's just look a little bit at errors. If you remember, errors are the other side of the throw bowl. Three other throw a ball child. Let's say that and you can have things these air Generally, things that are indicate something terrible's gone wrong with your run time environment. So a linkage era that indicates, like to classes that are supposed to talk to each other, the the virtual machine couldn't link there could together properly, all right, so that means you're runtime images. Garbage now needs to be discarded, right? Or, like other virtual machine areas, like out of memory error. You tried to create another player and there's no memory left in your computer. All right? Too bad. Stack overflow. Okay, so you got yourself into an infinite loop and you exhausted the resources of the VM again. So these errors tend to be nasty things that really, once you had an error, the depth of the general sense is like you can't recover from this. Like, you have no idea what state your code is in right now. All right? And what, Just like exceptions, there's a zillion of these in the job. STK go. You can go look at them and kind of marvel at the number of errors and hope that you never see one. Okay, let me give you some advice. Use coarse grained try blocks. Okay, If you have five methods in a row that emit exceptions, don't do five. Try catch blocks. That's really difficult to read. And it's not really the way try Catch was designed. The try block is supposed to hold the entire set of, ah, problematic code and then you catch the errors. After that, don't use exceptions. Surface flow control. Let's say you're let's say you're signing somebody up for a club, but you have to be 18. Don't invoke the method and then throw ah, underage exception If the person is too young, like you should actually be checking those business rules ahead of time instead of you and then doing something different rather than try to execute your operation and blow up at the last minute. So if you can avoid exceptions, you should avoid them, like with if statements, rather than throw statements of one of the reasons. So there's two reasons for this. One is exceptions are difficult. You don't see them in the program. They're difficult to trace, so an exception could come bubbling up from some method. 10 levels down and suddenly your code is broken and you don't even see where that's coming from. And then the second thing is exceptions. There really slow that JBM is optimized for non exceptional execution, and if your code throws lots of exceptions, it's going to get really slow really fast and don't ever catch exception silently. In other words, don't write empty catch blocks. OK, everyone like from the early days of job, but we've all been bitten by this where we've spent hours or days debugging a program only to find an empty catch block that was hiding an exception that was being thrown at the very least, right? The error to the logs. Okay, please. And if you don't know what to do with the error, just let it bubble up to the caller and let them handle it. Don't ever suppress it like at a deep level in the code. That's just terrible thing. If you don't want your co workers to come after you with baseball bats don't do this. Okay, okay. One more technique. I'd like to point out to you that I don't see a lot of people using, but I find it to be a really cool technique is exceptions as data holders. So let's say you're trying to look up a user and you can't find them in whatever the database or whatever, and you're gonna throw a user not found exception. Okay, that's great. Um, but you can add things to the exception because it's just a class that you're writing. It just extends, exception, right? Or maybe runtime Exception. If you're following that advice, you can put the user I d into the exception, you know, create a constructor that takes the user I d And then you save it, and then you come back together. That returns the user I d. And so you basically are wrapping up the context of the error. And you could put a lot more data in here too. You could put all kinds of stuff in there. The database you were accessing the time of day, the sequel Query reason. I mean, whatever I table, you were query against whatever. And then you wrap all that up in the exception object, and then you throw it right, and then somewhere upstream at the short to top of the program, some top level code is going to catch this object, and it's gonna have all this good data in it. All this context about what was going on when this thing blew up right? Which is very difficult to discern if you're in the top level code and suddenly some user not found exception comes up. You're like, what was going on here? What user who wasn't found where, like, what are you talking about? Right, so you can actually add that data as attributes to these objects and just put getters on the on the exception. And then you can basically, you know, token eyes your context and send it up to the to the catch block. That's handling this error. And it can use at least a king. Is it for logging, right? So you get the context singer logs. Or maybe it can use the data to understand. Oh, if I don't find the user in this database, maybe I'll check this other data store and see if I can find them there. This is a really interesting technique that you shouldn't neglect. So many people think of Exit the Let's put it this way. The base. Throw a ball class. You can pass in a string as a message, right? So people just tended to ape that behavior everywhere. But you can make very rich exception objects. Okay, good enough for exceptions. Let's go to the exercise and this is gonna be a very simple one. We're just gonna take the method we wrote in the last chapter about looking up players from a map. And if we can't find the player, we're gonna throw an exception. All right, so you see the details in the instructions. You know the drill. Pause the video now and when you're done, come back and we'll do it together. Okay, welcome back. Hopefully, that wasn't too difficult for you. Let's go take a look at our exception worksheet. So right now what we're doing when we call that method to fetch a player by color, we just returned. Whatever comes out of the map, which means that if we pass in a misspelled color or some color that we don't have a player for, we just re certain. No, but let's do it a little differently, just a za way to get used to exceptions. Let's change that to throw exception. So we're going to create a new class player, not found exception and inherit that from exception. We're going to check the constructors from separate class. So let's go over there and open up our sorry game and this isn't specific to card. So I'm going to put it in the top level package found section. If you haven't figured this part out the way you do a super class in job, as you say exception. All right. And we're gonna use make sure you get the right package, java dot lying. We're gonna use the checked acceptance just into little street. Those concepts Constructors from Super class. That's a good thing, because look what's gonna happen. You get all these constructors now. I hate these to do's so excuse me while I take them out. But here's something we didn't talk about in the slide in the slides. Sometimes you get an exception, and you're going to change the exception class. So let's say you're clearing in the database and you get a sequel exception, like your malformed sequel exception or something. And I want to change that to player, not found exception. I can create a player, not found exception and and add a throw a bill as the cause. So, in other words, the sequel exception is the root cause of the problem. But I don't want sequel exception to bubble up to the top level code. That's very difficult for anyone to understand. What actually happened was I couldn't found the player. The reason was SQL exception. All right, so these are the constructors that are inherited from exception. So let's go back and say room of the two DUIs in the sorry game. Get players by color if the players know Throw an exception. Okay. With some interesting, uh, message here. So let's go back to our sorry game. And where is the player by? There it is. Get players my color. Okay, so we're gonna want to test the return of this call for null. And we can't actually do that, because it's all one light. So let me show you another little re factoring trick. I'm going to re factor this and let me use the menu. Although I don't usually use the menu extracted. Local variable Holt shift. Ellis, this is the short cut in eclipse. I'm gonna call the variable player, and now I've got myself a little variable. Okay, So if that's no, If a player is no, bring throw a new player, not found exception. I want to put a string in it and say no player with color. And then at the color that was put into the no percent into the method. Okay, so now we got a big red button there, and it says we don't have a throat. We don't have We didn't declare our throat. Okay, so remember, if you're throwing an exception. If there's an exception in the method, you need to throw his declaration. And when I hover over it, it eclipse tells me just that same thing you didn't handle. This exception is being thrown. It's not being handled. Maybe you'd like to add a throws declaration. Well, yes, I would. And it gives you, ah, option to say the most specific exception. Or you could throw exception or throw throw a ball if your method is throwing a lot. But let's not worry too much here. We'll just do that. Okay, so this is how you would throw an exception in your coat if you come across some kind of erroneous condition Now we've created another problem down below, right? We're getting this, So let's see what they say here. There's an error in the main method. Now. One thing we could do is just as it says here, add another throws decoration so I could do this right and just say, you know what? I'm not gonna handle it. Let it escape main and whips jump up there. And of course, as we talked about in the slides, if you do have a player not found exception. And it comes out of the main method. That's the end of your program. Boom. Crash. Right. So maybe I don't want to do that. I think that out. And in fact, I want to do I want to do a try. Catcher. So this is the method that can fail get player by color. And if it fails, I'm not gonna have a Greenpeace the green player to talk to. So this line is gonna fail to. So I might as well put them both in the try block, right? This is the transaction, and I'm trying to do I have a surround with in eclipse, so I don't have to say I don't like to type that much. That puts it in a try catch block catches the, uh, the exception for me. Get rid of that to do. And while that's okay, Prince Stack traces violence. See, they they said, uh, print line E mess. OK, so looks, Let's actually look at this one first. So first of all, let's just see if we broke anything. Run as job Oops, run as Java application and we get this nice little output. Remember, we're getting player green at the end and printing out their locations. The player green ended up on square 32 it says Player piece one of player green, his own square to 32. Now that's Let's look at the, uh, let's change this to be a color that we don't have. All right? And then run the program again. Boom. Now we get this factory so we get when you do print stack trace, you get the name of the exception game. Put that player not found to the full equality class name. We get the message that we put into the exception when we created no player with color grin . Right. And then we get the stack trace here, which says, Okay, this happened net line 65 in sorry game, which was called by Line 88 sorry. Game. Right. So here's lying. 98. Line 65 is up above where we through the exception. All right, so the exceptions will tell you exactly where they were thrown in. Who called you to? Who was calling that method to get there? So that's really super. Um e that Prince stack trace just printed out to standard output, so you might want to do something a little bit different. Um, in this case, I'm putting it out to standard out again. But I can say ee dot get message, right? And then we run it. In that case, we just get the message on Lee. We don't get any information about the stack trace or the, um, the exception class. I can t v dot to string, which a little bit better. It shows the exact exception that was thrown. And then any message that was there and, of course, the prince stack trace will show you the entire stack trees. All right, let's see if they wanted anything else works. Nope, That's all they asked us for. So this is how you would use exception. So just to review when you're doing an operation that can encounter an error, you create an exception object, and you can add data to it, or messages or things like that. And then you throw it right, and usually the you could've put player on it like I'm sorry, created the exception of different line, assigned it to a variable and then threw it. Um, but normally people do like this throw knew something. Rather there's no real reason to have two lines there. And then when you're doing a try catch block, you put the problematic code, which is both of these lines, right, Because the second line depends on the first. So I'm gonna try this block a code. If it fails, I'm gonna do this right. I'm gonna catch 7. 07 Enums: Okay. Welcome, everybody to chapter seven. We're gonna talk about the NMS, which is a way of providing restricted choices for variable values. So in, um, Zahra, fairly simple construct. We have unjam a java when we want to provide a limited set of values. So you could think of something like a set of colors or the week days of which, you know, their seven week days, right? And so you don't want to provide an unlimited set of values. So in this chapter will take a look at the numbers in the surrounding infrastructure in terms air. Fairly simple. So this is going to be somewhat of a shorter chapter. All right, The syntax for Denham's looks like this. So instead of saying public class color, you say public Inam color. So Inam is a key word in Java. And, of course, in, um is a short for enumeration, just so that would be the more formal term. But in Java there cold, Denham's in here. I'm created in, um called color, and I provided four values Red, green, yellow, blue And again, this is with reference to our class project where we have the sorry game. These are the four colors used in Sorry, And once you've done this, color becomes another class that you can use as a type for variable. So in the player class, instead of having a color as a string, you could have the color as a type capital, see color, the Denham. And now it can only take on one of those four values. You couldn't assign color to be black here or white or ah, purple or something like that, because those air not values that are in the okay, bye vintage of being. Ah, in, um, you get a bunch of special methods and capabilities. So let's take a look at what they are. First of all, to reference the values of the, um they're basically static variables. The compiler does some special magic when it seized the e numb keyword and those values that you type in there become the names of static variables. So here I'm defining a nuisance variable called color, and I'm signing it to color dot red. So that hasn't now the reading them everything, um, has a name method. It's not cold. Get name. It's just called name, which is sometimes annoying. Um, and that will turn the name of the e them into a string. So our color hair is colored out red R E d. All caps so that will return the string r E D. All caps now. Denham's like every object, also have a two string method. By default. It just calls the name method and returns the exact same string. But like with any to string method, you can override to string in your venom definition and give it something more useful to you. If if that's what you want, Denham's also return in order. Nell's. This is actually let's go back to the previous slide. It's kind of interesting, given this definition of the color in em. The orginal for red zero. The ordeal for green is one. The orginal for yellow is too in. The order for Blue is three, so that means so they're ordered in the name that you define them, but which is kind of an interesting in handy thing. But it also means that if someone comes later on and reorganizes, the the the order of the less like let's say they want to make it alphabetic here, and they want to put blue first, and then what would be next? Green. It's gonna change all the orginal. So if your code is relying on the Ordell's, that could really mess it up. So be very careful with that. The compiler also generates a static method called value of for every Annum, where you can pass in a string, and it turns it into the E numb if it finds the one with the with the matching names. So this is basically the exact opposite of the name method that we saw about their name, takes it and turns it into string. Value of Texas String turns it into a Nina All right within arm's. There's also some special collections that come with it, since they are a limited set of items. First of all, every annum again has a static method generated called values, which returns a standard array of the game's. So you get an array, in this case of colors, and you can, you know, loop over the raid just like any other array. It's when you get into the sets where kind of gets interesting. There's a special class called Denham set, and you can say in, um set dot all of and then provide a class object for, ah, one of the items that you have and this will return a set of colors now what's interesting about Inam said. First of all, these factory methods, like all Love and then the next line will see another one. They provide ways of generating the set, so you want to do it all by hand, which is kind of useful. But the other thing internally, they use like a just a bit to represent the genome because they know that there's a limited number and they know how they're defined. Um, they're represented extremely efficiently in memory now that may or may not be of interest to you, because if there's only like in this case four colors, we don't really need to worry too much about representing them efficiently. There's only four right, so it's not gonna take up much memory or used much CPM, but in uM said also has other factory methods, one of them being of where you can give a specific subset of the the NMS values that you want to put into the set. And there's also some other factory methods for in upset like a nem tea set of colors and things like that. So, uh, if you're working with the numbers and you need collections of them, it's worth looking at the Emam set Java duck just to see all the capabilities that it has. And there's also a special map called in a map, which has this kind of bizarre constructor syntax. Um, but that is four maps that use Denham's as keys, and again it uses that super efficient representation for the set of colors inside the INA met. Okay, another great property of enemies is that the compiler ensures that these air Singleton's right, so there's only one instance of each. So that means the quality of reference always works, so you can either do if you have to be names of color. C. One C. Two. You can either do see one equal equal c two or you could do C one dot equal. See to those air guaranteed to work out the same, so that reduces some of the complexity around equality. Okay, Denham's have a little bit of special kung fu when they work with switch statement, so if you're switching on a variable that isn't in. Um, first of all, you can represent the cases without the class name, right? Thank goodness the compiler can infer. Okay, you're passing in a color. That's part of the color in, um, you don't have to say color dot red color dot green. So that's nice. Also, the compiler, of course, can look at the name and say, Oh, there's four een, um, variables in color, your only handling Two cases here and it doesn't throw an error, but it generates a warning and it says, Hey, you, there's cases here you haven't handled so either handle blue and yellow or put a default section in your switch statement. All right, writing color dot red and color dot green is annoying and makes the the code ugly to read. So just be aware you can use static imports for in ums and this is very common in import static color that star. And now you can just say red, yellow, green, blue and it will differ prints that from the color, you know. Okay, a little bit more advanced usage of Denham. So Denham's air just classes, after all, with the little bit of special syntax and a little bit of special handling from the compiler. So you can add your own the attributes and methods. So, for example, here in this created in him called size and I've added a private in score and I've added to get her for it. Right. So these are just standard instance, attributes and methods like we've been seeing since the beginning of part one and then a standard looking constructor that takes the value for score and initialize is this instances value of score? Right now, one thing here that's different is the private, uh, access modifier on the constructor. You can't make a public constructor for anin. Um, because other classes can't create Denham's. You can't be halfway through the, um code and some other class going new size of something like that. That doesn't work right so that the constructors are private. And now what you see at the top is those air. Basically, the constructor calls Okay, so you see small of one medium to large of three. So the large Denham size will have the score set to three. And if you look at like that 1st 1 where it's his small Perrin one Perrin. Basically, that is a shorthand for what you see in the top left bubble, their size small equals new size of one. Right? You could make that if you weren't writing an email. Sorry, Denham. What you would do is say public static, final size, small equals new size of one, right? You just type that all out as static variables if you want this to be, um, enumerated set. But Denham's basically just give you that shorthand syntax for the constructors and all the methods that we've reviewed in the previous slides get automatically generated by the compiler. So you don't have to write any of that stuff. Okay? A potentially really powerful technique that I don't see used very often is providing unique implementations of methods for a name. Um, so here, I've got an Emam called Case. Uh, and I I've put in a abstract method public aps X during transform stream. Okay, so that means every Denham class that gets created needs to override transform, or else it would be an abstract object, right? Which we which we can in Stan she ate. So when you define the Denham's here, I've got two cases upper case and lower case, you have to provide an implementation of the transform method, which you do by this kind of awkward syntax here with lots of curly braces. But you see the upper case, uh uh hm uses the string dot to upper case in the lower casing Amuses string, Got to lower case. And now you can access these methods. By code like this, you can say string s equals uppercase dot transform an impasse in some string that will obviously return H i in upper case. So this is a very interesting way you can implement, like varying behaviors with different Denham's. And if you're familiar with design patterns like this state pattern or the strategy pattern , this is a very interesting way to implement those patterns. Even if this in taxes a little bit, you know, awkward to look at. Okay, that's pretty much wraps it up for in NMS. We're gonna go do our exercise now. And the obvious thing we're gonna do is exactly what we talked about in the slides. Replace the color being a string with the color being angina. So usual thing. Go ahead and pause. Now, go. Do your, uh class. And when you're done, come on back and I will work it with you. Okay. Well, welcome back. Hopefully you got through that exercise without a lot of trouble. Let's go take a look at our exercise sheet here and not much here. In the explanation. We're just replacing this string of color with a Nina. So it says, go to the, uh, game package and created color anin unnamed color and add red, yellow, red, green, yellow, blue. So it's good. Do that. Here's our sorry game. Let's hope in the set. All right? New and notice that eclipse there is an Emam. It would work just as well if you created to class and then changed class to enough right that these are just little wizards to get you started and they wouldn't have read. Green looks yellow and blue. Okay, great. That was easy. Right in the player class changed the type of the attributes to color and then fix the broken constructor. All right, so the player class here we have a color. That is a string. Now we're gonna have a color. That's a color that's a little bit nicer code, right. And now Of course, we see this breaking because the color being passed in is a string. Well, no, we actually want to pass in a real color. Okay, great. So now we fixed the players, constructor. Now there's an error in sorry game class. When we create the players, we have to use colors rather than strings. Okay, so that's kind of obvious, right? So we go appear to where the red bar is, and it says, Hey, you're trying to create a color. You're trying to create a player with the string, but we just change that constructor to use color. So this needs to be color right? Which now moves the error appear rights that were just tracing down these errors and, uh, the create player. Now we can't call with, uh, the strings anymore. We have to change them too. Denham's. And so if you remember which method will use here, that's the value of and we pass it now. In this case, we have to say, uh, upper case, right, because otherwise it won't, uh, it won't match the enough. And then this one's green color dot value of green. All right. Great. And you see the error here. But let's just keep with our little little book here. And it says now the player by color, after being needs to change its type. Right? So here we are trying to put, um colors into the players into the map here with a color as, ah kee. But the colors now color and what we define up above was players by color had a string, so we need to change that to color. Now, of course, if you wanted to, we could changes to anin. Um, map, right? And if I remember the syntax correctly, we go like this color duck like this I don't think was in the Bring that and then that works, too. So if you wanted to take advantage of that hyper efficient implementation, you could do that. But now the, uh, the creek player method is fine again. So be cleared those errors. And now what else? While it says Okay, yeah, they remember we wrote this thing called get player by color when we were doing collections and actually worked on that method last Chapter two, with exceptions, umm, where the Okay, it's passing in a string here and here. We're only getting a warning here saying, Yeah, this seems wrong because this map is keyed by color in, um and you're passing in a string. That's probably not gonna work, right? And they're right. I'm gonna pass in a color. Okay, so now that's all happy. And of course, now the main method is mad because we're passing in a string here. Remember, we were practicing passing in non existing colors here to get the exception, we've now taken that possibility away. So we say color value of green. Or, you know, if we didn't want to do it like that, we could say color dot green, right? And that's probably actually that's probably better. I was showing the value of method here, but it's actually safer to just do this. So then we do the same thing or so no, you can't actually pass in a bad color to get player by color because it only takes color in NMS in the NMS. They're all the ones that are that are allowed. Um although I guess I guess I would say in in our game here, we've only created two players. We didn't create one with each color of the of the That's in the name. We don't have a blue or yellow player, so it is still possible to pass in blue here and get the acceptance. So we haven't completely gotten rid of our code from before, so let's try running that. Let's look at our okay, which creates the main. Okay, says Run the game. See that? It works, right? We have not missed anything and run the application and boom. And then we still get the player, not found exception. No player with color blue. Now one thing to notice is that all the player names now are all caps, right? And before they were lower case. So if you wanted to fix that, how would you do it? Anybody have an idea? Obviously, I can't hear your answers, But if you were falling along, you realize you can put a two string method in your in. Um, right now, by default, it's gonna return name, which is not what we want. But let's say we just want to go back to a lower case, would return Name that to lower case right now. If we run the simulation again, we see everything's gone back to lower case if you wanted to capitalize them, which will probably be the prettiest thing you could do. You have Teoh use a utility library that knows how to do capitalization. There's no capitalized method on string, unfortunately, but there are you there are utilities out there like, uh uh, the patchy Commons Library's that will have methods like capitalizes strength. All right, so we did our little extra credit here. Number 10. So back to the slides. Hopefully, that wasn't too hard for you that the NMS are fairly simple and fairly straightforward. So again, just summarizing, uh, Denham's let us have a limited set of pre defined values so that we can't be passing in random strings into a method where only a certain number of strings are actually valid. Right? Um and then on top of that, because they are objects, you can add your own data and your own methods in your own method. Implementations to Yuri names. And that can be very powerful programming technique to keep track of a limited set of options of upsets of data or algorithms or something like that. So, uh, in terms of really handy, okay, in the next chapter. We're going to kind of change the flavor of this part of the course now because what we've really seen most of the major language features, there will still be a couple come coming in along the way. But the rest of this part two of the overall course is going to be going through the class library that ships with the job sdk. And there are tens of thousands of these classes, so we're clearly not going to talk about them all. But there are certain things you just need to know about. As a programmer, I'm gonna try to take you through a tour of, uh, starting points to learn about things, but show you some of the more important classes and packages you need to understand and know about. And then some of it will be like a jumping off point for more exploration on your part. But in the next chapter, we're gonna start with that most basic package, the one that is imported into every class that you have the job of the outlying package. All right, we'll talk to you in the next chapter. 8. 08 JavaLang: OK, everyone. Hallo. And welcome back to Chapter eight, where we're gonna talk about the java dot lying package So java dot Laing is the core package. It's the one package that's automatically imported to all your classes. It's the package where the class object lives, which is the super class of all of your objects. So it's pretty core to the function of the job SdK. There's a lot of classes and interfaces and exceptions in this package. We're not going toe by any stretch. Look at all. Then there's dozens and dozens. I would encourage you at some point to just pull up the job, a dock in, browse through it and and read the short descriptions of each thing and and understand basically what's in there. But what I'll take you through in this chapter of some of the more frequently encountered once that that you'll need to know about. All right, we're gonna start with comparable. So Java has this small little tiny subsystem in it for sorting objects. So Java has this concept that some objects have what you might call a natural sort order. So, for example, strings you sort them in alphabetical order right. A B C D E f g a comes first becomes next. He comes next. Or numbers. 12345 Right. They all have a natural order. So but suppose you write your own class, let's say person or something like that, or die side on or whatever and you want to sort those and you feel that there's also a natural sort order for that class is Well, how do you teach that to the Java class libraries like, how do you tell a list to sort using You know what they call the natural sort order? Well, you do that by implementing the comparable interface. Comparable has a single method called compared to where you pass in the other object that you're comparing to And then you return an imager to say whether it's bigger or smaller. Let's look in detail here, uh, taken two strings aa a BBB. Okay, so when you sort those a comes first become second. So in this sense, a is quote unquote smaller and B is bigger, right? So if I take the smaller string A and I compared to the bigger one like that will return minus one and you can do this, uh, yourself strings the class Java lang string that exists in the job and outlying package already implements comparable. So that's why we already have this method available to us. And so if you say a smaller compared to bigger, you get a minus one, which kind of minus one kind of means, you know, the order is correct, like you got the smaller ones come first. The bigger ones come later. It's a sending order, right? So if you do bigger compared to smaller, it returns positive one which kind of means a little bit has the meaning of, like, flip the order here. If you compare on object to itself, it returns zero. All right, so how is this used to do? Sorting well, the algorithms that Java uses to sort lis rely on this value to tell them whether the order is okay the way it is, you know, minus one or whether it needs to be flipped with the plus one or whether they've actually got two instances of the same object. And it doesn't matter which ones in front cause of the same. Let's look at how you implement comparable So here's a class person. Uh, and the person has an age, which is an integer. Okay, So how do you do this? You say you're going to implement the interface, and then you look at implementing the compared to method, and this is just returning this dot age minus other dot age, and it says just return a negative number of the current objects smaller returned a positive object. A positive number of the current object is larger, and in this case is not just going to return plus one in minus one. It's actually going to return. You know, the larger the age difference is, the bigger the number is gonna be, uh and that's fine. A lot of the algorithms don't care. A lot of them only care about the sign as it positive or negative. There are some algorithms that can take advantage of the larger, you know that they'll understand the difference between plus one and plus 20 and they can make bigger moves in their sorts. But most of them don't. Okay, But when you do this, when you create a class like this and you implement comparable, you're basically telling java. Okay, people naturally sort from youngest to oldest. That's the standard way of doing it. How would you utilize that? Well, let's say you had a list of persons Member list is a list is ordered. A set is not. So you need to do this with a list and then you can just run collections that sort and pass in the list. And when you pass a list to collections that sort which we've done in our project already, it will use this quote unquote natural sort order, which is defined by comparable now. OK, that's fine. So what if you say the natural sort order of people as youngest to oldest? But there's some other. There's a specialized these case where you want to sort them by a different attributes. Or maybe you want to sort them from older to younger, like how do how do you parameter rise it? Cause here you've actually coded the sorting algorithm into the class itself, and you can't really swap it out and use different algorithms at different times. So for that Java has comparator, so this is basically an externalized or configurable sort order, and just to come clean, this doesn't live in job it outlying. It's in job with that, you tell. All right, but Comparator looks almost the same. Except look at the compare meant that you compare one object to another. All right, so this is Ah ah, method that doesn't live like in your person class. It lives in a different class, and we'll look at that in a minute. But this is the way you use it. Let's suppose we create to people and we have a younger person who's 10 and an older person is 20 and then we create a comparator. And in this case, we're going to create one a descending age comparator. So in other words, is gonna sort by descending age. So when you use it, Okay, if you do younger toe older Well, no, that's the wrong order, right? We wanted to go to from older to younger descending age. So that returns a plus one when we say older to younger, that returns a negative one. And of course, if we do younger to younger, that will again return zero. So how would you implement this? So here's a case of implementing Comparator in this case. You again, you don't put it in the person class. This is a standalone interface for a standalone class that's basically like if you're familiar with design patterns, this is like a strategy pattern. It's like applicable algorithm. OK, so again you just implement the interface and then compile it will force you to override the compare method. That's fine. And in this case, your past two objects, the 1st 1 in the 2nd 1 And then you have to decide using whatever algorithm, whatever logic you want, how to return an integer that indicates, Is that the correct order? So if the first person should come before the second person, then you return a negative number. If they should be swapped, you'd return a positive number. If they're the same or it doesn't matter, there's no ah in this case that they have the same Eiji return. Zero. How would this be used? Well, in this case, you could use the collections class like we did before, but List actually has its own sort method, where you can pass in a comparator. And so in this case you can sort your list based on any criterion you want. By creating these comparator for example, if a person also had a string attributes for their name and, you know, a state attributes for their residents, Um, you could sort ascending, descending on all of those if you just create a bunch of Comparator. Okay, so that's sorting. Let's go on to the system class. So this is another really important one. And this is another one we've used already. Okay, um, all these attributes and methods here are underlined in our little UML rectangle. There underlined means static. Okay, everything on the system classes static, and it allows you to interface with the system. So we have a standard in standard out standard error. You know, those streams that you read and write to read from right to. And then again, system has MAWR methods than this, but these are some of the more important ones getting the current time. That would be the number of milliseconds from the epoch. January 1st, 1970 in UTC, uh, Nana Time, which is a nanosecond precision timer. But it doesn't actually equate. It's kind of like since the JV m started, it doesn't I can't be converted into a natural date like a calendar date, but If you need really precise timings between events, you can use that. Get property lousy Teoh to get what are called system properties. I'll show you that in a second. G C means garbage collect so you can ask this system to run the garbage collector. So if you think you've just create a lot of garbage, you want to free up some memory. You can call dot GC on system. And then there's an exit, which tells it to exit the jbm and you can pass the status code, which will be returned to whatever program called it at the command line. Zero means normal exit. Anything else means, uh, erroneous. So there's not much to the use of of the system class. You could get the current milliseconds from Epoch by going current time milles, and then you could print it out by using system that out. That print Lynn OK, but now you know we've done system it out that Kremlin many, many, many, many times, and now you see what it is. System is a class in java dot lang Out is a public attributes of the system class whose type is Prince Stream and Prince stream has a method called print Lynn, which stands, of course, were printed line, and you can pass strings to it and prints it out to the standard output. So if you did system dot er dot print Lynn, you'd be printing to standard error, which probably would also be the console unless you've redirected it somewhere. But if you've done any limits, you understand what I'm talking about. If not, don't worry about it. For now. Okay, let's talk about system properties of these air really important. This is a way of passing in data from the command line to the running program that in this data can be retrieved internally as the program's running and we use the command line parameter dash D to set system property. So here's here would be one. So John Jabba Dosh job. A dash CPI CPI means class path. So cp dot means current directory is the class paths of just there for completeness and then Dash D. My prop equals full. So these air key value pairs and the name here the key is my prop and the values full. You could keep adding on more. You could say Dashti prop two equals X dash d Prop three equals Why? Or something like that as many system properties as you like. And then at the end of the command line is the class that whose main method you're trying to run. And then inside your program, you can retrieve the value of this parameter by using system dot get property and you pass in the key. In this case, it was my prop. And then, of course, the variable value will get the value full F u l l. Because that's what you typed on the command line. So this is a common way of parameter rising, uh, coat, uh, programs. When they run with values from the command line to system properties very, very commonly is all right. The related classes run time. So this is an interface to the runtime environment like the jbm, And one of the key things that runtime is used for is if you want to launch an external process, so if you want, If you want your Java program tow, launch another program on your computer like by executing a command. This is the classy would use. I'm not going to go into the mechanics on that, you can look that up online. There's just a set of things you need to do. But that's the exact method. So you would pass in a command to that method you say execute exactly. And then you get back A javelin process object, which allows you to read the input streaming outputs. Dream of that, um, process, etcetera. There's also an exit method on runtime. So it's another way Toe killed the jbm Some, uh, methods that allow you to query the memory of the jbm You know how much is free? How much is what's the total memory that we've used? What's the maximum memory were allowed to use? It said. There's another GC method to do garbage collection, so there's some you know, overlap here with the system class, and then the last one is a static method called get runtime, which returns a runtime. So you've seen that before. What kind of pattern is that? If you remember Chapter three about statics, you'll recognize that as singleton pattern right now, they used a different method name Instead of saying get instance, they said get run time but is still Singleton panel and so using runtime again. Very straightforward. If I wanted to garbage collection garbage collect, I'd say, Get runtime dot gc if I wanted to, Then exit. Get run Time that exit zero. Nothing special there. Okay, job a doubling, that math. So this is where all the floating point math, utilities air gathered right again. These a rope static methods. And we have triggered a metric method sign co sign tangents. He can't Cosi can't all that stuff. I didn't put everything on this slide, of course, because it's just too much, uh, exponents and log a rhythm both natural and based. 10. I believe men and Max methods. I'm writing everything here just for doubles, but there's also a no overload for floats and for in sand for long etcetera, square root rounding a floating point number two, an integer or along, or something like that. And then there's a riend method on math, which returns a random off double floating point number between zero. What, all right, And so, using math, the math packages really easy. It's just static methods, and there's also a couple constants, one of which is pie. So, you know, Java has the exact well not the exact value, but a good close value apply for you that you can use in case you're doing some physics or engineering. Okay, Another interfaces run noble job by that lying that rentable. You'll see this one quite a bit. And this just recommend represents some kind of task that you're going to perform right, and this is often used with threads. And so it has a single method called run. No parameters, no return, and the way you would use it is like this. Let's say I want to create a class. That would be a task that prints the current time, and I can have my class implement run noble that I have to implement the run method. I just put some code in there, whatever I need to run. And then I can pass this to somebody who knows how to execute run nobles and no call to run method. So you see this one a lot, and it was built to work with threads. Although run nobles air used for all kinds of things now but job. When Java was released, it had multi threading, built in as a first class concept, and everybody was so excited because, uh, other languages didn't have that in kind of grafting multi threading libraries into, like, C was difficult and error prone and Java came out and said, Look, we have java dot lang dot threat like this is a threat of execution and it's a It's a top level concept, which is great. And, uh, so you look at the threat. There's one constructor that takes a run noble right, so you can pass your rentable in to the thread constructor and then look at the next two methods. Run or start, that will start the thread going, and it will run your rentable right. You can stop the thread. You can interrupt it. If it's taking too long, you can join it, which says, basically, wait until it's done and then continue your execution. So combining it with what we saw in the previous page with our rentable. This is how you would do that, you'd say New threat of new date printer, which was the class that we have in the previous played page. It's a run a ball and use a threat that start, and then that thread, that new threat that you just created will execute the code that's in the date printer. All right now, having said that, probably best. I mean, it's definitely best to avoid threads if you can. They're pretty low level. You really kind of have to be an expert to use them without busting things. And in part, three of this class will talk about the concurrency package that is in java dot You tell that has much higher level, much more robust building blocks and much more friendly notation and syntax to use if you need to write multi threaded programs. All right, now what we're talking about threats that may be interesting to talk about thread local. This is a map where the key is the current threat, right? It can only hold one value per thread. And so you see the methods on thread local like set and you pass in on object, right? The key implicitly is the current threat. And so when you say get it returns, the object if you see removing, obviously clears the storage for that thread. So this offer storage of data on a per threat basis and could be used something like this. Um, the very popular spring framework uses it in somewhat in this way. So I'm creating. Let's say I have a knob JEC that's called a transaction and every threat. And my server has its own transaction. So I create a threat, local named transactions. And then when I created transaction, I C. T equals new transaction. And then I said it into my transaction thread local, right? And then I go off and I do my transactional work and I come back when I'm done. Or maybe at some other place in the code. I need access to that transaction for the current thread, and I can just say transactions dot get and it will get the transaction that was stored up above by this threat, not by some other threat. Then I could commit transaction and remove it from the thread local or something like that . But this is a way to store data in a multi threaded environment that is particular to one thread. All right, and then last one is literal. This is an interesting interface. You probably won't ever have to implement this or work with it directly, But it is notable because this is what allows you to use a collection in the so called enhanced for the all the standard collections, like list set collection Que deck etcetera. Um oh, maybe not Deck. But all of these implement this interface, and it just has a couple of methods on it, and it just means that you can use it like this. So when you see this, this is the the enhanced for loop. So four person p colon people read for each person p in people. Um, then we know that list must implement a terrible or you pour compiler would complain if you tried to do this in tax. So anything that implemented arable can be stuck into a enhanced for loop. So this is really important interface for people who write libraries or reusable collections of utilities. And if that makes sense, if they're object they're creating is really adorable. It's nice to implement this interface and then people can use it like this, which is a friendly syntax. Okay, for the exercise is not really a great way to shoehorn these concepts into the project in any kind of meaningful way. So we're just gonna do something which is, um, kind of ad hoc. So check your instructions on the usual thing. Positive video. Here, do the project. When you're done, come back, start the video. I'll do it with you, and then we'll just summarize the chapter. So go ahead and pause it now. Okay. Hope that wasn't too difficult or too boring. So here is our little instruction book. That And it just says we're going Teoh create. Ah, pack that. We're going to create a person class and we're going to give it an age property, and then we're going to make it comparable. So basically, what we saw in the slides were gonna work through that ourselves. So that's great. Let's go up. I'm gonna put this in my It doesn't really matter what project you put in. I don't want to put it in. Sorry, game, because that's kind of a nice little coherent set of classes. I'm just gonna put it in the hello World package project, but it doesn't matter. It said created packets called juggling because that's our, uh, the package were working on and then created person class. Now, if you really wanted to shortcut this, um you could actually say Okay, I want to add an interface here, I want to add Oh, there it is comparable. How did it know? All right, Comparable t actually going comfortable person because we're comparing people. Check this box inherited abstract methods. And now it's going to do this We don't really need, but it's not applicable for us, but boom! And we gotta compared to method already. That's kind of cool. Um, it said we wanted a private It's okay. Age property and the constructor that goes with it by now, you should be able to do this kind of stepping your sleep, right? We've done this multiple times. This is just kind of formulaic. In fact, there are ways to do this with the wizard as well. But, uh, let's just leave it alone this way, Okay? You want to sort from lowest age to highest? All right, so this dot age minus other dot age. So that's fine. Let's take out the two dio goes. We say you say this dot age minus Buddha image, right? Remember, you can access the age attributes of this other person because you're in the person class here, right? Even though this is like a quote unquote different object than then. This is You can still just go straight to the attributes like this. So you don't need a getter for age or anything at this point. All right? Now we want to run. We want to create some persons and try and sort them. Uh, you could put a main method here in the person class, but the project says, Let's just create a new class called mean. And I know I'm putting a main method here, so I'm just gonna check that great, create a bunch of persons person p one equals new person and give them an age of 35. And then let's do that. The war Times and that's given age, Pete and, uh, 41. That's that. Now it says, making it ray list persons and add those guys in groups. Okay. And they had to do this word syntax, which will explain in part three, I do my import, which is an eclipses control shift. Oh, I want Java util list, not some other list. And now I think, do this person's only think they want us to call it lists, didn't they? So go ahead. Show that they re factoring. So I'm just gonna grab this and I'm gonna do a control shift car. Oops. Sorry. Shift. Cold car on this A list, Right? Because that's what they wanted us to call it. Okay. And what's next? Create three persons. Put them in the list. Creating hence for Lupin. Print them out. All right, so we say four a person p in list. It was a system print. Lynn P. All right, so there's a problem here. Right? What's this gonna look like? See that they ask about how we would print it now so I can do this, and I can save run as job application, and I'm going to get gobbledygook, right. This is the default implementation of to string in the object class. And this is basically the address of the person in memory, which is kind of useless to us. Right. So how would we fix this? So your java programmer, you look at this. You look This is terrible output. I wanted I wanted to print their their ages. Right. How would you do that? And hopefully you remembered from, uh, part one of the class. Go back here. You need to override to strength. Great. So we're going to return Person of age plus h. Let's just do something like that. How do I know I'm using to string? Well, when you pass in an object to print one, it automatically calls to string on it for you. You could also say p dot to string, but let's first prove that it works. OK, there we go. So 35 8 41 That's the order that we put them in right? Which is what you would expect in list because you're adding them to the end of the list list should keep the ordering. All right, now it says sort sort the list with collections dot sort and put it, of course, before you print collections, groups, firms that sort Gillis Bell. Come on, That is not what I wanted. Sort that some white did that, and now they go 8 35 41 So now they come out in ascending order of age, youngest to oldest, which is the default sort order that we defined by implementing the community method. We've enforced that ordering by doing this, writing this equation all right, and it says Okay, that's great, but let's sort them the other way to I want to be able to go each way. So let's do the descending age Comparator that implements compared to our person. Okay. Sounds like a little bit of fun. So we have a descending age, comparator, and let's do our little trick again and add the compare a tour. And that's gonna be comparative person. Of course. Keep that abstract method. It returned this great. And now we know we want them to be. We want the oldest person first. And so if the oldest person is first, we want to return a negative number. So I think what we want to say is, uh oh, to, uh Ah, now we can't get to the age because we're not in the person class anymore. So we're gonna need a little get her here public. Yeah, age in turn age. All right, We need to know what that is. Wonder get age galaxy. If I reason my way through that properly, it says now, use collections. That sort you can pass in as the second argument. The descending age Comparator. Okay, let's go back to my main. We keep our thing here, and we said Comma New Descending Age Comparator. And now let's see if the ages come out, it should come out 41 35 8 This time you got it. Okay, we did that right. And it says, by the way, you can also use list dot sort and see if that works. So let's, um, comment this out, and we'll just say this dot sort new descending age Comparator. And see if that works. Yep, that sorts them in descending order. Okay, so there's all those different ways that multiple, different ways to sort the list based on, uh, this comparator that you're passing in. Does that create the same result? Yes. And that's pretty much all for, uh, that we have for this exercise. It's very, very short and easy. If you want to go and play a little bit with some of those other classes that are in the, uh, slides, I certainly encourage you to do that. But for now, we're just gonna go back, finish this chapter up. All right? So just to review Javad Outlying package contains a lot of core functionality. A lot of it is very simple and boring, but very important. So that some of the classes we looked at our comparable and its friend Comparator, the thread that run noble, the threat local that deals with multi threading system and run time for talking to the environment and then math for doing floating point math. But don't forget some of the other things we saw in previous chapters As we've gone along. We've already looked at object. We've looked at class. We've seen all the the primitive rappers float double long, short character, bullying all that stuff. Those were also in the java dot Laing package. So, um, you know, if you if you look through the Java Doc for that package, you'll see those classes there as well. Okay, so in the next chapter will kind of do the same thing again. But we'll be looking at probably the second most important package in Java, which is java dot You tell and that one's got a lot more interesting functionality. All right, we'll see you then. 9. 09 JavaUtil: Okay, welcome back to Chapter nine. We're going to talk about the java dot util package so java dot you tells probably the second most commonly used package after Javad out lang. And that's mainly because the collections framework classes old of hair, and we've come across list and set and all those other classes before. They're used quite a bit, and so you'll find yourself importing java dot Utah a lot. But there's also ah, a bunch of other common utility classes that are in here that are that are worth knowing about. So let's go through and take a look at some of the more common ones. All right, there's a class called objects, which is a class. It has static methods on it that allows you to do no safe operations that you would normally the check for null so like to string equals hash code. Compare. Those were some of the main ones. There's a few more. You can look at the Java doc to find the others, but the way you would do it is this. So in the past, if you had an object, reference acts and you said, if X is not equal to know. Then call ex dot to string. Otherwise used the string null. Okay, you can dispense with all of that machinery and just say objects not to string, because that's what objects not to string does. So it's no safe and the same thing for working with hash code. If you're object, you passed in his null. It'll just return zero same. It has no safe implementations of equals, etcetera. So you don't have to put in null checks everywhere. Okay, job that you tell that date. So this is the original class for handling dates in Java. This encapsulates an instant in time. And it's the number of milliseconds since the epoch. Which two programmers, The pocket's midnight January 1st, 1970 in UTC, which is London time. Right. Um, this turned out to be not the best idea. Most of the methods on this class or deprecate ID it has a lot of methods, like get month, get year get day, but it doesn't handle time zones very gracefully. Doesn't due date logic at all? As far as I know, generally all uses the two methods you see here you You can, uh really It's the 1st 1 you call get time, and that returns the number of milliseconds since the epoch, um to instant. That's a bridge method that takes you into the new implementation of java dot time that we'll talk about a little bit later. Okay, so this will capture the current time. When you create a new date like this, it just basically called system that current time milles and captures that millisecond value inside a date object. And you can always return that back by calling get time. You can also create a date by passing in a value that represents a number of milliseconds since the box so you can set a date to some particular instant in time. Now, in order to do the the conversions from from dates two years, months, days, hours, things like that that human beings normally think about. You need the calendar class, and this is the one that has the smarts that knows about time zones, knows about leap years and all that crazy date logic. Um, here's part of the A t. A p I. You probably can't make heads or tails out of it by looking at that, because it's really kind of an awful A P I, um, you get a calendar object by calling Calendar that get instance now that looks like a singleton method. Call right. That's usually what we use for Singleton's is class name dot get instant static method, but this is actually a factory method. Each time you call it, you get a new instance of calendar, so it's not a singleton at all. So that's a little bit annoying. And then to, uh, get set and add values to the calendar. You have to use this sort of syntax. So let's say you wanted to take a calendar and change the year 2 1980 you say calendar that set and then you pass in the constant calendar dot year, and then you say 1980 all right, and then you can convert a calendar back into a date. If that's what you wanted to do. There's other classes that go with calendar and date. There is the time zone class, which we've hinted at on our diagrams here that will let you switch time zones from from one class to another that this lives in java dot You tell then to convert dates between strings and back and forth from dates. Two strings and strings. Two dates. In other words, parsing and formatting. There's a class called date format and more, more usefully, there is a subclass called Simple date format that you generally use. They actually live in a different package. It's java dot text, but they go together with these guys time zone, calendar and date. Now these three classes have an A p I that only their mothers could love. It's really horrible. And if you have to do a lot of work with it, you're you're gonna feel like this, right? So you may be telling yourself, Man, there's gotta be a better way to do this. And there is. It turns out that there's a package called Java dot time, which is infinitely superior to these classes, and you should really avoid using date and calendar, if at all possible. Only if you're working with legacy could should you be using that this job time packages based on the Jota Time project, which was an open source project that arose in response to the horrifying nature of the AP eyes for the job. It's time handling, and in one fell swoop. Java went from having, like, literally the most awful date and time handling AP eyes to having one of the most elegant and powerful. And we'll talk about this in the next chapter in Chapter 10. Will review the java dot time package. It's very rich and very, very easy to use. Okay, Another class we have in java dot util is the optional class, and this is to declare a value that may or may not be there. Sounds kind of interesting. Some of the values on the left you can ask if there's a value present. If there is, you can get it. Um, there are some other things using consumers and run a bles. I'll show you that in a little bit. Well, we haven't really. We don't really have the background yet in this class toe. Tackle those methods on. Then there's some factory methods you can say, creating optional from some valuing, but it's not from its of is the method you use. And if the value might be no, then you have to use of knowable. But anyway, you can look at this and say All right, suppose I have an optional of string. So again, the the angle bracket string angle bracket means that the optional contains or may contain a string. And you can write code like this if optional that is present. That means there's a value inside the optional. Then you can pull it out by using optional that get, and it's gonna be a string in this case. All right, Um, now, using optional is a little bit more sophistication to it than that. There's really two big use cases here. One is just to advertise, like if you're writing an A P I, and you want to advertise of the callers that this method may or may not return a string. Now, without optional, you would just return. Know if there's no value to return, which means that the caller needs to be aware that this method might return null. They didn't read your documentation, they might not realize it, and they might get a no pointer exception or had some other problems downstream. But if you make it optional, then they know for sure. Okay, there may or may not be a value coming back from this, and I need to check and I need to handle both cases, right? So this is better than putting it in your job A dock saying, Oh yes, this method might return old. Be prepared for that case. If you make it optional, they have to handle it because it's coming back as a strongly typed object. The other way of using optional is very powerful, and we won't really explore it until in detail until part three of the course. But here I have an optional let's say it's an optional string again, and I call this method if present or else and basically what this does, there's two clauses here that you might see separated by a comma. If the string is present, I'm gonna parse it. So I'm gonna call the part string method. If the string is not present, I'm going to call the method, generate new strength. Okay, this is just cartoon could, But to let you know. So instead of going if string, you know, if s equal, equal, null, then parse string else generate new string. This is ah ah more powerful way of doing it. This notation we see here with the dash and the angle bracket that is lend a function notation which we haven't talked about yet. So but it's really nice not to have the conditional here. It's really easy to make mistakes when you're writing. If blocks like, for example, you might write if s equal equal? No, when you actually meant to say asked not equal no. And then that's a really hard bug to spot just with your eye when you're looking at code. Um, the real power of this and of of optionals is not going to be apparent until we've introduced Lambda Functions and gone through that. And then I'll come back, revisit this with you and show you just how amazing optionals Ca NBI. Okay, the four matter This is a class that's super important, but you you won't probably ever use it directly, but you look at the job a dock. So this controls the 4 May of strings as inspired by the esperan a function in the C language. So if you've never looked at that, here's some code that it that it looks like. First of all, this is normally how you use the Ford matter. So there's a a static method called format on the string class that actually under the covers creates a four matter and uses for matter to do the work. But as I said, I mostly what I see is people using string dot format. That seems to be the common way of accessing this functionality. Um, string dot format takes two or two or more arguments. The 1st 1 is the format string. So it looks like a regular string. But you see that percent s in it. When you see the percent, that means substitution parameter. So in other words, from the parameters that follow in the method call, we're going to substitute in percent asked. The S just means string. So take whatever you find in converted to a string. Well, the parameter we have is just bob or hate. So it is a string. So it just is going to copy it in there and it's gonna print out Hello, I am Bob. So you know this particular usage of string dot format is not very powerful, but let's go on and look at the next one. Now there's another really super useful place where you can find this kind of method, and that's on Prince Dream, which is what system That out is right. So you can say system that out dot format And now you can do the same thing. You have a four match string, all right, and there's two formatting parameters in there now, the or, I would say, a substitution parameters. Now look at the value that we're passing. B comma be. Look at the line above. That's a bite. So I accept Bite B equals 110 right? And what I'm gonna do out here is printed out twice. That's why it has become a B. So the first substitution parameters percent D D stands for decimal. In other words, print this out as a number, so that's going to come out as as just a regular old imager, basically, and then the 2nd 1 present 04 x What does that mean? While the X means that I want to print this value as based 16 x a decimal, right? So, in other words, ah from zero toe f using those characters and the fact that it's a Capital X means if you have any letters, I want to capitalize those. If it was a small X, I used small letters. The four means I want four characters wide when I printed out, and the zero on the left hand side means if it's less than four characters patted on the left with zeros. All right, so it's a very compact and, um, cryptic syntax and, you know, just because of its heritage from the C language. But you can look at the Fort Java that you told up four matter Java doc to see pages and pages of documentation about this. So you're probably wondering, what does this one actually print when you call it? And this is what it prints. The hex value of 110 is 006 e right, and that's exactly 60 is 110 decimal. Okay, so this is really and just as a hint, if you ever need to print something out in Hex, this is the fastest way to do it in The easiest way to do it is to use the format, uh, functions, okay, and that just about wraps up java dot you till there's a various and sundry other classes here. So there's a class called random, which generates random number streams of most of the primitives. You can have, you know, a stream of Boolean stream of inst doubles longs, etcetera. Um, so if you remember from the previous chapter in Java, darling, that math, there's a random function which returns a stream of doubles that go between zero and one. This one has some a little bit of extra functionality on top of that. So if you want to do like a stream of Vince that goes between zero and 100 you can use the Java Util random class. To do that directly, there's a you you i d class. So you ideas air fairly common, and Java has a class for it, And that class will allow you to convert between your i d objects to bite a raise and two strings and also to parse out the components of the U idea. If you just want one of the components, you know, normally they're separated by dashes. You can pull those out like that. So that's a very useful class. If you're working with you, i ds it also generates random you you ideas for you. So if you need a u i d, you can use this class there's a bit set, so if you want to use a set of bits to represent some options so like but zero means this bit, one means that bit two means that you can use this class bit, said it. It's a very compact representation, and, uh, it has helper methods on it. So you don't have to, like, use bit masks and do logical ans to try to figure out you know what values you have. There is a class called scanner, which uses regular expressions to read data out of files or strings. I don't see this used too much, but it could be quite useful. It's it's good for you to know about it. There's also AH, based 64 encoder and decoder. So if you need to encode or decode based 64 values, you can use that and there's a bunch of other classes, most of which are not used that much. But once again, I would say job that you tells a package that you probably should go ahead one day and just look at the Java doc and read through the classes that are in there because there are some interesting well utility classes that you can use to do lots of different things. You want to write your own code for for an exercise. There's no exercise this chapter. I really like just tinkering with these classes. You can do that on your own that you don't need like a guided exercise. I just presented these as kind of independent, UH, one off classes. And so you can just take those and looking at the slides. You can fiddle them with them a little bit if you feel inclined. So summarizing. The Java dot util package contains lots of commonly used functionality. It's utilities, and the main part of the package is the collections framework. The lists that map que Decade said, are all of those guys that's by far and away. What you're going to use mawr in the job you thought. You tell package that anything else. But there's other utilities. There's the objects class, which is gug could be pretty useful. There's the old date and calendar, a p I, which hopefully you know, if you're writing new code, please don't use that. But you you will come across it a lot in legacy code because for a long time. That was the only thing we had. There's optional, there's random. And then there's all those various classes that we just saw on the previous slides. So that's all I have to say about Javad at you till in the next chapter, we're gonna go and tackle the java dot time class, which is just my favorite package and Java, So we'll take a look at that. And until then, have a good time. We'll see you then. 10. 10 JavaTime: Okay, Welcome back. And welcome to Chapter 10 about the java dot time package. In this chapter, we're going to review the java dot time package, which is just one of my favorite ones in Java. Will look over all the multitude of classes that come along with this package and tryto make sense out of them. And then we'll look at how to do formatting and parsing of dates and times and all the other things that are associated with that. So times a complicated concept And someone says, you know, what time is it? How do you specify that? So there's actually, in general, like to large categories. So if you're asking a question like you know, what time will the solar eclipse be? You're really looking to specify an instant in time. This is going to be happening at a precise, you know, astronomical instant. And so you may use expressions like this. You say Okay. July 12 2025 10:15:47 a.m. Eastern daylight time. All right. Now, if you're in a different time zone like Pacific, it'll be at a different time. I noted notice three hours earlier for Pacific from Eastern. So when you're trying to specify an instant in time, you gotta have the date. You've gotta have the time and you've gotta have a time zone, right? That's how you can specify if you're missing any one of those. The person was gonna miss the eclipse. On the other hand, if someone says to you Hey, when were you born? Because they want to send you a birthday card or something like that. You might just say yeah, August 15th 1985. OK, notice that the difference here. So you might call this like a local date. All I care about is that it's August 15th here, right? If you were born on the east coast of the United States and now you're living on the West Coast and you're turning 21 it's August 14th at 9 p.m. You can't go to the bar and say, Hey, my birthday is August 15th but that's on the East Coast, you know? So it's already after nine PM So authority the 15th of the East Coast, they won't let you in, right? It only matters with local date is So, um, in that case, you don't need a time zone. And you know, in this case, we don't the time. You could also do it the other way without a date. And just say, uh, you know, what time does your work start? Well, 9 a.m. Right. Okay, let's look at the 1st 1 specifying an instant in time. This is the way computers think right generally, especially on Lenox machines. They measure the time since the iPAQ, which would be midnight January 1st, 1970 in London. UTC. And in fact, if you call jobs system that current time Millie's, that's what you get the milli seconds from that instant if you create a New Java Util eight instance, that's what stored internally the same value. So in the new job at that time package, we have a class for this, a class called Instant and ah. The underlying methods are static factory methods that create instance, and you can just say now and it will create an instant that represents the current instant when it was created. You can also pass in values of Millie since milliseconds since the epoch and second since the epoch or you can parse a string. All those would create instances. Um, and you can get back the number seconds the talk about the nanoseconds, What that means in a minute. Or you can cover it back to milli seconds. Um, so what does it look like? It's very simple, you say now equals instant thought. Now, now you have an instant, you have an instant instance and or you can part a date using the parts functioning. If this is nice of standard date representation here, notice you have a date and the time in a time zone. In order to do that. One thing that might help you understand instances to know that internally, the data is stored in two values. The number of seconds since the epoch and then a number of nanoseconds offset from that zero second mark to give you more position. And the way they do it like this is because if you tried to store the number of nanoseconds since the iPAQ, you'd run out of storage space in in a long and an eight byte imager, so they split it into two very cleverly and you get the second since the iPAQ stored in a long and then you just need uninjured to store the nanosecond offset from that. Now, the instant class has a lot more methods. Okay, but they kind of fall into a common set of methods that all of these date time types tend tohave. And so we'll talk about that family of methods a little bit later on in the chapter. Now, of course, humans don't generally think about times as seconds from the epoch. We usually say something like July 15th 2024 8:45:13 a.m. Pacific daylight time. Okay, that's how we like to think of it. And the job has a class for that. It's called zone Date time. So Zone daytime has more familiar things to humans. Like the year, the month, the day, the hour, the minute the second, the time zone, which is represented by this concept called Zone I. D. And it also has a static factory method cult now, So you might do something like this with his own daytime. So you need a time zone to do this, right? So, you, uh this is a simple way to get a zone I d. Which is the time zone representation for this package. and then zone daytime also has a factory method called of where you can pass the parts in separately. So 2024 is the year seven is the month. 15 is a day. It said her hours, minutes, seconds, nanoseconds and then the times out. And if you were to created a date like that and print it out, it would say something like this. Now it says, America, Los Angeles, because that's the time zone My computer was in on the west Coast of the U. S. When I ran this Good. Okay, so just to say about time zones, this is Ah, there was a class called time zone in the job that you tell package that has been there since the 19 nineties. The new classes own i d for the java dot time package and it's a beast on the inside. It has all these rules that no described for this time zone. Ah, how far off its offset from UTC. You know what side of the of the international Dateline it's on when they go to daylight savings time? All that crazy stuff that had to deal with when you deal with times so using his own ideas straight forward. I mean, you can get the time zone that your computers in you can use the standard i n a times and database descriptors, toe load, any time zone that you want. Um, And then once you have a time zone or a zone, I d rather probably the only thing you're interested in doing it is retrieving the i D. Unless you're really working deeply with times. So it's easy to convert between the zone daytime and the instant The instant has a method called At Zone, where you pass in his own I D. And it turns it into his own daytime, uh, zone daytime. You can just say to instant, and it converts back to an instant zone. Daytime also has a static factory method, which combines an instance on Instant and the Zone I d to create his own daytime. So you might do something like this. You could say ah created Get his own idea again. Get the default, do instant dot now and then you can say now dot at zone passing his own idea. You get the zone daytime or you can say zone tight daytime of instant now. Kama Zone I d those to do the same thing. Okay, that's straightforward Now, humans also conceived up times without time zones, Right? You say Brandy Rhodes died March 19th 1982 a black day for music. But no one cares about the time zone. They don't want to know if he died in Texas or Florida or you just make a move. Commemorate Commemorate. That is March 19th 1982. So in Java that time we have a class called local date time, which is almost the same a zoned date time. Except it doesn't have the time zone or a zone I d. So you can add his own I d to it. You see the last method there you say at zone zone I d to turn it back into a zone daytime . Or you can just keep it as a local daytime. There's also a now factory method again to get the current local date time. So local daytime also has another factory method called of just like zone daytime. But this time you only pass in year, month, day, hour, minute, second and now you can print it out and it will print something like this. Notice that there's no time zone attached to this output. Now you can have daytime's without time zones, but gonna have dates without time. And so sometimes, like on the previous light, we just say august 15th 1982. Okay, that only has a year, a month in a day. So that's what we call a local date. Sometimes you say work starts at 9 30 in the morning. Well, that's only an hour minute in a second without any date attached to it. That's called a local time. Okay? And you can get local dates and local times out of yours own to date times and your locals a daytime objects because they have a two local date in a two local time method on each of those. Okay, so all these pieces kind of fit together like puzzle pieces. So let's put it all together. You can have a local date like August 18th 1982 or you can have a local time like 10:45 a.m. and 30 seconds. If you combine those two, you make yourself a local date time, which has a date and a time together. If you take a local date time and you add to it a zone I d. Now you have yourself a zone to date time. And, of course, once you have his own daytime, you can go back and forth. To instance, you confined the number of milliseconds since the Epoch Junior 1st 1970 And, of course, you can go both ways across this graph from zone to date time you can say get zone I d or get local daytime and it will really go backwards for you and from local daytime. You can say get local date or get local time so you can go run this graph forward and backwards. Okay, Another concept of time. We have to think about his intervals or lengths of time and again. There's two different ways you can kind of work. This, um, one is by years, months and days. So you say, Hey, I hurt my knee four months ago. All right? Well, exactly how many seconds is that? Well, it's not really exact right, because months and years have differing numbers of days. You know, we know how many seconds air in a daze, but a month can have 28 29 30 31 days. Ah, year can have 365 or 366 days. So this is imprecise. And there's a class for this called the period class. Or you can measure it on interval very precisely. Using days, hours, minutes, you say, four hours eight minutes ago. You know exactly how many seconds that was or anything like that. So that's a precise duration class A measurement. All right, Before I show you how to work with periods and durations, I want to talk about something that's common to the All of these types that were talking about is that these instances are immutable. In other words, once they're created, you can't alter them. Um, but they do contain methods that will spit out new objects. Based on some calculation, you do eso What am I talking about? So it uses a technique called fluent AP eyes, and it uses a set of methods something like this, like plus days minus days plus minutes, minus minutes so you could take, say, for example, a duration of four days and three minutes, and then you could say plus days to And now you have a new duration of six days in four minutes. Right? So it will generate new objects for and I'll show this to you in just a moment. They also have methods better like with our or something like that. So if you have ah, a local time, that's 10:45:16 a.m. And you want to change that to nine. You can just say dot with our nine and you'll get another a new instance of local time That has everything the same. Except you change the hour. All right. It doesn't ever Nothing ever alters the original instance. They're always immutable. So let's see what that looks like. Let's go back to durations now. So factory method for durations dot of seconds. So I say duration dot up seconds. So now duration D is 33 seconds long. Now I can say equals d dot at days three. And so what I've got here is two different duration objects. D is 33 seconds long and ease three days and 33 seconds long. All right. D has not been altered by this, uh, by this factory method that we called here. So that leads to this kind of fluent AP I way of writing things, which is this is how people normally do it. You'd say I need a duration of 33 seconds, four minutes and 13 days. And so you could write it like this. Duration dot of seconds and then plus minutes plus days. And you're actually creating a new duration object each time you do that. But you're only saving the reference to the final one. So you got your duration D, and then you can say deduct two seconds and it's gonna be some very large value because it's 13 days and four minutes and 33 seconds. Um, now, if you said two seconds, that's probably not the answer you were expecting and similar thing. If you said d 20.2 minutes, you'd get some large value because days have lots of minutes in them and it would kind of calculate the total number of minutes. They also have these methods called two seconds part two minutes part, and the part is sort of after you've taken out the larger pieces, right? So once I remove the days and that remove the minutes I'm left with 33 seconds. If you did two minutes part, it would remove all the days and then would say, OK, we got four minutes left. So just be aware of the difference between those two. You'll see that when you use it. So just to remind you, durations used the time units of days, hours, minutes, seconds. Milles and Nano's so days were the longest unit that the duration understands. Now, of course, you could put in, you know, 3000 days or something like that. That's fine, but it doesn't know anything about months or weeks or or years or anything like that. Periods, on the other hand, are all about days, months and years. So Period has a ah factory method of that takes the number of years a number of months in a number day. So I'm created. P is going to be three years, four months, 23 days, and then I take, uh, pee and I add 12 days and I subtract 18 months. And now what's that? Okay, so I can call. That's a new period. Q. I can call queue dot get months and it tells me, minus 14. So what? I've got here now is a period in Q of three years, minus 14 months and 35 days. All right, that's accurate. But that's not generally hell, We think, um, you want to normalize that? So when you when you normalize it again, generates a new period and it normalizes the years in the months, not the days, because there's always 12 months in a year, but there's a different number of days in a month. So when you say 35 days is that one month and four days, or one month and five days or one month and six that you can't really say so it leaves the days alone. So once you normalize it and you call get months, uh, this is gonna return 10. So the period are is if I do, my math right is going to be two years, 10 months and 35 days. Okay, And you can take a period and add it to like a local date. Time to advance it to that time. And they'll use some sensible rules on how to deal with the very number of days. So periods are the long ones. The member duration in the duration days was the longest unit we have in period. We use all the long durations that or I should say, Time, minutes. I shouldn't mix my words. They're years, months and days, right? So days are the shortest thing that periods know about. Whereas days were the longest thing that durations know about. Okay. And another way you need to know about creating durations and periods is to use the between factory method. So here we have two local daytime's on you can see what those parts out to. I'm just using the of factory method to create a duration between two local date times. You just say between and you pass in the start value in stub value. And if you were to print that out or in, you know, query the internals, you'd find out it's 213,549 seconds there. I can also create a period now, remember, period, the shortest time unit. It knows about his days. So this will come out today's. But notice what I have to do. I had to change it to a local date. The period when you say period up between that factory method. If you're passing in something that has hours, minutes and seconds. It doesn't like that. And so it tells, you know, I can created period between something that fine grain. It could only have days as that smallest time unit, so you can just convert that to a local date and then it works. Okay, formatting and parsing. There's a new class for that as well. Date time for matter. So let's see how this works. It's pretty straightforward. First of all, it's in a different package job at that time, that format, and you can create a date for matter in many different ways, but you can build a custom one from a string pattern. So here I'm using years, months, days, and you can go to the Java Doc page of daytime for matter to see all the different Myriads of ways you can construct patterns. But now I have some local daytime that I got from somewhere, and if I want to turn that into a nice string, I say local daytime got for men and I pass in my four matter right and then going the other way. I can parse it, and I can say, Parson and then pass in the string and then the four matter now notice again. I had to switch to the use of local date here because the pattern I'm using doesn't account for hours, minutes, seconds. And so if you try to parse that into a local date time, it's going to get to the hours part and say, Hey, you didn't tell me what the hours were. I don't know what to do and it will fail, All right, so there's all these little quirks and edges of the of the package, but that's the nature of time. It's complex, Okay for the for the daytime. For matter, you don't always have to build your own patterns. It has a lot of pre defined patterns, and they basically looked like this. They're generally I so standard patterns. There's a couple others, I think, but you can go into the Java doc and see what they look like. And, uh, you can use these if they suit your time. If they see your purposes again, the date time for matter instances like everything else in the Java time package is, are there immutable and therefore their threats safe. Now this is particularly significant for this because in the previous version of date handling and Java, there was a class called simple date format, which was not thread safe, which meant, and it was not immutable either, which means it was not reasonable. You had to create a new one every single time and woe to the programmer who forgot and reused one because you would get crazy results. Okay, so when General, you probably want to use the pre defined four matters if they suit your purpose. If not, it's easy to create a custom one. Okay, one thing that's really great about the job of time packages that it's so consistent all the instances air immutable and thread safe. So you congee just share them across threads and you can reuse them and you know, they never they never change. It's it's very, very nice to use pretty much. All the classes have things like a factory method called now, which looks at the system clock and creates a new instance. Based on that they have these ah plus and minus metha methods were they create new instances where you can add plus and minus days, minutes, seconds, years months, etcetera to create new objects. Um, and you can also reset one part by using the with factory methods. You can convert two xxx to convert to some other type, or you can get parts of the like get seconds or something like that to get the parts out of the, uh, instances that you have. There's Parson format methods. Parse is a is a static factory method format. You call it on the instance itself. The non zoned types usually have a method cult at zone where you can pass in a zone I d. And then it will convert it into a zone, uh, object. And then there's all those of factory methods that we've seen a lot of, and it really depends on which type you're you're using as to what, exactly the arguments of of or but generally all these methods air here, some on some of the types. These don't apply. Um, but generally, generally, you'll find that the method your name really consistently. Okay, so, uh, we can have a contrived exercise here, which would be we can tight. We can go back to our board game simulation and weaken time. Its execution Okay, So, like, in the in the main method, weaken, get a start time in a stop time. So, um, go ahead now and switch over to your little instruction book. It'll tell you exactly what to do. This is pretty simple, though. And, uh, go ahead and do that. Pause the video, and when you're done, start the video again, and then I'll walk you through it. Okay? I hope that was somewhat useful for you. Let's go to the job that time instruction sheet here, and we're gonna do this little exercise. But as it notes here, it says, Go ahead and play with these AP eyes a little bit more. And Explorer, this is a very rich package. We didn't even talk about things like using different calendars like a Japanese calendar, or, you know, like a Buddhist calendar or something like that. So, um, there's all there's all this more richness. It's in here. So let's just do the exercise as described here in the sorry gamed out main method created local date time before and after just by using the static now factory methods of Sorry game . We got our main. Okay, So must do this local date time. This will be the star local date. Important that and say now, Great. And then at the end, because school below all the stuff and say local dates stop Nichols. Okay, time now. Okay, Simple enough. Then it says created duration by using duration. Doubt between. Okay, that's cool. So, duration, operation duration. Uh, here looks import first. Did I get it? Here we go. Between start groups start. Okay, great. So now I've got to local date times and a duration. What are we gonna do here? Print the two local date times first natively and them with one of the four matters on the date for matter class, and you can find them on the job. A dog. So let's ah, this Just try it first. Having a little trouble typing today. Start so stuff. All right, let's just run that and see what that looks like. Okay, so you see how their, uh, how they're coming out here Now, we don't have any space between the previous part of the program, so let's just print a little. I didn't do it here. Just getting lining up in there so we can see we're doing okay, So it's not entirely a friendly format, in my opinion. But let's try printing it, as they suggest with one of the four matters that are included. So let's take the start time. Remember, there's a format method and I can say date time for a matter. And let's see, What could we do here? There's a date. There's a time. There's a local data, local tennis issues, local time. See what that looks like? Okay, so this is 2154. 58 point 2572672 So it goes down to 100 nanosecond precision here that's probably as good as my laptop can give precision. All right, then it says, print out the duration and then also the milliseconds and then seconds. All right, so let's print out the duration. Let's just do all of my once print operation dot to Millie's, um, now that this'll be an interesting one, right? In fact, let's just stop there and run this because there's a Millie's in Emily's part. So first of all, when you print out a duration, there's some kind of ah, standard notation for durations that look like this in its point double of 39998 seconds. Um, that's not very. That's good for computers to parse and everything, but I think for again, for people it's not too easy. Then I print out duration and milles, and it prints out three milliseconds. Okay, so you can see it was 3.9998 So it's about as close to four milliseconds you can get. Um, let's see what happens if we change it to Millie's part. Okay, so it's actually prints it the same for this. Okay, now, the other one it asked for was the Nano's ray system. Duh outs. Duration. Uh, this will be get Nano because it's not to Nana's. It's getting annals because Nana's and seconds or what's on the inside of this object. If you remember, we talked about that. Let's see what the nanoseconds are in its 7001000 All right, So, um, this is nanoseconds right's nanoseconds, zeros, one microsecond and seven milliseconds. It took seven milliseconds, one microsecond and zero nanoseconds. According Teoh, This timing to figure out to run our whole game. And don't forget, the game is running right, Like we got these two players that are moving their pieces around the squares we created How many squares, 60 squares or something like that, and a bunch of a couple players and the whole deck of cards. And we went and we did that all in seven milliseconds. That's kind of cool. That's right. In a couple of see how fast we get it to go for milliseconds six five, six. Looks like about five is the average rain. Three. Okay, we got it as low as three. All right, Prenup duration most because now it's like, OK, so that's pretty much all the exercise was was just to get used to playing with that, Um, you can do things like we printed, start and stop, Let's print and then we four minute as Anicet Time. Let's try something else here. Let's take start that to local dates and start to local time. That's to see what those look like, and so the local date looks like exactly what you would expect. Um, the local time also comes out pretty much like it expect. Accepted as Nana Second precision, which may be most people wouldn't be expecting that Um, but this is basically how you can use this package, and it's it's way richer and more flexible than the old job. You till date books. Try that again. There were you OK? So to summarise this chapter, we know that instance. And zone daytime instances let us find a moment in time or an instant in time. Then we know that we have local date, local time and local daytime to just represent calendar and clock times when we don't really care about the time zone. We just care about what time it is now. Locally, someone says, Be here at 9 a.m. You show up at 9 a.m. Your time not Florida time or you know, the time in Hungary or something like that and then his own ideas. A time zone. And that's what you need to bridge the gap between those two groups of time representations , right? Once you have the time zone, you can go from the local times to the zone times, and then you have the classes that represent Interval. So durations represent an exact time measured in seconds and nanoseconds. Of course, periods are more conceptual. They used years months and days, and they might not be quite as accurate because of the very numbers of days in different months and years. And then we have date time for matter, which is the class that controls printing and parsing using patterns and again the patterns , the pattern symbols you can use for a daytime, for matter extremely rich and varied. So it's worth looking over that Java doc just so you can see what they look like. All right, that wraps up our investigation of the job of that time package. In the next chapter, we're gonna look at doing input and output with Java, so that's gonna be a very interesting one. And I'll see you in the next video. 11. 11 IO: after 11 where we're gonna talk about input and output. Okay, So kind of like with time where we have the old Java Util date and then we have the new job it up time package. We have sort of two systems for IOS. So there's ah what we call java dot io, which is the original way based on a class called file and then Java Nyeo and I. Oh, I guess it's pronounced nao new i o, which is focused on a class called path. So we'll look at those two systems. Um, then we'll look at the input stream outputs dream framework and how that uses a pattern called the decorator pattern. And then at the end of the chapter, will go over property files And how these jobs logging framework. So this is a pretty long chapter. So grab a glass of your favorite drink and sit back and relax. Here we go. So let's start off looking at the new Io instead of looking at the old stuff first. So how are you supposed to do it now? So there's a a class cult path which is in java dot nyo dot file and again that's a replacement for the old workhorse job. A Iot file path is a class there represents the idea of a path on a file system logically so it could represents directories them files. And it's not really it's logical, in the sense that you can create a path for a file that doesn't exist, is not actually connected directly to the file system. It really is like it's a logical data model of, ah, file system path. And then there's another class in the night, a package which is called files. And that's the second the second wing of the of the new IO system. And that's the one that does all the file system operations. You give it path objects, and it uses them to do work on the hard disk in more or less. That's the division of labor here, So let's look at path. We're gonna look at PATH pretty closely, so here's just an introduction. There's a bunch of methods on path again, these air, not all of them. If you look at the code sample, you see the factory method of it's a static method. You passed it in something here that looks like a file name and creates a path object for you, and you can have things like one of the methods is too absolute path that you can, uh, print. And it will give you something like back notes that 60 for example, depending on where you are on the foul system, etcetera. Let's look at what it actually really prints out. So here's a set up. Were using Windows here because Windows is a little bit more complicated and so if you can get Windows, you can get Lennox. But there's a directory, TMP, and there's a file on their cold notes dot txt and I'm going to run some Java code where the current working directory is slash TMP. So I'm in that directory. They're okay. So here's the code. I'm going to run and get us a path equals path of notes that takes T and you see that makes sense because there is a file called news dot txt in the temp directory. So now on the path object. There's all these different methods you can call, and so let's let's look at them closely. If you call to string, it basically returns back pretty much what you put in of method. If you say to absolute path or to riel path, it actually looks at where you are from the current working directory. Okay, this is resolved by looking at I'm in C colon temp, and this person said that the code says notes that text. So that must be a file relative to see Colin Tip So it puts together a file name. And of course, the actual string that comes out will be different in Lenox. It'll have forward slashes and it won't have the C colon. It's all this is ah, file system step is very implementation dependent. Is this an absolute path? Notes dot txt. Now it's just a file name. How many names air in the path itself? Well, there's just the one. We didn't give it any any hierarchy. And what is the file name? While the file name is what we gave it notes dot Txt. What if we do it with a directory? So here's the same set up, same current working directory. But now I'm going to do this so the of factory method can take any number of string string arguments. See? So here I've got two of them. It can take 12345 as many as you like. And the 1st 1 is the directory slash TMP. And then the 2nd 1 is the file name notes that txt. All right, So what changes from before? When we look at all these methods, almost all of it is the same. Except now there's two names in the path. There's temp, and there's notes that ticks t. So the path itself knows about two level of hierarchies, and so that comes out is a to all right now. So interesting. What if I try to do with an absolute directory? Okay, same set up. And I'm going to do this, okay to statements here now, because there's a difference here with Windows. You need to give the drive letter right. If you know anything about windows like you, there's multiple drives that are file system roots, and you need to specify which one to really truly specify where your file is and then slash temp and notes. But on Linux there's a root file system, which is slash, and so you can say slash temp. You could move the slash out into another string so you could have slash cola, comma temp, comma notes that 60 for limits. But this works just as well. And now when you run all these outputs, this is what you get. Everything, again is pretty much the same. Except now the path registers as absolute. The Path class considers that an absolute path. All right, let's keep going. What if we have a fake file? So same set up working out of slash temp? But I create a path like this with the file name that doesn't exist. And then I run all those methods again. What's gonna happen? Well, for the most part, everything looks exactly the same, except it's a new file name because remember, the path object doesn't really care about the disc. For the most part, right, when you go to to real path, however, it throws an exception that throws in no such file exception. So you might be wondering, why is that one method concerned about what's on the disk and nobody else is like that? That seems to be unusual method and the problem is, or the reason is that when you try to get the real path of a file. It has to figure out if that path contains assembling or if the file itself is assembling, as you can have on Lenox and some other file systems. And so it actually has to go to the disk and traverse the disk to follow the SIM links. That's what really path means. Riel path means I'm going to take out all the SIM links. Forget about all the siblings. I'm going to tell you really where this file lives on the file system. So if the file doesn't exist, it can actually do that working. Then it throws an exception. That is, to my knowledge, I think, the only method on the path class. It actually talks to the file system. But I could be wrong about that. Okay, A couple more methods here. Resolve and relative eyes, these air kind of in verses of each other. So what does resolve me? So let's I have ah, route path, which is slash TMP and then I have a sub path, which I'm just calling sub. And if you look at the directory structure on the left, you see, I'm now saying, Okay, have the TMP directory and there's a subdirectory under it. So no files here, just directories. And then I want to get the path to the full path to the subdirectory s so I can say, OK, starting at root. And I can say dot Resolve the sub path and what that's going to do, basically, more or less. It takes the parameter and appends its path to the root path. Right? But it joins them in a smart way with file system dependent separators and things like that . And so when you look at this one, it will say slash temps that slept sub, which is the correct path to get to that directory. All right, now you might be asking Why would you do this in this convoluted wait? You know, you have slash tap. You know you have some. Why not just create one path? The reason is here, this is cartoon code. In the real world, what's likely to happen is you know, you're looking for a directory cult sub, but you don't know exactly where that's rooted on the server. And it could be the machine. It could be anywhere. And so somebody is passing to you the route path they're going to say, Here's your route path. This is what you're working Directory and then you go, OK, great. I need to find the directory sub, which is a sub director of that route. So you'd be handed the root directory as it like a parameter, and then you would resolve off of that route to find the files and the other subdirectories that you're looking for naturally with that method is meant for the opposite is relative eyes, which just does the opposite. So in this case, I have the path of the root directory and I have the full path of the subdirectory. And then I want to find the relative path from the root to the subdirectory and so I can save root dot relative eyes, subject it just as the exact inverse of what resolved. As so, Those two methods are very useful for working with pads. Ah, one more method you should really know about is normalize. And so let's hear I change the set up again. I've got the temp director. I've got two files there now notes dot txt and logs that txt and I constructed path like this path of slash temp. Okay, so that puts me in the director. Then I say notes that txt Okay, that's the path to the file. Then I go dot dot Now, if you remember usually and when you say dot dot in most operating systems, most file systems, it takes you up a level right so that Texas back up to the slash temp level. And then I say logs that txt. So you know that's fair. You can do that slash temp slash notes that takes t slash knocked out slash logs that 60 but it's kind of awkward and redundant. Normalized removes all of those redundant markings like the dot dots. Or and if you have a dot, which means current directory. Basically, just remove that and so normalized will take that out interval. The better path will be slash temp slash logs that texting with all the extra junk removed , so normalizes another good one. If you're doing a lot of building relative paths and resolving off of things and some of those sub paths have dot dots in them or dots in them at the end, you may want to normalize to just remove all that stuff and get the get the clean path. Okay, so that's the path class. There's a lot of stuff on there. And so there's other methods to deal with. Pads, in a logical sense, like you know, starts with this other path ends with this other path. Get the parent, get the route. All these kinds of ah method you might want to use if you're traversing a file system. Okay, The second wing of the NAO packages the files class and this basically you pass it paths into the files class, and it does the operating the or the file system operations. Right. So here's ah, well, look at these in a little more detail again. But here's some little cartoon. So I created path of notes that takes tea. And then I just asked the files class, Hey, does that path exist? Your false. And they will tell you if that file actually exists in the path that your current working directory that you're running. So let's look at some coming use cases. Let's say we're writing data. So here we see a case for using resolve, right? Somebody has given me a root directory. It's past in our, you know, configured somewhere and I know that in that directory that working directory, whatever it is, I'm looking for the file logs that txt that's where I have to write my data to. And so I take root beer dot resolve the path for logs that takes T. And that gives me this file object, which is the file that I'm supposed to write to. And so here's some methods for files Aiken do delete if exists, so that will obviously deleted if exists, and I can write a string to it. This is one of the simplest ways of writing output to a file. You just give it that path and a big long string to right out to the file and that that's extremely simple. There are, of course, more sophisticated ways to do it. Here's one like suppose I need to write out a multi line file, and I'm capturing those lines in a list. So you see the first line list of you know then that first line, second line, third line, fourth line like that that creates a list of strings, and I'm going to pass that in to the files class now to use this method, the one you need to use here is just called right. So you pass in the path, which is called file. You pass in the list of strings, which is called lines, and then you have to provide these open options and there's ah, we'll examine these Ah, in a moment. But you can use the class standard open option. It's ah, it's an enema I believe in. You have options like create the file, right? The file. If you don't open the file with with write permissions, then it won't actually do the right. And if the filed is existent, won't do create if you're asking for create, so that will write line by line. And, of course, what I'm showing you here is mostly reading and writing strings. But of course, it can also do bite a race for binary files. Okay, these open options were just talking about on the class or the standard open option. There's create only create a new one. So if you use, create new and the file already exists that will fail, read and write a pendant truncate. There's a handful of others, but those are the main ones there that you need to know about. And while we're talking about parameter rised arguments for some of these functions, a lot of the methods that take character data like strings and lists of strings and stuff like that they have overloads that take char set arguments. Char set stands for character set, and you can parameter eyes the method and tell the files class how you should interpret the data on the disc according to what character said. And so there's another class called standard char sets, which has a handful of these pre defined on the most common ones. Utf eight us. Ask E. I saw 88 59 1 utf 16 and two or three others that are on there. These are the probably the most important. Um, otherwise, the char set class has a look up method where you can pass in sort of a nice so identifier , and it will look up the char set and see if Java actually has it. But they do guarantee that these handful of ones that are on standard char sets because their standard, um, that this chart sets always exist. Okay, back to the files class. So let's read some data OK, so get the path the same way. And then we say you can say something like read all lines and that will read in a list of strings for you, Right? So if your files not too big, you can do that. Um, also, if your files pretty small, you can read it in as a single strength. So he reads the entire file as one string if you call the read String method. And of course, there's other overloads that read by Teres so they can read the bites out of the file. Alright, what about creating files in directories? Well, it's all pretty straightforward. Create directory, create directories. If there's any missing parent directories, it will create those for you so that by the time you're done, you're you have the full tree created. Um, you have create Sorry, you have create file here which, um, obviously creates file and you can pass in those some of those options. I believe Teoh create the file of different ways. Um, file permissions are a bit of a Harry thing because they're different from file system to file system. So let's talk about Lennox, which is going to be the most common one. Um, we have a class called posits file permission. So in order to Teoh, use these further there's a multi step pop process. First you have to create a set of permissions, and you can do that by using, um, these static public variables on posits file permission. Class like Owner Read owner, Right, you know, Group read group group Execute World Read World Right All that and you could just create a set. It's a little bit awkward. You can also create them from strings like the one you see there and if you're used. Lennox, those air very familiar to you read right, execute for the the owner, the group and the rest of the world, right? So then the deposits file permissions class will parse that out and create a set posits fall permission objects. Then you have to turn that into a file attributes by using this other invocation posits file permissions as file attributes, passing your set of permissions. Then you get your file attributes object in that you can use in the create directory. So that's a bit of ah, it's a bit of a hall there, And the reason for this is that, um, file permissions are very sensitive to implementation, right? You may know, like Windows is really different than, uh, then Lennox. And so they tried to make it flexible to handle every single file system that you might come across, and as a result, it got really, really complicated like this. And there's a bunch of others methods that you can find on the files class. Does this file exist? Is it directory? Is that a file? Is it executed? Elicit, assembling, cause it rideable. Is it readable? On and on and on. There's a whole bunch of these files files methods that you can use to query the file system. And I just encourage you to look at the files class when you start doing Io and you can see everything there that is available for you. Okay, One other thing that files conduce is move files from one path to another, and again, you need standard copy options. There, for example, replace the existing one so that if if there's a file there already by the same name, you copy over it, and copying looks exactly the same ways they files that copy from one path source to another path destination. All right, Now, here's where it gets a little bit interesting. There are some overloads of the copy method where the source could be an input stream or the destination could be an output stream. And you might be saying, Well, wait, What? What's an input stream? Alpa Stream. We didn't talk about that. Okay? You're right. We didn't talk about that. This is part of the, um, older filed at the Iot system in Java. And so, uh, the fact that files that copy can take input streams and outputs dreams is kind of our link . One of our links back to the original IO system that's in Java. So let's take a look at what that means. The streams. I mean, maybe legacy is too strong a word, but it's from the original. The pre existing java dot io package and there's input stream in output stream and an input stream is something you can read. Bites from an output stream is something you can write bytes to, and you can do it one at a time or as an array. Um, one of the curiosities here is on input stream when you do read, it doesn't come back as a bite. It comes back as an int, and I'm not 100% sure why that is. I'm sure there's an explanation, but it just is. You could always cast it to a bite if you need a single bite. But I think generally you be reading into an array of bytes both of these air abstract classes so you can't in Stan. She ate them on their own, yet to use a subclass, which actually has a source or a sink of data. And so what might those be? Well, the main types you're going to come across for input streams. Ah, bite, array, input stream. So that is, you create an array of bytes in memory, and then you feed that to a bite array input stream, and it turns it into an input stream that you can read from file input stream, Of course, and then a piped input stream works with its counterpart on the other side, the pipe to help its dream for like different threads in a program or different parts of a program to talk to each other and pipe data through memory But there's also a bite array output stream in a file up its dream. Of course, now, if you're doing character based data like strings and chars, there are specialized classes for that called reader and writer and these Air 10 problem. Unless you're doing binary file access, you'll probably be using these more than industry. Malp it stream, but they do that the same thing. Read and write character, raise or strings again. The read comes back as an into instead of a char, so you have to cast it or convert it in some way. If you want a single char and the same as before, their abstract class is very analogous to input stream output stream. And here are the types of readers and writers. Ah, you can read and write from a character array from a file from a string. Or you can make a reader out of an input stream and a writer out of Anel put stream. So if you had an input stream, which returns bites and you wrap that with an input stream reader and I'll show you what I mean by that in just a minute, it's gonna convert those bites in the characters because now you have a reader instead of a stream right. And if your writing and your writing strings to an output stream reader, it's going to convert those strings into bites before it sends them to the output stream. So that those classes or your bridge between the readers and the streams for readers and writers, I guess in streams. All right, so what I mean by wrapping, we come to this big problem that we have about composing functionality. So, yeah, I want to read from a file. But, you know, the data zipped up, so I wanna unzip it first. And then I want to read, You know, the strings that air in there, Um, and knowing that I want to read it lame by lying to, and that's a bunch of stuff that you'll have to build out. Um, and that's very This kind of stuff is very common. And so there's this pattern that's utilized by the Iot package called decorator, So let's see what how that works. This is often a source of confusion for people who are just starting on this. So how does the decorator work? So let's Let's be fucked. The problem here When I'm reading and writing from a file, I may want to compress the data on compressed, sedated, encrypted. Decrypt it. I may want to supply security before I allow them to access the data. Or I may want to log what I would have read or written. And how am I gonna accomplish all that so I could write this one Giant it says, writing class with giant file writer class that does all these things I can think of and then have have methods like enable compression, enable decompression enable encryption enabled decryption. Um, that sounds pretty horrible, right? And whenever you think of a new functionality you want to add, you have to open up this gigantic class that does 50 things and add number 51. And I hope you don't break anything or you could make sub classes. So it's like, OK, have a file reader that I have a compressing file reader and un compressing file reader, an encrypting file reader and a decrypting file reader, and on and on and on. But what if I want to compress and decrypt? Well, I could have a compressing, decrypting file reader and then an un compressing, encrypting file reader in an UN compressing security forward, you start to have a cross product of all these possible extra functionality. So you and operating a lot of sub classes and writing the same code over and over. And not only that, let's make it worse. I want to switch the order. So sometimes I want to compress first and then log and other times when a long first, and then compress. So my am I really gonna have the logging compressing reader and then the compressing logging reader. I mean that that sounds pretty horrible, right? So the decorator pattern is a solution to this idea of like ala cart functionality that you want to add to a base class. You want to add ala cart functionality from a menu as many or as few as you want, and in any order that you want. The decorator pilot pattern solves this problem, and here's what it looks like. So we've got your base writer class or interface. And then here's two of the extra functionalities logging and compressing. All right, so first of all, what makes a decorator decorator? Well, it implements that base interface. So, writer, I know in real life writers in abstract class. But let's just pretend it's an interface here. So improvement implements writer so that has the same right method that any other writer has. But then what's this other line mean? The other line means it also contains a reference to a writer. It's got to Arabs connecting. You might be looking at this and saying, Say what? Let's look at the code. So here's what Ah, logging decorator that most simplistic version might look like. So it implements the interface, right? We said it would do that, and so down below you see the right method because that's what comes along with the writer in your face. And then when you constructed, you pass in the delegate And that delegate, if you look at the attributes at the top, is also a writer, right? So you see, we've got we've got to reference. It's a writer implements writer, and then it's got a delegate, a typewriter, and when you right a string, then when you call right on this decorator, the first thing it does is do your personal thing. You're a logging decorators so you'd log right? So system out Pentland writing a line and then it prints out the line. Once you're done with your particular function, you pass it on to the next delegate. And that delegate, for example, could be a file writer said the file writer will take the string then and them write it to the file or the next one could be a compressing writer or compressing decorator. And it might compress it and then pass it on to its delegate, which could be the file writer. Or could be, you know, when encrypting decorator or something like that. And so in the end, you end up with something like this. You see the on the bottom right here. You see, the compressing decorator has ah reference. The logging decorator has reference to the file writer. They're all writers the way you were constructed and code looks like this. You create your you know, the quote unquote true writer, the base writer, the thing that actually writes to the the Iot system in this case of file writer. And then when you create the logging director, you wrap that ah file writer up by passing it into the constructor. So now the reference called Logger, is a logging direct decorator that contains a reference to a file writer. Then you pass that logger into the constructor of the compressing decorator. So now the compressing decorator, the compressor is a compressing decorator that points to a logging decorator that points to a file writer. And you get that little diagram that you see on the bottom right hand side. And so, of course you can. You can see how you could put a Szmyd any of these on as you want. You could log and then compress and encrypt, and then you could log again if that's what you wanted to do. Or you could double the order in whatever word you want them to be in just by changing the order that you create them and how you pass them in the constructor. All right, so this is what you see in in Decorator, and this is what you see in the java dot io package. So what are the common decorators, while probably the most important ones of the buffered reader and writer and the buffered reader has this the distinction of having the method read a single line. So you know commonly what you might want to do is open up a text file and read it line by line. Okay, You need the buffered reader for that on the other decorator. Some of them are buffered input and output streams. So just you know, generally, if you're talking to something external to your program, it's good to buffer input and output so that you don't end up waiting or, ah, overwhelming system, an external system. There's data input and output streams and what those are is. They convert Java primitives like imagers and floats and things like that into a byte stream and and from a byte stream back into primitive. So that's they go together. And that's a very useful way to rate a set of job of primitives to a binary file and then read it again. Later on, there's G zip input and output stream. There's also a zip input and output stream, and there's a handful of other ones that are probably less common. But you can use all these decorators in the pattern that I just showed you in the previous light, and you can write your own. You can subclass output stream, for example, and attach a longer. If that's what you wanted to do or something that counts the number of bytes. Maybe you want to know precisely how many how many characters or how many bites were written. You could put a by counting writer decorator and wrap that around your output streams or something like that. Okay, so putting this all together, this is a long discussion. Um, here's how you read lines from a text fell. Create a file reader on your filing. My file, that tax so that fr wrap that in a buffered reader using the decorator pattern. And then the buffered reader has the method called read line. And so now you can repeatedly call read line until the buffered readers empty and returns null and ah, then you've read in the entire file. Now, what if I don't have a file name? What if I just have a path? Well, path, it turns out, has a method called to file which creates a file object which is, you know, paths. Ah, you know, grandfather, whatever. And then the file reader has a constructor that takes in a file object and So this is basically a bridge from the new Io system to the old IO system. Right? And so what is this file class? So file was the workhorse before we had path. All right? And if you look at the file UML picture here, you see the, um methods like, for example, get absolute path, get name, get parent, etcetera. These air is exactly the same methods that are on the path class, right? They didn't even change the method names because they're good method names. Um and so you see, that file contains the ability to logically manipulate ah path structure for ah, directory or a file on the file system. But it also has methods like can read can write, you know, exists make directories is directory. So those all require you going to the disc, right, actually accessing the hard drive and so that in the new io, that's the domain of the files class. So in some sense, the old java dot io That file is like the new new io path and files kind of mixed up together, jumbled together. And so it's a better design what they did in New io, where they separated, sort of the physical manipulation from the logical manipulation. All right, One other thing you should know about with the with the sort of old Io is and And this will be a problem, too, with new Io is getting sometimes getting streams or getting handles on files you want is difficult, and especially if it's in your jar file. So Java applications air typically shipped as a jar file, which is just a zip file format of all the classes that air compiled in all the libraries that go with the, uh, with your project and in that set of class files, you may also have some configuration files or property files or, you know, some of their data files that you want toe package up with your project and send it along. So how do you get at that? You can't really use a path. There were filed very easily to get them because they're not on the file system there inside a jar file, right? So one of the common ways to get at these is using class and class loader because they have methods called get resource extreme. So what does that mean? Let's take a look. So here I get my time inside of some object somewhere. And I used this reference. I say this don't get class to get my class object. The class object has a method called get resource as stream, you can pass ah, file name to it or file path, and it returns an industry, Uh, which is then You can use that in all the methods that we just looked at for reading it, writing it, etcetera. I guess you probably can't write to internally to a jar file. You can only read you can. Also, every class object has a class loader object which allows you to get resource a stream again with another path, uh, name here and then another way of getting class loader. And it's This is safer If you're in a multi threaded environment, like in an application server or something, you say thread dot current thread that get class letter, actually that maybe get context class letter. Think I forgot something there, but again, get resource that stream. It's a class loader, and you can use that. So just one thing to be aware of is that they treat the path of the class in the class loader class resolved things a little bit differently. Class loader dot get resource is stream if you pass it a relative path like we did here in this 1st 1 actually, both both of these class loaders have relative path. So conflict that properties data slash props that XML these air resolved relative to the root of the class path. So it's gonna look for config doubt properties in the default package. It's gonna look for props that XML and the data package regardless of where you were in your code when you called class litter, get resource is stream. If you try to use an absolute path, you started with a forward slash like slash data slash props that will blow up on you. Um, in the other hand, from class dot Get resource that stream. If you give it a relative path like we did up here, it's gonna look in the path starting from the package that this class is located in, right. So if this was in the package, let's say game like we used for our project, then it would looking game dot some package. Look for the file file dot txt. All right, if you give class a absolute path starting with the Ford Slash, it will resolve from the root of the class path. So that could be because the methods air named the same. That can be a little bit confusing. Sometimes it's like, Hey, this used to work and it doesn't now it to be careful if you're calling Class Loader or class. Okay, so that's a lot of information. There's still a couple more things I think you should know about Io. Um, so let's get through these last two. So two more things to talk about one is property files, which is a kind of proprietary form of configuration, or maybe not proprietary, but the standard form, a configuration for Java. And then there's logging, I say. Let's take a quick peek at property files. Um, Java just has this standard format for configuration properties, and it's a file where you have key value pairs. Um, the key values are separated by Coghlan's or equal signs, and generally the keys have dot separated parts. That's not really necessary, but it's extremely common, and also the property files are usually named. You know something dot properties again, Not necessary. It will work if you name it something else. But that's generally help. People name them its convention. And of course, now, knowing what we know from all the slides we just looked at, we know we could find this. My props, that properties on the disc created path used the files class reading the file, all the strings, all the lines of strings split the strings on Colon's. And then, you know, look up the data that we're looking for. But the good news is you don't have to because there is a class called Properties, which is made for reading property files. And if you look at the UML chart here, you see there's methods like load and store. Okay, lists prints out the contents of the file. There's get property and set property andan. The other thing that's worth calling out is there is a constructor that takes it just says defaults. But the defaults is another properties object. And so what that does if you call get property and the current property object doesn't have the property you're asking for, It goes, it looks in the defaults. That's a really nice set of functions. You have super easy to use. This, like theeighties a little bit odd, though. First you created properties object and it's empty, and then you call load on that object and you pass in. Ah, reader of some sort. So here i 12. 12 Conclusion: Okay, welcome to Chapter 12 the conclusion of part two of the professional Java class. So just remember, we're in the middle of a three part series. You just finished the 1st 2 parts. If you started from the beginning, there's still one part left to go. Let's review all the things we learned in this Ah feature packed park too. So we started off by talking about packages in the class path and how that affects how you write your code and help what that means with public and private modifiers and things like that. We then went on to talk about java dot langdon object, which, if you remember, that's a super class of every object that you create in job. It's always at the top of the higher game. We looked at the methods on javelin object and what that means for your code. We talked about static methods and attributes, and we even looked at patterns like the singleton pattern, which you can construct with statics. Then we went in deeper into the collection framework. We talked about lists previously, but in this case we looked at sets and maps and queues and decks, and we went through all those different types of collections that we looked at the various implementations and what features they have. And ah, it's really collections is quite a complicated framework. Then we went on and talked about exceptions, and we talked about runtime exceptions versus checked exceptions and the try catch, block, try, catch, finally block the throws, keyword and how to create your own exceptions. Then we looked at Denham's, and after that we looked at some of the core library. So we looked in the java dot lang package of me. We pulled out some of the classes that were most important to your programming, your everyday work and kind of examined those and see what capabilities they had. Then we did the same thing for job with that you tell Package which, of course, it. Its main claim to fame is that it hosts the collections framework. But there's still a bunch of other interesting classes in there that we went over for a job that you tell, and then, with a little more detail, we went over the job of that time package, which has jobs new way of dealing with dates, times, date times, local date. Time zone daytime's ah, what else? Periods and durations and all that is a fairly complex framework, but very beautifully put together. And then finally, in the last marathon chapter that we did, we talked about input output. And so we talked about the n i O package, with its path and files classes as the Ming to workhorses you'll use than the Iot package with the job that you tilled up our job, that I have that file package class. And then we talked about property files and the properties class. And then we even got into a little bit the Java framework Java Util. Logging the Jewell logging framework. So if you got all the way through Part two, congratulations. That's a lot of material to get through, and I'm sure it took you know, some concentration to do that. So congratulate yourself when getting this far, and hopefully you'll stick around for a part. Three. Part three is where we really get into some of the really interesting stuff that's in modern Java. Um, we're gonna talk about generics, which, of course, we've run into every time we've used collections. We see the generic, um, syntax but I haven't really talked about like what exactly does that mean? And what are the implications of that? It's actually quite complicated. And then we're going to talk about something that was introduced in Java eight, which is Lambda is and Streams. And these two things together, I would say, have completely revolutionized Java programming. It doesn't look anything like pre Java A programming anymore. It's really way more powerful. Um, and then we'll talk about annotations, which we've also seen some annotations. But imitations are significant enough that they're do talking about. And then the big bad job, a module system which was introduced in Java nine and impacts that's gonna have on how you write code. So I hope that all sounds interesting to you. I'm certainly interested in talking about all those things with you, and I hope to see you in part three of this class. Take care