
In this video, I am installing Visual Studio Code. VSCode is a free program that is really nice for working with just about every programming language you want, from html, css, and javascript to C#, Java, and Python.
The rest of this course will not use VSCode, but you are free to use it if you would like. I would recommend having this handy for other coding, not just Java, and the integrated terminal is nice for running powershell and GIT as well as working with C# or Java.
In order to work with Java, we need to have the SDK up and running on our machine. This video is me installing the latest version (jdk 15.0.2) at the time of this recording.
If for some reason you can't get this to work, please just install Eclipse and skip this command line section. In the end, you just need to be able to run the code somewhere.
This video walks us through setting up our windows machine to compile and run a program. For this video, you'll want to get the file "ManualCheck.java" and make sure to place it somewhere on your computer that is easy to access, such as the desktop.
Make sure to follow along with me in the video to complete the steps for manual programming, which make sure we are ready to go for writing java programs on our machine.
This video shows us how to write our very first program, the standard "Hello World" text printing program. Although we haven't covered syntax to this point, the program is simple and straight-forward.
To maximize your learning from this course, I highly recommend that follow along and perform all of the actions which I am performing in the demonstration. This will help you to learn the material, understand what is truly going on, make mistakes from which you can learn, and ultimately retain the knowledge from these instructional videos.
Although we will have a working file 'HelloWorld.' by the end of this lesson, I am not including the file for download on purpose. This will encourage you to create the file on your own. Additionally, if you have any mistakes, you'll have to fix them. Hopefully you will find this a simple and useful activity.
Please note: If you are using the Java 7 SDK, you will need to select the default folder installation path for the Java 7 version you are on, instead of java 6. Use that path when working with the environment and/or manual programming to execute the javac compiler and java runtime executable programs.
In this video, we take a moment to purposefully break our helloworld program, thereby giving us the opportunity to see errors as they happen at compile time, and learn how we might respond to the errors. This demonstration also shows us how programming manually can be more complicated than programming with an IDE due to the feedback not happening as quickly when we make an error.
By purposefully breaking our code, we get used to seeing some errors that we might encounter later. The experience of having broken the code and seeing the direct result may help us to fix errors later when we encounter similar messages from the compiler.
Please note: You will need to select the default folder installation path for the Java version you are on, including the correct current update number . Use that path when working with the environment and/or manual programming to execute the javac compiler and java runtime executable programs.
This video shows a demonstration of installing the Eclipse IDE (which you may choose to use for the remainder of our course; new videos I produce will use this IDE going forward as I no longer use Netbeans - however every java program we write in this course can be done in any Java IDE, including both Netbeans and Eclipse).
This video shows a demonstration of installing the Netbeans IDE (which you may choose to use for the remainder of our course; old videos use this IDE, new will not).
After installation, we'll quickly create a HelloWorld project to make sure everything is working and see how a powerful IDE can be beneficial to any programmer.
This video shows how to quickly create a project in either NetBeans or Eclipse. Going forward, the lecture resources [files] will be available as *.java files. Therefore, you'll be creating your own project and just importing the resource files.
The files attached for this video are actually going to be used in the next video as well, so this will give you a head start on setting up your project for the next video, and will highlight the idea of creating your own project to work along-side of me as we go through the lectures together.
All of the code for section 1 is contained here. Additionally, you should find the required code for each individual lesson attached with the specific lesson.
This video is done on a lecture whiteboard, which can be difficult to write on at times so some of the handwriting may be a bit tricky to read.
This video is the first of two parts to discuss storing types in variables and working with the types in code.
In this video, we go over the Number types of Integer [int], Long [long], Float [float], and Double [double].
This is the second part of our introduction to types. In this lecture, we discuss the non-number types of Character [char], String [String], and Boolean [boolean].
In this video, we continue with coding examples for storing and using types in variables. This video focuses on the non-number types of Character [char], String [String], and Boolean [boolean].
This video starts our look at a couple of different methods for gathering input from the user. The first method involves using the java.util.Scanner, which makes it necessary for us to import the java.util.Scanner or java.util.* package. This video focuses on the use of the Scanner, and we'll mostly use the Scanner object in our course.
In this video, we take a look at another way to gather input - using the BufferedReader object.
If you are taking a course and have an assignment due that does a simple input - calculate - output type of operation, this is a good place to stop and complete the program. If you need to take user input and make decisions or change the calculation algorithm based on the user input, you should continue on to week 3 (section 3) to gain knowledge of decision statements and loops.
In this final video for section two, we do another exercise in gathering user input as well as handling the input by storing it in a variable and then ultimately placing the information into the correct location in the Sudoku grid. Finally, we print out the grid with the user input correctly placed in the grid.
As stated in the video, the game is not playable at this point, nor is it intended to be. We are still learning from the ground up, and positioning ourselves to be able to build the game in a way that it can be played later.
The more we repeat these activities, the better we get at them, so practicing different exercises like this is a really good way to enhance our learning, even though it's just a short and seemingly trivial activity.
Recursion is shown in this video using the Fibonacci sequence, which is one of the most famous sequences.
This week we enhance the density calculations, adding both the ability to validate user input and also the ability to take any of the three density variables as an unknown and solve the equation accordingly. Additionally, all user input in the main algorithm is validated.
The challenge at the end of this lesson is to be able to finish off the rest of the calculators to prevent invalid input as well as to be able to take one of the variables as an unknown and calculate the equation accordingly.
Lastly, as it is important to create a quick exit from the looping for our demonstration, we get to see our first Easter Egg programmed into our code, which allows us to know a "cheat code" to quickly and accurately solve the puzzle!
In this lesson, we spend time planning the things we need to handle in order to build code to keep score during the card game 500. Special care is taken to validate input to gather the correct bid information and calculate the overall score for both teams after each round (iteration).
Seeing it all come together in this simple, yet robust program, is a good way to close off the section and demonstrate our clear understanding of looping structures.
This lecture is our first real computer science discussion, as we take a solid look at the difference between how regular variables are only copied and used in multiple places of memory, thereby not being prone to referencing errors, while complex objects such as arrays (and classes next section) are referenced directly in memory. The by value types (ints, booleans, Strings) don't get changed in methods when they are passed to a method, however the by-reference types are just a memory pointer, which means the same object is "referenced" and therefore, the changes made to a referenced object in a method actually affect the object that was created in the calling method as well as the object inside of the called method.
As an update to this, I want to point out that there is actually no such thing as "Passing variables by Reference" in Java. In fact, everything is passed "By Value." What actually happens is the variables for complex types are passed as By Value pointers that point to the address in memory of the complex types. This is why we see some behavior where complex objects are modified when the variables are passed to a method. For more information on this, please see this video that I did for O'Reilly:
https://www.oreilly.com/learning/is-java-pass-by-reference-or-pass-by-value
In this video, we're going to start from the ground up to examine what it takes to work with our own custom classes in Java.
I will be doing Unit Testing as we go, even though we haven't covered that just yet. If you want to watch the JUnit section to get a better idea of what is going on, you are welcome to do so, but we're going to move through everything from the ground up, so you should be able to work along with me through the section.
I will encourage you to not just watch the videos, but to actually work them with me. If you need to pause the video and come back, don't be afraid to do it! As each video in this section will build on the previous video, make sure you are good with the material before moving on to the next.
In this video, we begin our look at custom classes by creating our class Vehicle and looking at the implicit default constructor that comes as part of the class.
We also setup unit testing to make sure that we can test our Vehicle class.
In this video, we begin our look at using properties in our custom classes.
Properties are also called "getters and setters" or, more officially, "mutators and accessors"
We need to have the properties in order to work with the object to set values for things like the "VIN, make, model, mileage, and year"
In this video, we continue our look at the properties for our custom class, and finish up all the properties and testing on our Vehicle class.
In this video, we take a look at creating the explicit constructor for our vehicle class. The nice thing about the explicit constructor is that we can actually create and pass state to the object at the same time. We also need to test for this, of course.
In addition to constructors and properties, we also often need to work with custom methods in our classes. In this video, we go over what it takes to write some custom methods and then test to validate they are working as expected.
In this video, we begin a two-part lecture on what inheritance is, how we use it, and why it is a powerful tool in object-oriented programming.
In this video, we conclude our two-part look at inheritance.
In this video, we begin working with inheritance by adding classes for Car and Truck that will eventually directly inherit from the Vehicle class using the "extends" keyword. For now, we put them in as their own classes to see what it would be like without inheritance.
In this video, we just take a final look at what it would be like if we didn't use inheritance in our system for the Vehicle, Truck, and Car classes. We also look at how we have no ability to work with the code using 'polymorphism' -> which is the ability to treat objects of a common super type in a similar fashion, regardless of their underlying subtype.
In the next two videos, we'll transform our system into a system that leverages inheritance.
We'll begin by making both the Car and Truck be a subclass to the superclass "Vehicle". We'll do this by using the "extends" keyword, which is a critical keyword to understand class relationships.
In this video, we complete our look at using the "extends" keyword to transform the Car and Truck into subclasses (or subtypes) of the superclass Vehicle (or supertype). We also make sure all of our testing is in place and include the ability to work with unique properties on the Car and make sure that we can see how the inheritance changes our ability to program to all of the types using polymorphism
In this video, we discuss what it means to "Override" a superclass method. We'll override the 'toString()' method that exists on all objects in Java to make it more useful for what we would like to accomplish in our Vehicle system.
In this video, we discuss a strategy for testing the toString() methods for each of the classes, appropriately.
In this video, we take our first look at what it means to "overload" methods. This is different than overriding, and it is critical to understand the differences between the two terms.
By overloading, we present methods with the same name but different parameter lists. This gives us options as to how we would like to work with our object classes.
This is the code for section 6.
FYI - As of 2018.01.23 I've updated the videos. The code is currently available on GitHub in releases. I will be posting information about that as well as physical copies of the code soon.
Finally, if you start from the top and work down through lecture 70, you should not need any of my code, and working through it on your own would help you learn the concepts. I get it that some of you might want to start in the middle, or validate your code against mine, which is why I'll post some physical copies soon.
This lecture begins our Putting It All Together lesson for section 7. For the first part, we'll build a class to manage vehicles as a system with the ability to find, add, and remove vehicles from the system. We'll also look at figuring out how to identify a few pitfalls and examine a few strategies to prevent the user from causing errors. For the system, we'll use the concept of polymorphism, and therefore the autolot will be coded to the interface, not to some specific type (for example, we only have one add method, not one for each type of vehicle, but one that handles all types of vehicles).
This lesson completes our examination of the autolot system. In part two, we build the driver (which is a console-based GUI) to interact with the autolot system. We discuss how this style of coding has helped us to build a system that allows us to reuse the Autolot code in other GUIs when we have learned how to work with them (such as websites).
This lesson takes a look at the Starships that we were building in section 6. In this code, we learn how to implement the comparable interface so objects can be compared (which allows for sorting). Additionally, we discuss overriding the equals() method so we can easily call to the .equals() method to compare objects for equality.
This lecture covers an advanced topic -- the Strategy Design Pattern. This is a simple introduction, but gives us a new idea to consider when coding: Coding a behavior. To this point, everything we've coded has been a tangible object. By coding behaviors, we can interchange behaviors in our code without having to write separate classes. We dive into this and build two behavior interfaces, one for propulsion and one for weaponry, then we implement three propulsion behaviors and two weaponry behaviors.
Please note that if you are taking your first course as a programmer this topic will probably be beyond the scope of the course you are taking. I am assuming, however, that most all of you taking this course will be continuing on to harder courses as well as pursuing programming as a career. Therefore, you will most likely encounter this idea in the future. If you don't need it for your current course, keep it in the back of your mind, because it will be good to know, even if you never need it for a course.
The final lecture for section seven makes a couple of critical changes to the Sudoku program. The overall algorithm for the code and gameplay is not changed, however we add in a system called GameSystem that will ultimately allow us to have 10 games, with Sudoku being one of them. We create an interface for Game and implement a GameShell abstract class to handle the common code. Sudoku extends GameShell which makes it also a Game by default.
In this lecture we also create a player object to track common properties for players of all the games in the game system.
We then change the Sudoku code to no longer reference the main method and ultimately implement the code in the play() method, as well as to have one player object to track the Sudoku player.
Please find the code for section 7 attached.
This video is the first part of two parts of an introduction to testing. In this part, we go over some of the major arguments against testing and talk about how testing is actually very important, even if there is a bit more work up front.
In this video, we conclude our introduction to testing by discussing some testing strategies and the unit testing methodologies. We also look at the different assertions and how we'll use assertions to pass or fail the unit tests.
In this video, we go over creation of the unit tests in Eclipse and start our Person object and testing on the Person object, working from the ground up. After we get the test class and JUnit libraries in place, we begin our testing by testing the Person class constructors.
There are two sets of files for this video. The starter pack and the finished code. I highly recommend starting with the starter pack and working along with me. If you get stuck, there are some text files that contain finished versions of the code in both projects. If you are pressed for time and just want to review, or if you have completed the video and want to check your work, take a look at the finished version to compare results or see the end result of this part of the project.
In this video, we continue our look at testing by adding the tests and then coding the accessors (getters) and mutators (setters) for our Person class instance variables.
As before, there are two sets of files for this part of the project. I again recommend using the starter pack and working along with me. The finished version is there for your convenience as well.
In this video, we continue testing our Person object by writing the tests to verify the toString() method is working as expected.
We'll just verify toString() contains our expected property values using the contains method of the String class. If you need to do more thorough testing, like validating a specific format, you could do that here as well.
As before, there are two sets of files for this part of the project. I again recommend using the starter pack and working along with me. The finished version is there for your convenience as well.
In this video, we start our examination of how we'll go about testing the Comparable interface, which will implement in the Person class. This method can sometimes be tricky to implement, so we'll take some time planning before we get started. Some good things to think about will be what inputs can be sent to the method, what specific values we want to return, and what the order of precedence will be for determining if one person is greater than, less than, or equal to another person.
Comparable is an important interface to implement when we are going to be ordering objects. It is very conceivable that an object like person would need to be ordered by last name, then first name, and sometimes we'll care about age as well. We take all three into account in this class.
Please find the planning spreadsheet and pdf/Word Document that I used attached to this video for your reference.
In this video, we go over the implementation of the Comparable interface and take the time to work through some of the testing. The amount of testing needed would go far too long for the video, so a set of instructions exists that allows you to follow through with creating all the tests and learn more about the TDD process.
As with the other testing sessions, I recommend getting the starter pack and working through to the end. The finished code is also available for you to review.
In this video, we take the time to discuss how the equals method works, and how we can override it and test it in our Person class. Once again, we'll benefit from our grid that helps us see which cases we really need to focus on for comparing to determine if two Person objects are equal.
In this video, we go over the coding and testing for overriding the equals() method in the person class. Once again, we use our plan to determine that all code paths are covered and that the method is working as expected with valid testing.
This lecture describes an advanced testing concept: abstract testing. In this lecture, we convert the Person class to an abstract class and then use that as a base class for three other class objects. We then show how we can leverage abstract testing using the factory design pattern to create a base test class that tests common function and is leveraged in the sub-test classes. This is an advanced concept which may not be needed as an introductory programmer, but I want to make sure everyone is aware that this possibility exists.
In this lecture, we create testing on our AutoLot system. We again use some abstract testing, however you could just continue to unit test each class individually if the abstract testing concept with the factory pattern is too complex at this time. The testing helps us to iron out a couple of bugs that existed in the AutoLot code, and is our first chance to see some real good testing where we have a full system that needs testing other than just basic class object testing.
The final lecture for section 8 gives us the ability to see some testing in action in our Sudoku class. Some of the class is left untested due to the complex nature and the amount of time it would take to write the tests on the classes. Additionally, this is the only version of the testing where we leave the default Netbeans testing syntax in place (not using the extension of Junit and leaving the @Test directives in place in the code).
This video is a quick overview of some of the differences between JUnit 3 and JUnit 4. The good news, you can keep doing everything you've done before in JUnit3 in JUnit 4 if you want to. In this video, we look at some of the differences between how the JUnit 4 syntax uses things like attributes while the JUnit3 syntax does not. Although the videos have not gone over exceptions at this point, one of the biggest differences is testing exceptions. Therefore, you may choose to work through Section 9 first, and then come back to watch this video once you are fully familiar with Exceptions.
Our first lecture in section nine is an introduction to exceptions. This introduction walks us through the different types of exceptions that exist and how we can leverage them in our code. We've seen many of the Runtime Exceptions already, and during this section we're going to learn how to write better code that keeps our programs from encountering 'hard faults' or 'hard stops' that occur when a runtime exception breaks our code. We'll also talk about Checked and Custom exceptions, take a good look at the try...catch...finally block, and look at how we might go about testing exceptions when they occur in code. Finally, a look at the hierarchy will show us how the Exception types are organized, which is critical when building proper try..catch blocks. All of the concepts presented in this introduction will be examined and explained in the lectures for section nine, so this is a great place to start when learning about exceptions, and may be a good reference to come back to as we become more familiar with exception types, try/catch/finally blocks, and testing exceptions.
Our first lecture with code dives into the subject of unchecked exceptions (runtime exceptions). Unchecked exceptions are Runtime Exceptions or extensions of the runtime exception class. During the lecture, we'll look at four of the most common runtime exceptions and develop code that causes these exceptions and use try..catch..finally blocks to prevent hard faults (or hard stops) in our programs. By the end of the lecture, we'll see how we can code to prevent runtime exceptions from causing our programs to break during execution, as well as start to understand how to recover from runtime exceptions and even being to dive into the hierarchical nature of the try..catch..finally blocks.
Lecture three for section nine gives us our first look at Checked Exceptions. The main way we'll interact with Checked Exceptions in our course is through files -- which we'll talk about in Section 10. With that in mind, this is a quick look and shows how the compiler will act when Checked Exceptions are encountered. A critical difference is also pointed out for when to use throws vs. when to use throw.
Lecture four for section nine shows how we can write our own Exception types that extend the RuntimeException object, and can be thrown and caught as needed. The second part of the lecture dives into how we go about testing the Exception object and also test the code that throws exceptions to make sure that Exceptions occur when they are supposed to.
This lecture takes a look at how we test exceptions in JUnit 4. With the new syntax, we can easily tell the test method what exception to expect and allow for the testing of that specific exception.
The person class is modified to throw an IllegalArgumentException when an invalid age or name is encountered. The tests are set up to expect the exception to happen, first with valid code to fail the test and make sure the test does not succeed when good code is passed that does not throw an exception, then the line of code that causes the exception is added to make sure the exception is thrown as expected.
Remember not to put any code in the test after the line of code that causes the exception, because the JUnit 4 syntax prevents the code from executing once an exception is encountered.
Our PIAT lecture for this section continues the AutoLot coding and uses exception handling, illegal argument exceptions, and a custom exception "MustRefuelException" to put all of the concepts together that we have learned about using exceptions during section nine. We'll see everything except the checked exceptions come into play in this system, including using try..catch...finally blocks, using a custom exception, using illegal arguments to prevent bad input, and testing to make sure that our exceptions are working as planned. We'll also use try..catch blocks and some crafty looping to make sure that user input is exactly correct in our "GUI" program (the Driver). Now that we have completed the learning on exception handling, our code is becoming much more robust.
Our final lecture for section nine gives us yet another look at creating a custom exception type (the SudokuGridCellException) as well as using try..catch to handle exceptions, testing that exceptions happen as expected, and a final look at throwing new illegal argument exceptions when the user has provided invalid parameters to a method.
The first lecture of Section 10 gives us an introduction into working with files by showing how to read from files in a couple of different ways. Things to note are that there are multiple ways to work with the files and each works equally well. We also get to run into some of the checked exceptions that we didn't really see last week. Our first file readers just open a text file and read the test and print it out either with all capital letters or all small letters. The main ways to open and read files are illustrated through the use of the FileReader and BufferedReader object, as well as the File and Scanner objects, and the distinctive way each combination needs to work to access all the data correctly from the file.
Our second lecture this week dives into writing to text files. As with reading files, there are multiple ways to write to a file so we take a look at a couple of them. The first way we write to the file is with the FileWriter itself. The second way involves decorating the FileWriter with a BufferedWriter. The final way uses a Printwriter with a File object. All three methods to this point have been wiping out the file and re-creating it with the new output. The final demonstration for this lecture shows how we can append text to the end of an existing file.
In this video, we get to start putting everything we've learned this section to the test. We'll use file readers and writers to open a file and read the text. We'll then work with that text to perform a cipher-shift on each character and save the result to a text file. In this manner, we get to see a very simple encryption example that we could easily do with some file I/O. Unfortunately, this encryption is not at all secure, so we won't be using it to protect any sensitve information anytime soon.
In this video, we learn a bit about what Serialization is, and how to serialize our custom objects in java. We'll implement the Serializable interface on our custom code and then create a doctor object that we'll save to a file as a stream. Finally, we'll restore the doctor object from the stream and compare to see if it is equal to the original object.
This second look at an encryption program lets us use the fact that we now understand how to translate our object into a stream of bytes. By serializing the object and putting it into a stream, we are then able to easily change the data by performing a shift at the byte level. Once we do this, files become unreadable and even unusable in their native form in some cases (we've corrupted the file). We can easily get back to our original file by simply performing the decoding of the data by shifting each byte back to where it was. Here we show how to encrypt our text message file, and we also show how we can change a .jpg image into an unusable file that won't display as a picture until we decode it.
For our final new topic on opening, reading, and writing to files, we take a look at Random Access Files. There are some critical points to note about Random Access Files. First, these files are binary, so they can save state. Second, they are the only type of file in Java that allows us to both read from and write to the file. They also provide the only mechanism for traversing through the file in any direction other than forward and in any order (hence: random access). The key idea is to determine the size of the data in the file and then use the file pointer to move to the next record location. It is then easy to pull data from that location or to overwrite the existing data with updated data directly for just one distinct record. This lecture is a little more computer science oriented and may be more advanced than some introductory courses would require, but this is good information to know and is part of the File I/O objects in Java, so I felt it was important to cover Random Access Files and how to work with them.
In this lecture we take a short detour from working with files to see how we can work with Strings to pull the data from a formatted string, either with a pipe (|) or comma (,) delimiter. We take a look at two methods that can be used by the programmer to do this. The first method is to use the .split() function of a String object. This object automatically creates a String[] with each token from the split String in a separate index in the array. The other note about this option is that the .split function requires the use of a regular expression in Java. Regular Expressions are beyond the scope of our course, but I encourage you to read about them to find out what they are and how they work.
The second method for parsing out data from a formatted String is to use the StringTokenizer object. Unlike Split, we don't get direct access to each token at index, however we get an object that can easily be iterated and used to pull each token in order for use in our code.
During our lecture we also make note of the usefulness of these methods, the differences between the two, and how using one of them should easily allow us to bulk load some data in our systems, such as the autolot program.
Our "Putting It All Together" lecture this week shows how to use the information we've learned so far with files and serialization. The main changes to our program allow us to easily save and restore the state of our AutoLot system. This makes it possible to provide a way for the dealer to be able to store their work and not have to enter vehicles every time they want to work with the system. Additionally, we provide a new "bulkload" function, which reads a pipe-delimited file containing data about some vehicles. By adding in this functionality, a dealer could now easily load a new set of vehicles without having to create each vehicle individually. In the end, our program becomes much more user-friendly and powerful with these simple additions.
Our final lecture for section ten involves using the tools we've learned to save and restore the state of a game in progress. Now that we can serialize objects and store them in a file, we can easily make the grid and all of it's items serializable. When the user enters SAVE we can then save the current state of the grid to the default backup file. Typing RESTORE allows the user to easily start from where they last saved a grid in progress.
This course provides instruction through video lectures and materials which will teach (you) the student how to program in Java from the very basic level to an intermediate level of programming. The intent is to aid anyone who is struggling in learning how to program and would like to see practical examples and demonstrations. This course is not affiliated with any university and will not provide answers to any homework assignments for any reason. Topics covered will include but not be limited to:
In the end, this course is a stand-alone course, however it would be a huge aid to the online student who is taking a self-directed course, an individual who is trying to learn how to program, or even a high school student looking to get a head start on computer science material they might encounter in college. The material is organized in a start-to-finish fashion, building on knowledge with each section, so it is best to proceed through each section in order. Each section should amount to about a week worth of learning, lining up with most popular online course formats. Additionally, the course works hard to build practical knowledge that will help a student excel in their coursework, and also builds a strong foundation for a start to a career in programming for anyone looking to learn!
As an added bonus, several useful programs are built throughout this course, and the end result of the course includes full source code for a working Sudoku game, amongst other programs, such as card game score calculators and basics physics formula calculation programs.