{"id":15042907,"url":"https://github.com/in28minutes/java-tutorial-for-beginners","last_synced_at":"2025-05-15T08:08:57.200Z","repository":{"id":39415639,"uuid":"182059398","full_name":"in28minutes/java-tutorial-for-beginners","owner":"in28minutes","description":"Java Tutorial For Beginners with 500 Code Examples","archived":false,"fork":false,"pushed_at":"2023-11-26T21:01:07.000Z","size":1335,"stargazers_count":1557,"open_issues_count":13,"forks_count":1461,"subscribers_count":83,"default_branch":"master","last_synced_at":"2025-04-07T03:13:57.900Z","etag":null,"topics":["java","java-8","java8","programming","programming-challenges","programming-fundamentals"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/in28minutes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-04-18T09:34:41.000Z","updated_at":"2025-04-06T16:24:37.000Z","dependencies_parsed_at":"2024-10-12T15:50:33.867Z","dependency_job_id":null,"html_url":"https://github.com/in28minutes/java-tutorial-for-beginners","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/in28minutes%2Fjava-tutorial-for-beginners","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/in28minutes%2Fjava-tutorial-for-beginners/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/in28minutes%2Fjava-tutorial-for-beginners/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/in28minutes%2Fjava-tutorial-for-beginners/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/in28minutes","download_url":"https://codeload.github.com/in28minutes/java-tutorial-for-beginners/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248889907,"owners_count":21178321,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","java-8","java8","programming","programming-challenges","programming-fundamentals"],"created_at":"2024-09-24T20:48:14.549Z","updated_at":"2025-04-14T13:41:20.464Z","avatar_url":"https://github.com/in28minutes.png","language":null,"readme":"# Java Tutorial For Beginners\n\nWelcome to this book on **\"Learning Java In 150 Steps\"**. \n\nI am **Ranga Karanam**, and I have more than two decades of programming experience. \n\nI love Programming. One of the aims I had when I started ```in28minutes``` was to make learning programming easy. Thanks for helping us provide amazing courses to 300,000 learners across the world.\n\nAt **In28Minutes**, we ask ourselves one question every day: \"How do we create awesome learning experiences?\" \n\nIn this book, you will learn to write **object** **oriented** code with Java. You will be exposed to a lot of examples, exercises and tips. We will take up a lot of examples, and try and see how to write code for those in Java. \n\nHelp us improve this guide - **Fork, Pull Requests, Shares and Likes are recommended**!\n\n## Table of Contents\n\n* [Chapter 01 - Introduction to Programming with Print-Multiplication-Table](#introduction-to-programming-with-print-multiplication-table)\n* [Chapter 02 - Understanding Methods](#understanding-methods)\n* [Chapter 03 - Understanding the Java Platform](#understanding-the-java-platform)\n* [Chapter 04 - Eclipse](#eclipse)\n* [Chapter 05 - Object Oriented Progamming (OOP)](#object-oriented-progamming-oop)\n* [Chapter 06 - Primitive Data Types](#primitive-data-types)\n* [Chapter 07 - Introducing Conditionals - if, switch and more](#introducing-conditionals---if-switch-and-more)\n* [Chapter 08 - Loops](#loops)\n* [Chapter 09 - Reference Types](#reference-types)\n* [Chapter 10 - Arrays and ArrayList](#arrays-and-arraylist)\n* [Chapter 11 - Object Oriented Programming (*OOP*) - Revisited](#object-oriented-programming-oop---revisited)\n* [Chapter 12 - Introducing Collections](#introducing-collections)\n* [Chapter 13 - Introducing Generics](#introducing-generics)\n* [Chapter 14 - Introduction to Functional Programming](#introduction-to-functional-programming)\n* [Chapter 15 - Threads and Concurrency](#threads-and-concurrency)\n* [Chapter 16 - Introduction To Exception handling](#introduction-to-exception-handling)\n* [Chapter 17 - File Operations](#file-operations)\n* [Chapter 18 - Concurrency : Advanced Topics](#concurrency--advanced-topics)\n\n## Our Approach\n\nWe did a study on why students give up on programming?\n\nThe popular answer was\n\n\u003e Difficulty in writing their first program\n\nPut yourselves in the shoes of a beginner and look at this typical ```Java Hello World Example```.\n\n```java\npackage com.in28minutes.firstjavaproject; \npublic class HelloWorld \n{   \n     public static void main(String[] args) {           \n            System.out.println(\"Hello World\");   \n     } \n}\n```\n\nA ```Programming Beginner``` will be overwhelmed by this. I remember how I felt when I saw this almost 20 years back. Stunned.\n\nWhy?\n- There are a number of keywords and concepts - package, public, class, static, void, String[] and a lot more..\n- What if the programmer makes a typo? Will he be able to fix it?\n\n\n**We believe that there has to be a better way to learn programming.**\n\n- Why don't we learn programming step by step? \n- Why should it not be a lot of fun? \n- Why don't we solve a lot of problems and learn programming as a result?\n\nThis is the approach we took to writing this guide and develop our introductory programming courses for Java and Python. \n\n\u003e Do you know? The first 3 hours of our Java Course is available [here](https://courses.in28minutes.com/p/java-tutorial-for-beginner-in-250-steps).\n\n\n\n## Introduction to Programming with Print-Multiplication-Table\n\n### Step 01: First Challenge : The Print-Multiplication-Table (*PMT-Challenge*)\n\nLearning to program is a lot like learning to ride a bicycle. The first few steps are the most challenging ones. \n\nOnce you use this stepwise approach to solve a few problems, it becomes a habit. \n\nIn this book, we will introduce you to Java programming by taking on a few simple problems to start off. \n\n\u003e Having fun along the way is what we will aim to do.\n \n_Are you all geared up, to take on your first programming challenge? **Yes**?  Let's get started then!_\n\nOur first *programming challenge* aims to do, what every kid does in math class: reading out a multiplication table.\n\n#### The *PMT-Challenge*\n\n1. Compute the multiplication table for ```5```, with entries from ```1``` to ```10```.\n2. Display this table.\n\n```\n5 * 1  =  5\n5 * 2  = 10\n5 * 3  = 15\n5 * 4  = 20\n5 * 5  = 25\n5 * 6  = 30\n5 * 7  = 35\n5 * 8  = 40\n5 * 9  = 45\n5 * 10 = 50\n```\n\nAs part of solving the multiplication table problem, you will be introduced to:\n* **JShell**\n* **Statements**\n* **Expressions**\n* **Variables**\n* **Literals**\n* **Conditionals**\n* **Loops**\n* **Methods** \n\n#### Summary\n\nIn this step, we:\n\n* Stated our first programming challenge, *PMT-Challenge*\n* Identified basic Java concepts to learn, to solve this challenge\n\n### Step 02: Introducing ```JShell```\n- - - \n\n```JShell``` is a programming tool, introduced in Java SE 9. JShell is a **_REPL_** interface. The term **REPL** refers to this:\n\n* **_'R'_** stands for **R**ead; *Read* the input Java code\n* **_'E'_** means **E**val; *Evaluate* the source code\n* **_'P'_** translates to **P**rint; *Print* out the result\n* **_'L'_** indicates **L**oop; *Loop* around, and wait for the next input\n\nHow about starting off exploring Java? Are you game?\n\n##### Snippet-1: Check the Java programming environment\n\nYou can use [https://tryjshell.org/](https://tryjshell.org/) to run the code for the first 25 steps. Or you can [Install Java 12+](https://github.com/in28minutes/java-a-course-for-beginners/blob/master/00-02-java-eclipse-installation.md#installing-java). Here's the [troubleshooting section](https://github.com/in28minutes/java-a-course-for-beginners/blob/master/00-02-java-eclipse-installation.md#troubleshooting) if you face problems.\n\nLaunch up command prompt or Terminal.\n\nLet type in ```java -version``` on the terminal and press enter.\n\n```\n\n\tin28minutes$\u003ejava -version\n\tjava version \"x.0.1\"\n\tJava(TM) SE Runtime Environment (build x.0.1+11)\n\tJava HotSpot(TM) 64-bit Server VM (build x.0.1+11, mixed mode)\n\tin28minutes$\u003e\n\n```\n\nA successful execution displays the version of Java installed your system. You need to have atleast Java 9 to pursue this book.\n\n##### Snippet-2: Launch JShell\n\nYou can launch JShell by typing ```jshell``` at your terminal. \n\n```java\n\n\tin28minutes$\u003ejshell\n\n\t|  Welcome to JShell version x.0.1\n \t|  For an introduction type: /help intro\n\tjshell\u003e\n\n```\n\nWhen run, this command displays basic information about the installed ```JShell``` program. A ```jshell``` prompt then appears, which waits for your input.\n\n##### Snippet-3: Sample JShell input, using a built-in command\n\nThe ```JShell``` command ```/help```, with a parameter ```intro```, gives you basic guidelines on how you use the tool.\n\n```java\n\n\tjshell\u003e /help intro\n\n\t|\n\t| intro\n\t| The jshell tool allows you to execute Java code, getting immediate results.\n\t| You can enter a Java definition (variable, method, class, etc), like: int x =8\n\t| or a Java expression, like: x + x\n\t| or a Java statement or import.\n\t| These little chunks of Java code are called 'snippets'.\n\t| There are also jshell commands that allow you to understand and\n\t| control what you are doing, like: /list\n\t|\n\t| For a list of commands: /help\n\t\n\tjshell\u003e\n\n```\n\n\n##### Snippet-4: Evaluating an expression\n\nType ```3+4``` at the Jshell prompt\n\n```java\n\n\tjshell\u003e 3 + 4\n\t$1 ==\u003e 7\n\tjshell\u003e\n\n```\n\nThis was your first real **REPL** cycle! When you type in  ```3 + 4```, JShell evaluates it and prints the result. \n\n\u003e The entity ```$1``` is actually a variable name assigned to the result. We will talk about this later. \n\n##### Snippet-5: Getting out of JShell\n\nThe ```/exit``` command terminates the ```JShell``` program, and we are back to the terminal prompt.\n\n\n```java\n\n\tjshell\u003e /exit\n\t|  Goodbye\n\t\n\tin28minutes$\u003e\n\n```\n\n\n##### Snippet-6: Again, enter JShell and Exit it!\n\nYou can now effortlessly launch, feed code to, and exit from  ```JShell```!\n\n```java\n\n\tin28minutes$\u003e jshell\n\t\n\t|  Welcome to JShell version 9.0.1\n\t|  For an introduction type: /help intro\n\tjshell\u003e /exit\n\t|  Goodbye\n\t\n\tin28minutes$\u003e\n\n```\n\n#### Summary\n\nIn this step, we learned:\n\n* How to launch ```JShell``` from our terminal, and run a few commands on it\n* How to run Java code on the ```JShell``` prompt\n\n### Step 03: Welcome to Problem Solving\n\nLets try to break down the *PMT-Challenge* problem to be able to solve it.\n\n```\n5 * 1  =  5\n5 * 2  = 10\n5 * 3  = 15\n5 * 4  = 20\n5 * 5  = 25\n5 * 6  = 30\n5 * 7  = 35\n5 * 8  = 40\n5 * 9  = 45\n5 * 10 = 50\n```\n\n\nHere is how our draft steps look like\n* Calculate ```5 * 3``` and print result as ```15```\n* Print ```5 * 3 = 15``` (```15``` is result of previous calculation)\n* Do this ten times, once for each table entry (going from ```1``` to ```10```)\n\n#### Summary\n\nIn this step, we:\n\n* Broke down the *PMT-Challenge* problem into sub-problems\n\n### Step 04: Introducing Expressions \n\nThe first part of solving our *PMT-Challenge* is to calculate the product of ```5``` and another number, say ```3```.\n\nLet's start up jshell and type ```5 X 3```.\n\n```java\n\n\tin28minutes$\u003e jshell\n\n\t|  Welcome to JShell version x.0.1\n\t|  For an introduction type: /help intro\n\tjshell\u003e 5 X 3\n\t| Error:\n\t| ';' expected\n\t| 5 X 3\n\t|  ^\n\t| Error:\n\t| not a statement\n\t| 5 X 3\n\t|   ^\n\t| Error:\n\t| ';' expected\n\t| 5 X 3\n\t|    ^\n\t| Error:\n\t| missing return statement\n\t| 5 X 3\n\t| ^---^\n```\nYou probably look at the symbol 'X' as a multiplier, remembering your school days.\n\nJava does not identify '```X```' as the multiplication operator! Java supports multiplication, but only if you use its *predefined* operator, ```*```.\n\nLet's type in code shown below:\n\n```java\n\tjshell\u003e 5 * 3\n\t$1 ==\u003e 15\n\tjshell\u003e\n\n```\n\nSuccess!\n\nLet's look at some terminology:\n- ```5 * 3 ``` is an expression.\n- ```5``` and ```3``` are operands. They are also called **literals** or constant values.\n- ```*``` is an operator.\n\n\nJava also has built-in operators to perform other numerical tasks, such as:\n\n* Addition: ```+``` \n* Subtraction: ```-```\n* Division: ```/```\n* Modulo arithmetic: ```%``` \n\nThe following examples illustrate how to use them.\n \n```java\n\n\tjshell\u003e 5 * 10\n\t$2 ==\u003e 50\n\tjshell\u003e 5 + 10\n\t$3 ==\u003e 15\n\tjshell\u003e 5 - 10\n\t$4 ==\u003e -5\n\tjshell\u003e 10 / 2\n\t$5 ==\u003e 5\n\tjshell\u003e\n\n```\n\nYour school math memories are still fresh, and the operators don't seem to disappoint either! ```+```, ```-``` and ```/``` are your bread-and-butter operators.\n\n```%``` is the modulo operator, which gives you the remainder when integer division is performed. \n\n```java\n\n\tjshell\u003e 9 % 2\n\t$6 ==\u003e 1\n\tjshell\u003e 8 % 2\n\t$7 ==\u003e 0\n\tjshell\u003e\n\n```\n\n##### Snippet: Complex Expressions, Anyone?\n\nJava allows you to use more than one operator within an expression.\n\nLet's look at some simple expressions with multiple operators.\n\n```java\n \n\tjshell\u003e 5 + 5 + 5\n\t$8 ==\u003e 15\n\tjshell\u003e 5 + 10 - 15\n\t$9 ==\u003e 0\n\tjshell\u003e 5 * 5 + 5\n\t$10 ==\u003e 30\n\tjshell\u003e 5 * 15 / 3\n\t$11 ==\u003e 25\n\n```\n\nEach of above expressions have two operators and three operands.\n\n#### Summary\n\nIn this step, we:\n\n* Learned how to construct numeric expressions\n* Discovered that operators are predefined symbols\n* Combined several operators to form larger expressions\n \n### Step 05: Programming Exercise PE-1 (With Solutions)\n\nAt this stage, your smile tells us that you enjoy evaluating Java expressions. What if we tickle your mind a bit, to make sure it hasn't fallen asleep? \n\nOkay, here comes a couple of programming exercises.\n\n1. Write an expression to calculate the number of minutes in a day.\n2. Write an expression to calculate the number of seconds in a day.\n\n#### Solution 1\n\n60 (minutes in an hour) multipled by 24 (hours in a day)\n\n```java\n\n\tjshell\u003e 60 * 24\n\t$1 ==\u003e 1440\n```\n\n#### Solution 2\n\n60 (seconds in a minute) multipled by 60 (minutes in an hour) multipled by 24 (hours in a day)\n\n```java\n$jshell\u003e60 * 60 * 24\n\n$1 ==\u003e 86400\n```\n\n### Step 06: Operators\n\nLets look at a few more examples to understand operators.\n\n#### Invalid Operators\n\nLet's type in ```5 ** 6``` followed by ```5 $ 6``` in JShell\n\n```java\n\tjshell\u003e 5 ** 6\n\t| Error:\n\t| Illegal start of expression\n\t| 5 ** 6\n\t|     ^\n\n\tjshell\u003e 5 $ 6 \n\t| Error:\n\t| ';' expected\n\t| 5 $ 6\n\t|  ^\n\t| Error:\n\t| not a statement\n\t| 5 $ 6\n\t|   ^\n\t| Error:\n\t| ';' expected\n\t| 5 $ 6\n\t|    ^\n\n\tjshell\u003e 5 */ 6\n\t| Error:\n\t| Illegal start of expression\n\t| 5 */ 6\n\t|     ^\n\t\n```\n\n```JShell``` was not impressed with our efforts at all! \n\nJava has a set of grammar rules, called its **syntax**. Code that does not follow these rules throw errors. The compiler informs you by listing the errors, and also provides hints on how you can correct them. \n\nNow, why is an error being thrown?\n\nOperators in Java are all predefined, and limited in number.  ```*``` is a valid operator, whereas ```**``` and ```$```  were rejected, with error messages.\n\n#### Understanding Result of Expression with Mixed Types\n\nLet's look at another example:\n\n```java\n\n\tjshell\u003e 5 / 2\n\t$1 ==\u003e 2\n\tjshell\u003e\n\n```\n\nSurprise, Surprise! ```JShell``` seems to evaluate ``` 5 / 2 ``` to ``` 2 ``` instead of ```2.5```. Where did we go wrong?\n\nRead what follows, with the biggest magnifying lens you can find:\n\n**The result of an expression when evaluated, depends on the operator context**. This context is determined by the operands passed to it\n\nThere are two kinds of numbers typically used in programming : integer (1,2,3,...) and floating-point (1.1,2.3, 56.7889 etc). These values are represented by different **types** in Java. Integers are commonly of type ```int```, and the floating-point numbers are ```double``` by default.\n\nIn the expression ```5/2```, both ```5``` and ```2``` are of type ```int```. So, the result is also of type ```int```. \n\nLet's try with a few floating point numbers: \n\n```java\n\n\tjshell\u003e 5.0 / 2.0\n\t$2 ==\u003e 2.5\n```\nBoth ```5.0``` and ```2.0``` are of type ```double```, the result is ```double```. We get a result of ```2.5```, as expected. \n\nLet's do a mixed operation - using a floating point number and integer.\n\n```java\n\tjshell\u003e 5.0 / 2\n\t$3 ==\u003e 2.5\n\tjshell\u003e\n\n```\n\nAmong the types ```int``` and ```double```, ```double``` is considered to be a *wider type*. When you perform a numeric operation between two types, the result will be of the wider type.\n\n\n\n#### Understanding Precedence of Operators\n\nLet's look at few complex examples of expressions with more than one operator.\n\n```java\n\n\tjshell\u003e 5 + 5 * 6\n\t$1 ==\u003e 35\n\tjshell\u003e 5 - 2 * 2\n\t$2 ==\u003e 1\n\tjshell\u003e 5 - 2 / 2\n\t$3 ==\u003e 4\n\tjshell\u003e\n\n```\n\nSurprised with the results?  You might expect 5 + 5 * 6 evaluate to 10 * 6 i.e. 60. Howeever, we got ```35```! \n\n\u003e We write English left-to-right, and carry this habit to calculations as well. \n\n_In expressions with multiple operators, the order of sub-expression evaluation depends on **operator precedence**._\n\nThe basic rules for operator precedence are actually quite simple (we will look at other rules a little later). \n\nThe operators in the set  {```*```, ```/```, ```%```} have higher precedence than the operators in the set {```+```, ```-```}.\n\nIn the expression ```5 + 5 * 6``` : 5*6 is evaluated first. So, 5 + 5 * 6 becomes 5 + 30 i.e. 35.\n\n```5 - 2 * 2``` and ```5 - 2 / 2``` are evaluated by following the same rules.\n\n#### Use paranthesis for clear code \n\nJava provides syntax elements, called **parentheses** ```(```   and   ```)```, to group parts of an expression.\n\n```java\n\n\tjshell\u003e (5 - 2) * 2\n\t$4 ==\u003e 6\n\tjshell\u003e 5 - (2 * 2)\n\t$5 ==\u003e 1\n\tjshell\u003e\n\n```\n\nWhen you put an expression in parenthesis, it is evaluated first. (5 - 2) * 2 =\u003e 3 * 2 =\u003e 6.\n\nParentheses lead to better readability as they reduce confusion and help avoid errors. \n\nThe old adage **_A stitch in time saves nine_** rings very true here. Use parentheses to make your code easy to read, even when they might not be necessary.\n\n#### Summary\n\nIn this step, we:\n\n* Discovered that operators are all predefined\n* Learned that result of operation depends on operand types\n* Understood what operator precedence means\n* Used parentheses to group parts of an expression\n \n### Step 07: Introducing Console Output \n\nWe have computed the product of two literals (as in ```5 * 3```) in earlier steps. \n\nThe next step is to print this result in a customized format - ```5 * 3 = 15```.\n\nHow do we do this?\n\nLet try typing it in into JShell\n\n```java\njshell\u003e 5 * 3 = 15\n|  Error:\n|  unexpected type\n|    required: variable\n|    found:    value\n|  5 * 3 = 15\n|  ^---^\n```\n\nHmm! Error.\n\nHow do we print text?\n\nJava has a built-in utility method called ```System.out.println()```, that displays text on the console. \n\n```java\njshell\u003e System.out.println(3*4)\n12\n```\n\nWe formed an expression, ```3*4```, and *passed* it to ```System.out.println()```, which is a built-in Java **method**.\n\n```System.out.println(3*4)``` is an example of a **statement**. It is a **method call**.\n\nThe syntax rules for method calls are quite strict, and all its parts are mandatory.\n\n```java\njshell\u003e System.out.println3*4)\n| Error:\n| ';' expected\n| System.out.println3*4)\n|___________________^\n| Error:\n| cannot find symbol\n|       symbol: variable println3\n| System.out.println3*4)\n| ^---------------------^\n\njshell\u003e System.out.println 3*4\n|  Error:\n|  ';' expected\n|  System.out.println 3*4\n|                    ^\n|  Error:\n|  cannot find symbol\n|    symbol:   variable println\n|  System.out.println 3*4\n|  ^----------------^\n\n```\n\nWhat if we want to print an entry of the Multiplication Table, as part of our solution to *PMT-Challenge*? In other words, how do we print the exact text ```5 * 2 = 10``` on the console? \n\n```java\n\n\tjshell\u003e System.out.println(5 * 2 = 10)\n\t| Error:\n\t| unexpected type\n\t| required:  variable\n\t| found:     value\n\t| System.out.println(5 * 2 = 10)\n\t|____________________^--------^\n\n```\n\nYou wanted to print ```5 * 2 = 10``` on the console. However, we see that we cannot pass ```5 * 2 = 10``` as an argument to ```System.out.println()```.\n\n```5 * 2 = 10``` is not a single value. It is a piece of text with numeric characters, ```*``` and ```=```. \n\nIn Java, we represent text using ```String```. A ```String literal``` is a sequence of characters, enclosed within **double quotes**: ```\"``` and ```\"```. \n\n```java\n\tjshell\u003e System.out.println(\"5 * 2 = 10\")\n\t| 5 * 2 = 10\n```\n\nCongratulations! You have now figured out how to display not just numbers on the console, but text as well!\n\n#### Summary\n\nIn this step, we:\n\n* Were introduced to the ```System.out.println()``` method for console output\n* Used this utility to print a single *PMT-Challenge* table entry\n\n### Step 08: Programming Exercise PE-02\n\nTry and solve the following exercises:\n\n1. Print ```Hello World``` onto the console.\n\n2. Print ```5 * 3```, as is.\n\n3. Print the calculated value of ```5 * 3```.\n\n4. Print the number of seconds in a day, using the ```System.out.println``` method.\n\n5. Do a syntax revision for the code that you write for each of the above exercises. In your code, identify the following elements:\n\t* Numeric and string literals\n\t* Expressions\n\t* Operators\n\t* Operands\n\t* Method calls\n\n### Step 09: Solutions to PE-02\n\n#### Solution 1\n\n```java\n\n\tjshell\u003e System.out.println(\"Hello World\")\n\tHello World\n\n```\n\n#### Solution 2\n\n```java\n\n\tjshell\u003e System.out.println(\"5 * 3\")\n\t5 * 3\n\tjshell\u003e\n```\n\n#### Solution 3\n\n```java\n\n\tjshell\u003e System.out.println(5 * 3)\n\t15\n\n```\n\n#### Solution 4\n\n```java\n\n\tjshell\u003e System.out.println(60 * 60 * 24)\n\t86400\n\n```\n\n### Step 10: Whitespace, Case sensitiveness and Escape Characters\nThe term *whitespace* refers to any sequence of continuous space, tab or newline characters.\n\n#### Whitespace\n\nLet's see a few examples of whitespace in action.\n\nWhitespace affects the output when used in-and-around string literals.\n\n```java\njshell\u003e System.out.println(\"Hello World\")\nHello World\njshell\u003e System.out.println(\"Hello      World\")\nHello      World\njshell\u003e System.out.println(\"HelloWorld\")\nHelloWorld\n```\n\n\nWhitespace is ignored by the compiler when used around numeric expressions. \n```java\n\n\tjshell\u003e System.out.println(24 * 60 * 60)\n\t86400\n\tjshell\u003e System.out.println(24    *    60    *    60)\n\t86400\n\tjshell\u003e\n\n```\n\n#### Case Sensitive\n\nJava is case sensitive.\n\n```System.out.println()``` involve pre-defined Java elements : the ```System``` **class** name, the ```out``` **variable** name,and the  ```println``` **method** name. All are *case-sensitive*. If any character in these names is used with a different case, you get an error. \n\n```java\n\n\tjshell\u003e system.out.println(\"Hello World\")\n\t| Error:\n\t| package system does not exist\n\t| system.out.println(\"Hello World\")\n\t| ^-------^\n\n\tjshell\u003e System.Out.println(\"Hello World\")\n\t| Error:\n\t| cannot find symbol\n\t| symbol: variable Out\n\t| System.Out.println(\"Hello World\")\n\t| ^------------^\n\n\tjshell\u003e System.out.Println(\"Hello World\")\n\t| Error:\n\t| cannot find symbol\n\t| symbol: method Println(java.lang.string)\n\t| System.out.Println(\"Hello World\")\n\t| ^---------------------^\n\n\tjshell\u003e\n\n```\n\n Inside a string literal, the case of characters do not cause errors. The literal will be taken in and printed, as-is.\n\n```java\njshell\u003e System.out.println(\"hello world\")\nhello world\njshell\u003e System.out.println(\"HELLO WORLD\")\nHELLO WORLD\n```\n\n#### Escape Characters\n\nAn **escape character** is a special symbol, used with another regular symbol to form an **escape sequence**. In Java, the '```\\```' (*back-slash*) character plays the role of an escape character. This escape sequence changes the original usage of the symbols.\n\nIf you want to print the string **delimiter**, the ```\"``` character, you need to escape it with a ```\\```. Without it, a ```\"``` character within a string literal causes an error!\n\n```java\n\n\tjshell\u003e System.out.println(\"Hello \"World\")\n\t| Error:\n\t| ')' expected\n\t| System.out.println(\"Hello \"World\")\n\t|                            ^\n\n\tjshell\u003e System.out.println(\"Hello \\\"World\")\n\tHello \"World\n\tjshell\u003e\n\n```\n\nThe escape sequence ```\\n``` inserts a *newline*.\n```java\n\njshell\u003e System. out.println(\"Hello \\n World\")\nHello\n World\njshell\u003e System.out.println(\"Hello n World\")\nHello n World\njshell\u003e System.out.println(\"Hello\\nWorld\")\nHello \nWorld\njshell\u003e\n\n```\n\nThe escape sequence ```\\t``` inserts a *tab*.\n```java\n\n\tjshell\u003e System.out.println(\"Hello \\t World\")\n\tHello    World\n\tjshell\u003e System.out.println(\"Hello t World\")\n\tHello t World\n\tjshell\u003e System.out.println(\"Hello\\tWorld\")\n\tHello    World\n\tjshell\u003e\n\n```\n\nHow do you print a ```\\```?\n\n```\njshell\u003e System.out.println(\"Hello \\ World\")\n|  Error:\n|  illegal escape character\n|  System.out.println(\"Hello \\ World\")\n```\n\nYou would need to escape it with another ```\\```. Printing ```\\\\``` outputs  the symbol ```\\``` to the console.\n\n```java\n\n\tjshell\u003e System.out.println(\"Hello \\\\ World\")\n\tHello \\ World\n\tjshell\u003e System.out.println(\"Hello \\\\\\\\ World\")\n\tHello \\\\ World\n\n```\n\n\n#### Summary\n\nIn this step, we:\n\n* Were introduced to method call syntax, with ```System.out.println()```\n* Discovered the uses of whitespace characters\n* Learned about Java escape sequences \n\n### Step 11: More On Method Calls\n\nLet's look at method calls with a few more examples.\n\nYou know how to invoke a method with a single argument, courtesy ```System.out.println(3*4)```. Other scenarios do exist, such as \n* Calling a method without any arguments\n* Calling a method with several arguments\n\nLet's check them out, using the built-in methods in Java ```Math``` class. \n\n\n#### Method without parameters\n\nIn method calls, parentheses are a necessary part of the syntax. Don't leave them out!\n\n```Math.random()``` prints a random real number in the range ```[0 .. 1]```, a different one on each call\n\n```java\n\n\tjshell\u003e Math.random\n\t| Error:\n\t| cannot find symbol\n\t|    symbol: Math.random\n\t| Math.random\n\t| ^------------- ^\n\tjshell\u003e Math.random()\n\t$1 ==\u003e 0.0424279106074651_\n\tjshell\u003e Math.random()\n\t$2 ==\u003e 0.8696879746593543 \n\tjshell\u003e Math.random()\n\t$3 ==\u003e 0.8913591586787125\n```\n\n\n#### Method with multiple parameters\n\nHow do we call ```Math.min``` with two parameters ```23``` and ```45```?\n\n```java\n\n\tjshell\u003e Math.min 23 45\n\t| Error\n\t| cannot find symbol\n\t| symbol: variable min\n\t| Math.min 23 45\n\t| ^---------^\n\tjshell\u003e Math.min(23 45)\n\t| Error\n\t| ')' expected\n\t| Math.min 23 45\n\t| ---------------^\n```\n\nWhile making method calls, the programmer must \n* Enclose all the parameters within parentheses\n* Separate individual parameters within the list, using the comma symbol '```,```'.\n\n```java\n\tjshell\u003e Math.min(23, 45)\n\t$4 ==\u003e 23\n\tjshell\u003e Math.min(23, 2)\n\t$5 ==\u003e 2\n\tjshell\u003e Math.max(23, 45)\n\t$6 ==\u003e 45\n\tjshell\u003e Math.max(23, 2)\n\t$7 ==\u003e 2\n\tjshell\u003e\n\n```\n\n```Math.min()``` returns the minimum of two given numbers. ```Math.max()``` returns the maximum of two given numbers.\n\n\n#### Summary\n\nIn this step, we:\n* Understood how zero, or multiple parameters are passed during a method call\n\n### Step 12: More Formatted Output\n\n```System.out.println()``` can accept one value as an argument at a maximum. \n\nTo display the multiplication table for ```5``` with a calculated value, we need a way to print both numbers and strings. \n\nFor this we would need to use another built-in method ```System.out.printf()```.\n\nWhen ```System.out.printf()``` is called with a *single* string argument, it prints some illegible information. For now, it suffices to know, that this information is about the built-in type  ```java.io.PrintStream```.\n\n```java\n\tjshell\u003e System.out.printf(\"5 * 2 = 10\")\n\t5 * 2 = 10$1 ==\u003e java.io.PrintStream@4e1d422d\n\tjshell\u003e\n\n```\n\nThe good news is, that if we call the ```println()``` method on this, the illegible stuff disappears.\n\n```java\n\n\tjshell\u003e System.out.printf(\"5 * 2 = 10\").println()\n\t5 * 2 = 10\n```\n\nThe method ```System.out.printf()``` accepts a variable number of arguments:\n* The first argument specifies the print format. This is a string literal, having zero or more **format specifiers**. A format specifier is a predefined literal (such as ```%d```), that formats data of a particular type (```%d``` formats data of type ```int```).\n* The trailing arguments are expressions,\n\nLots of theory? Let's break it down.  Let's look at an example.\n```java\n\tjshell\u003e System.out.printf(\"5 * 2 = %d\", 5*2).println()\n\t5 * 2 = 10\n\tjshell\u003e\n\n```\n```System.out.printf(\"5 * 2 = %d\", 5*2).println()``` gives an output ```5 * 2 = 10```.  ```%d``` is replaced by the calculated value of ```5*2```.\n\nLet's play a little more with ```printf```:\n\n```java\n\n\tjshell\u003e System.out.printf(\"%d %d %d\", 5, 7, 5).println()\n\t5 7 5\n```\n\nLet's try to display a calculated value. In the example below ```5*7``` is calculated as ```35```.\n```java\n\tjshell\u003e System.out.printf(\"%d %d %d\", 5, 7, 5*7).println()\n\t5 7 35\n```\n\nLet's use this to print the output in the format that we want to use for multiplication table:\n\n```java\n\tjshell\u003e System.out.printf(\"%d * %d = %d\", 5, 7, 5*7).println()\n\t5 * 7 = 35\n```\n\nCongratulations. We are able to calculate ```5*7``` and print ```5 * 7 = 35``` successfully.\n\n#### Exercise\n\n1. Print the following output on the console: ```5 + 6 + 7 = 18```. Use three literals ```5```, ```6```, ```7```. Calculate 18 as ```5 + 6 + 7```.\n\n#### Solution\n\n```java\n\n\tjshell\u003e System.out.printf(\"%d + %d + %d = %d\", 5, 6, 7, 5 + 6 + 7).println()\n\t5 + 6 + 7 = 18\n\tjshell\u003e\n\n```\n\n#### Playing with ```System.out.printf()```\n\nIn the example below, there are four format specifiers (```%d```) and only three value arguments ```5, 6, 7```.\n\n```java\n\n\tjshell\u003e System.out.printf(\"%d + %d + %d = %d\", 5, 6, 7).println()\n\t5 + 6 + 7 = | java.util.MissingFormatArgumentException thrown: Format specifier '%d'\n\t| at Formatter.format (Formatter.java:2580)\n\t| at PrintStream.format (PrintStream.java:974)\n\t| at PrintStream.printf (PrintStream.java:870)\n\t| at (#52:1)\n```\n\nIn a call to ```System.out.printf()```, if the number of format specifiers exceeds the number of trailing arguments, the Java run-time throws an *exception*.\n\n\nIf the number of format specifiers is less than the number of trailing arguments, the compiler simply ignores the excess ones.\n\n```java\n\n\tjshell\u003e System.out.printf(\"%d + %d + %d\", 5, 6, 7, 8).println()\n\t5 + 6 + 7\n\tjshell\u003e\n\n```\n\n#### More Format Specifiers\n\nString values can be printed in ```System.out.printf()```, using the format specifier ```%s```.\n\n```java\n\n\tjshell\u003e System.out.printf(\"Print %s\", \"Testing\").println()\n\tPrint Testing\n\n```\n\nEarlier, we used %d to print an ```int``` value. You cannot use %d to display floating point values. \n```java\n\tjshell\u003e System.out.printf(\"%d + %d + %d\", 5.5, 6.5, 7.5).println()\n\t| java.util.IllegalFormatConversionException thrown: d != java.lang.Double\n\t| at Formatter$FormatSpecifier.failedConversion(Formatter.java:4331)\n\t| at Formatter$FormatSpecifier.printInteger(Formatter.java:2846)\n\t| at Formatter$FormatSpecifier.print(Formatter.java:2800)\n\t| at Formatter.format(Formatter.java:2581)\n\t| at PrintStream.format(PrintStream.java:974)\n\t| at PrintStream.print(PrintStream.java:870)\n\t| at #(57:1)\n\n```\n\nFloating point literals (or expressions) can be formatted using ```%f```.\n```java\n\n\tjshell\u003e System.out.printf(\"%f + %f + %f\", 5.5, 6.5, 7.5).println()\n\t5.500000 + 6.500000 + 7.500000\n\tjshell\u003e\n\n```\n\n#### Summary\n\nIn this step, we:\n\n* Discovered how to do formatted output, using ```System.out.printf()```\n* Stressed on the number and sequence of arguments for formatting\n* Explored the built-in format specifiers for primitive types\n\n### Step 13: Introducing Variables\n\nIn the previous steps, we worked out how to print a calculated value as part of our multiplication table.\n\n```java\n\tjshell\u003e System.out.printf(\"%d * %d = %d\", 5, 1, 5 * 1).println()\n\t5 * 1 = 5\n```\n\n**How do we print the entire multiplication table?**\n\nWe can do something like this.\n\n```java\n\tjshell\u003e System.out.printf(\"%d * %d = %d\", 5, 1, 5 * 1).println()\n\t5 * 1 = 5\n\tjshell\u003e System.out.printf(\"%d * %d = %d\", 5, 2, 5 * 2).println()\n\t5 * 2 = 10\n\tjshell\u003e System.out.printf(\"%d * %d = %d\", 5, 3, 5 * 3).println()\n\t5 * 3 = 15\n\tjshell\u003e System.out.printf(\"%d * %d = %d\", 5, 4, 5 * 4).println()\n\t5 * 4 = 20\n\tjshell\u003e\n\n```\n\nToo much work. Isn't it?\n\nIf you carefully observe the code, these statements are very similar. \n\n***What's changing?*** The number in the third and fourth parameter slots changes from 1 to 4.\n\nWouldn't it be great to have something to represent the changing value? \n\n***Welcome variables.***\n\n```java\n\n\tjshell\u003e int number = 10\n\tnumber ==\u003e 10\n\tjshell\u003e\n\n```\n\n#### Terminology and Background\n\nIn the statement ```int number = 10```,  \n* ```number``` is a **variable**. \n* The literal ```number``` is the variable **name**.\n* The Java *keyword* ```int``` specifies the **type** of ```number```.\n* The literal ```10``` provided ```number``` with an **initial value**. \n* This entire statement is a **variable definition**.\n\nThe effects of this variable definition are:\n* A specific location in the computer's memory is reserved for ```number```.\n* This location can now hold data of type ```int```.\n* The value ```10``` is stored here.\n\nYou can change the value of number variable:\n```java\n\n\tjshell\u003e number = 11\n\tnumber ==\u003e 11\n```\n\nAbove statement is called  variable **assignment**. \n\nAn assignment causes the value stored in the memory location to change. In this case, ```10``` is replaced with the value ```11```.\n\nYou can look up the value of number variable.\n```java\n\tjshell\u003e number\n\tnumber ==\u003e 11\n```\n\nYou can change the value of a variable multiple times.\n```\n\tjshell\u003e number = 12\n\tnumber ==\u003e 12\n\tjshell\u003e number\n\tnumber ==\u003e 12\n\n```\n\nLet's create another variable:\n\t\n```java\n\n\tjshell\u003e int number2 = 100\n\tnumber2 ==\u003e 100\n\tjshell\u003e number2 = 101\n\tnumber2 ==\u003e 101\n\tjshell\u003e number2\n\tnumber2 ==\u003e 101\n\tjshell\u003e\n\n```\n\nThe statement ```int number2 = 100``` defines a *distinct* variable ```number2```. \n\n***How do we use variables to simplify and improve the solution to *PMT-Challenge*?*** \n\nLet's take a look.\n\n```java\n\n\tjshell\u003e System.out.printf(\"%d * %d = %d\", 5, 4, 5*4).println()\n\t5 * 4 = 20\n```\n\nLet's define a variable ```i```, and initialize it to ```1```.\n```java\n\tjshell\u003eint i = 1\n\ti ==\u003e 1\n\tjshell\u003e i\n\ti ==\u003e 1\n\tjshell\u003e 5*i\n\t$1 ==\u003e 5\n```\n\nLet's update the multiplication table printf to use the variable i.\n```java\n\tjshell\u003e System.out.printf(\"%d * %d = %d\", 5, i, 5*i).println()\n\t5 * 1 = 5\n```\n\n***How do we print ```5 * 2 = 10```?***\n\nWe update ```i``` to ```2``` and execute the same code as before. \n\n```java\n\n\tjshell\u003e i = 2\n\ti ==\u003e 2\n\tjshell\u003e 5*i\n\t$2 ==\u003e 10\n\tjshell\u003e System.out.printf(\"%d * %d = %d\", 5, i, 5*i).println()\n\t5 * 2 = 10\n\tjshell\u003e\n\n```\n\nYou can update the value of ```i``` to any number. \n\nThe previous statement would print the corresponding multiple with 5.\n\n```java\n\n\tjshell\u003e i = 3\n\ti ==\u003e 3\n\tjshell\u003e System.out.printf(\"%d * %d = %d\", 5, i, 5*i).println()\n\t5 * 3 = 15\n\tjshell\u003e i = 10\n\ti ==\u003e 10_\n\tjshell\u003e System.out.printf(\"%d * %d = %d\", 5, i, 5*i).println()\n\t5 * 10 = 50\n\tjshell\u003e\n\n```\n\nBy varying the value of ```i```, we are able to print different multiples of 5 with the same statement.\n\nCongratulations! You made a major discovery. Variables.\n\n#### Summary\n\nIn this step, we:\n\n* Understood the need for variables\n* Observed what different parts of a variable definition mean\n* Seen what goes on behind-the-scenes when a variable is defined\n\n### Step 14: Programming Exercise PE-03 (With solution)\n\n1. Create three integer variables ```a```, ```b``` and ```c```. \n\t* Write a statement to print the sum of these three variables.\n\t* Change the value of ```a```, and then print this sum.\n\t* Then again, change the value of ```b``` and print this sum.\n\n#### Solution to PE-03\n\n```java \n\n\tjshell\u003eint a = 5\n\ta ==\u003e 5\n\tjshell\u003eint b = 7\n\tb ==\u003e 7\n\tjshell\u003eint c = 11\n\tc ==\u003e 11\n\tjshell\u003eSystem.out.printf(\"a + b + c = %d\", a+b+c).println()\n\ta + b + c = 23\n\tjshell\u003ea = 2\n\ta ==\u003e 2\n\tjshell\u003eSystem.out.printf(\"a + b + c = %d\", a+b+c).println()\n\ta + b + c = 20\n\tjshell\u003eb = 9\n\tb ==\u003e 9\n\tjshell\u003eSystem.out.printf(\"a + b + c = %d\", a+b+c).println()\n\ta + b + c = 22\n\tjshell\u003e\n\t\n```\n\n### Step 15: Using Variables\n\nVariables should be declared before use.\n\n```java\n\n\tjshell\u003enewVariable\n\t| Error:\n\t| cannot find symbol\n\t| symbol: newVariable\n\t| newVariable\n\t  ^------------^\n```\n\nJava is a **strongly typed** programming language. This means two things:\n* Every variable in a program must be declared, with a type.\n* Values assigned to a variable should be:\n\t* same type as the variable's type, or\n\t* **compatible** with the variable's type\n\n```java\n\n\tjshell\u003e int number = 5.5\n\t| Error:\n\t| incompatible types: possible lossy conversion from double to int\n\t| int number = 5.5\n\t|_____________^---^\n\tjshell\u003e\n\n```\n\nThe variable ```number``` is an integer, mathematically a  number. The constant ```5.5``` is a number as well. \n\nWhy does it result in error?\n\t\n```5.5``` is a floating-point number of type ```double```. We are trying to store a ```double``` inside a memory slot meant for ```int```.\n\nLet's consider another example:\n\n```java\n\n\tjshell\u003e int number = \"Hello World\"\n\t| Error:\n\t| incompatible types: java.lang.String cannot be converted to int\n\t| int number = \"Hello World\"\n\t|_____________^--------------^\n\tjshell\u003e\n\n```\n```number``` is an ```int``` variable, and we are trying to store a ```String``` value ```\"Hello World\"```. ***Not allowed.***\n\n#### Summary\n\nIn this step, we:\n\n* Observed how declaring a variable is important\n* Understood the compatibility rules for basic Java types  \n\n### Step 16: Variables: Behind-The-Scenes\n\nGiving a value to a variable, during its declaration, is called its initialization. \n\n```java\n\n\tjshell\u003e int number = 5\n\tnumber ==\u003e 5\n\tjshell\u003e\n\n```\n\nThe statement ```int number = 5``` combines a declaration and the initialization of ```number```.\n\nThe next statement ```int number2 =  number``` is a little different. \n\n```java\n\n\tjshell\u003e int number2 = number\n\tnumber2 ==\u003e 5\n\tjshell\u003e number2\n\tnumber2 ==\u003e 5\n\tjshell\u003e\n\n```\n\nThe initial value for ```number2``` is another variable, which is previously defined (```number```). \n\nHere's what goes on behind the scenes with ```int number2 = number```:\n* A memory slot is allocated for ```number2``` with size of ```int```.\n* Value stored in ```number```'s slot is copied to ```number2```'s slot.\n\nIn example below, ```a = 100```, ```c = a + b```, ``` a = c``` are called ```assignments```.\n\n```java\n\n\tjshell\u003e int a = 5\n\ta ==\u003e 5\n\tjshell\u003e int b = 10\n\tb ==\u003e 10\n\tjshell\u003e a = 100\n\ta ==\u003e 100\n\tjshell\u003e int c\n\tc ==\u003e 0\n\tjshell\u003e c = a + b\n\tc ==\u003e 110\n\tjshell\u003e a = c\n\ta ==\u003e 110\n\tjshell\u003e int d = b + c\n\td ==\u003e 120\n\tjshell\u003e\n\n```\n\nVariable **assignment** is allowed to happen in multiple ways:\n* From a literal value, to a variable, having compatible types. The statement ```a = 100``` is one such example.\n* From a variable to another variable, of compatible types.The statement ```a = c``` illustrates this case.\n* From a variable expression to a variable. This expression can be formed with  variables and literals of compatible types, and is evaluated before the assignment. The statement ```c = a + b```below is an example of this.\n\nAn assignment to a constant literal is **not allowed**. \n```java\n\n\tjshell\u003e 20 = var\n\t| Error:\n\t| unexpected type\n\t| required : variable\n\t| found : value\n\t| 20 = var\n\t| ^^\n\n\tjshell\u003e\n\n```\n \n#### Summary\n\nIn this step, we discussed how to provide variables with initial values and the basics of assigment.\n\n### Step 17: Naming Variables \n\nThe syntax rules for variable definition are quite strict. Do we have any freedom with the way we name variables? The answer is \"yes\", to some extent. \n\n### Variable Name Rules\n\nHere are the Java rules for variable names, in a nutshell:\n\nA variable name can be a sequence, in any order, of\n* Letters [```A-Z, a-z```]\n* Numerical digits [```0-9```]\n* The special characters '```$```' (\"dollar\") and '```_```' (\"underscore\")\n\nWith the following exceptions:\n* The name cannot start with a numerical digit [```0-9```]\n* The name must not match with a predefined Java **keyword**\n\nLet's now see what kinds of errors the compiler throws if you violate these naming rules.\n\n***Error : Using a invalid character ```-```***\n\n```java\n\n\tjshell\u003e int test-test\n\t| Error:\n\t| ';' expected\n\t| int test-test\n\t|         ^\n\n```\n\n***Error : Starting name of a variable with a number***\n\n```java\n\n\tjshell\u003e int 2test\n\t| Error:\n\t| '.class' expected \n\t| int 2test\n\t|     ^\n\t| Error:\n\t| not a statement\n\t| int 2test\n\t|      ^--^\n\t| Error:\n\t| unexpected type\n\t| required: value\n\t| found: class\n\t| int 2test\n\t| ^--^\n\t| Error:\n\t| missing return statement\n\t| int 2test\n\t| ^-------^\n\n\tjshell\u003e\n\n```\n\n***Error : Using a keyword as the name of variable***\n\nIn Java, certain special words are called ```keywords```. For example, some of the data types we looked at - ```int```, ```double```. These ```keywords``` cannot be used as variable names.\n\n```java\n\n\tjshell\u003e int int\n\t   ...\u003e ;\t\n\t| Error:\n\t| '.class' expected\n\t| int int\n\t|     ^\n\t| Error:\n\t| unexpected type\n\t| required: value\n\t| found: class\n\t| int int\n\t| ^--^\n\t| Error:\n\t| missing return statement\n\t| int int\n\t| ^------...\n\n```\n\n### Variable Naming Conventions\n\nGood programmers write readable code. Giving proper names to your variables makes your code easy to read. \n\nIn a football scorecard application, using a name ```s``` for a score variable is vague. Something like ```score``` carries more meaning, and is preferred.\n```java\n\n\tjshell\u003e int s\n\ts ==\u003e 0\n\tjshell\u003e int score\n\tscore ==\u003e 0\n\tjshell\u003e\n\n```\n\n\u003e The Java community, with its wealth of experience, *suggests* that programmers follow some **naming conventions**. Above examples is one of these. Violation of these rules does not result in compilation errors. That's why, these are called **conventions**.\n\nIn Java, another convention is to use **CamelCase** when we have multiple words in variable name.\n```java \n \n\tjshell\u003e int noOfGoals\n\tnoOfGoals ==\u003e 0\n\n```\n\n```noOfGoals``` is easier to read than ```noofgoals```.\n\nBoth ```noOfGoals``` and ```NoOfGoals``` are equally readable. \n\nBut in Java, the convention followed is to start variable names with a lower case letter. So, for a variable, ```noOfGoals``` is preferred. \n\n*** NOT RECOMMENDED*** \n```\n\tjshell\u003e int NoOfGoals\n\tNoOfGoals ==\u003e 0\n```\n\nYour variable names can be very long. \n\n```java\n\n\tjshell\u003e int iThinkThisIsQuiteALongName\n\tiThinkThisIsQuiteALongName ==\u003e 0\n\tjshell\u003e int iThinkThisIsSuchALongNameThatIMightNeverUseSuchALongNameAgain\n\tiThinkThisIsSuchALongNameThatIMightNeverUseSuchALongNameAgain ==\u003e 0\n\n```\n\nHowever, avoid using very long variable names.\n\n***Use the shortest meaningful and readable name possible for your variables.***\n\n#### Summary\n\nIn this step, we:\n\n* Explored the Java language rules for variable names\n* Understood that there are conventions to guide us\n* Looked at a popular variable naming conventions\n\n### Step 18: Introducing Primitive Types\n\nThe table below lists the **primitive types** in Java.\n\n| Type of Values | Java Primitive Type | Size (in bits) | Range of Values | Example |\n| :---: | :---: |:---: |:---: |:---:|\n| Integral Values |byte|8|```-128``` to ```127```|```byte b = 5;```|\n| Integral Values |short|16|```-32,768``` to ```32,767```|```short s = 128;```|\n| Integral Values |int|32|```-2,147,483,648``` to ```2,147,483,647```|```int i = 40000;```|\n| Integral Values |long|64|```-9,223,372,036,854,775,808``` to ```9,223,372,036,854,775,807```|```long l = 2222222222;```|\n|Floating-Point Values| float| 32 | approximately ±3.40282347E+38F. NOT very precise (avoid for financial/scientific math)|```float f = 4.0f;```|\n|Floating-Point Values|double|64| approximately ±1.79769313486231570E+308. NOT very precise, but better than float (also avoid for financial/scientific  math)|```double d = 67.0;```|\n|Character Values|char|16|```'\\u0000``` to ```'\\uffff```|```char c = 'A';```|\n|Boolean Values| boolean|1| ```true``` or ```false```|```boolean isTrue = false;```|\n\nLet's now look at how we create data of these types, and store them in memory.\n\nWe choose type for data, based on:\n* The type of data we want to store\n* The range of values we would want to store\n\n\u003e Note: In the above examples, we used semi-colon ```;``` character at the end. This is the Java **statement separator**, which is not mandatory in ```JShell``` for single statements. However, it is a must when you use *code editors* and *IDE*'s, to write Java code.\n\n#### Integer Types\n\nThe only difference among the integer types is their storage capacity.\n\n```java\n\n\tjshell\u003e byte b = 5\n\tb ==\u003e 5\n\tjshell\u003e short s = 128\n\ts ==\u003e 128\n\tjshell\u003e int i = 40000\n\ti ==\u003e 40000\n\tjshell\u003e long l = 2222222222\n\tl ==\u003e 2222222222\n\tjshell\u003e\n\n```\n\n#### Floating Value Types\n\n```double``` is the default type for floating type values with size 64 bits. \n\n```\n\tjshell\u003e double d = 67.0\n\td ==\u003e 67.0\n```\n\n```float``` occupies 32 bits. ```float``` literals need to have a suffix '```f```' (as in ```4.0f```).\n\n```\n\n\tjshell\u003e float f = 4.0f\n\tf ==\u003e 4.0\n```\n\nIf this suffix ```f``` is omitted, a floating-point  number is assumed to be a ```double```. You cannot store a 64 bit value into 32 bits.\n```java\n\tjshell\u003e float f2 = 4.0\n\t| Error:\n\t| incompatible types: possible lossy conversion from double to float\n\t| float f2 = 4.0\n\t|            ^-^\n\n```\n\nYou can store ```float``` value in ```double```. Remember, both types store similar kind of values and a ```float``` value is only 32 bits where as ```double``` has 64 bits.\n```\n\tjshell\u003e double d2 = 67.0f\n\td2 ==\u003e 67.0\n```\n\n#### Character Type\n\nThe character type ```char``` can store a single character symbol. The symbol must be enclosed within a pair of single quotes, ```'``` and ```'```.\n\n```java\n\n\tjshell\u003e char c = 'A'\n\tc ==\u003e 'A'\n```\n\nFollowing are a few char declaration errors: Not using single quotes and trying to store multiple characters.\n```\n\tjshell\u003e char ch = A\n\t| Error:\n\t| cannot find symbol\n\t| symbol: variable A\n\t| char ch = A\n\t|           ^\n\n\tjshell\u003e char cab = 'AB'\n\t| Error:\n\t| unclosed character literal\n\t| char cab = 'AB'\n\t|            ^\n\n```\n\n#### Boolean Type\n\nThe concept of a ```boolean``` type is rooted in mathematical logic. The data type can store two possible values, ```true``` and ```false```. Both are case-sensitive labels, but  not enclosed in  quotes. \n\n```java\n\n\tjshell\u003e boolean isTrue = false\n\tisTrue ==\u003e false\n\tjshell\u003e isTrue = true\n\tisTrue ==\u003e true\n\tjshell\u003e boolean isFalse = True\n\t| Error:\n\t| cannot find symbol\n\t| symbol: variable True\n\t| boolean isFalse = True\n\t|                   ^--^\n\n\tjshell\u003e isFalse = False\n\t| Error:\n\t| cannot find symbol\n\t| symbol: variable False\n\t| isFalse = False\n\t|           ^---^\n\n```\n\n```boolean``` data are mostly used in expressions used to form logical conditions in your code. We will talk more about this - when we explore Java conditionals.\n\n\n#### Summary\n\nIn this step, we:\n\n* Looked at the primitive data types provided in Java\n* Understood the categories into which these types are divided\n* Saw what kind of data can be stored in each primitive type\n\n### Step 19: Choosing A Data Type\n\nHow do we choose the data type for a variable? Let's look at a few examples.\n\n#### Example 1 : Goals in a Football match\n\nConsider a sports broadcaster that writes a program to track football scores. In a football game there are two teams playing. A game is generally 90 minutes long, with extra time pushing it to 120 minutes at the most. Practically speaking, the scorelines are never huge. From a practical standpoint, the number of goals scored in a match would never exceed 7200 (the number of seconds in 120 minutes). Playing it a bit safe, a ```short``` data type would be enough to store the score of each side (though a ```byte``` would be more than enough).\n\n```java\n\n\tjshell\u003e short numTeamAGoals = 0\n\tnumTeamAGoals ==\u003e 0\n\tjshell\u003e short numTeamBGoals = 0\n\tnumTeamBGoals ==\u003e 0\n\tjshell\u003e\n\n```\n\n#### Example 2 : How do we store population of the world?\n\nWe know that the global count of humans is well over 7 billion now, so the only integer data type that can store it is a ```long```.\n\n```java\n\n\tjshell\u003e long globalPopulation = 7500000000;\n\tglobalPopulation ==\u003e 7500000000\n\tjshell\u003e\n\n```\n\n#### Example 3 : How do we store average rainfall in a month?\n\nRainfall is usually measured in millimeters (*mm*), and we know computing an average over 30 days is very likely to yield a floating-point number. Hence we can use a ```float```, or for more accuracy, a ```double``` to store that average.\n\n```java\n\n\tjshell\u003e float avgJanRainfall = 31.77f;\n\tavgJanRainfall ==\u003e 31.77\n\tjshell\u003e double averageJanRainfall = 31.77\n\taverageJanRainfall ==\u003e 31.77\n\tjshell\u003e\n\n```\n#### Example 4 : Grades of a Student\n\nClassroom grades in high school are generally A, B, C , .... \n\nFor a program that generates a grade report, a ```char``` type would be the best bet.\n\n```java\n\n\tjshell\u003e char gradeA = 'A'\n\tgradeA ==\u003e 'A'\n\tjshell\u003e char gradeB = 'B'\n\tgradeB ==\u003e 'B'\n\tjshell\u003e char gradeC = 'C'\n\tgradeC ==\u003e 'C'\n\tjshell\u003e char gradeD = 'D'\n\tgradeD ==\u003e 'D'\n\tjshell\u003e char gradeF = 'F'\n\tgradeF ==\u003e 'F'\n\tjshell\u003e\n\n```\n\n#### Example 5 : Is a Number Odd or Even?\n\nA ```boolean isNumEven``` is a good bet, with a default initial value of ```false```. It can be changed to ```true``` if the number turns out to be even.    \n\n```java\n\n\tjshell\u003e boolean isNumEven\n\tisNumEven ==\u003e false\n\tjshell\u003e isNumEven = true\n\tisNumEven ==\u003e true\n\tjshell\u003e\n\n```\n\n#### Summary\n\nIn this step, we:\n\n* Understood how to think while choosing a data type\n* Explored cases for integer, floating-point, character and boolean data\n\n### Step 20: The Assignment Operator ```=```\n\nWe were first exposed to the assignment operator while discussing variable assignment. \n\nWe are allowed to use expressions to assign values to variables, using code such as ```c = a + b```. \n\nLet's look at a few additional ways assignment can be done.\n\n```java\n\n\tjshell\u003e int i = 10\n\ti ==\u003e 10\n\tjshell\u003e int j = 15\n\tj ==\u003e 15\n\tjshell\u003e i = j\n\ti ==\u003e 15\n\tjshell\u003e\n\n```\n\nLet's consider the following example:\n```java\n\tjshell\u003e i = i * 2\n\ti ==\u003e 30\n\tjshell\u003e\n\n```\n\nThe same variable ```i``` appears on both the right-hand-side (*RHS*) and left-hand-side (*LHS*). How would that make any sense? \n\nThe expression on the *RHS* is *independently* evaluated first. The value we get is next copied into the memory slot of the *LHS* variable.\n\nUsing the logic above, the assignment  ```i = i * 2``` actually updates the value of ```i``` (initially ```15```) to ```30``` (doubles it). \n\nJava also does the right thing when it encounters the puzzling statement  ```i = i + i```, where ```i``` is all over the place! The code doubles the value of ```i```, and this reflects on the ```JShell``` output. \n\n```java\n\n\tjshell\u003e i = i + i\n\ti ==\u003e 60\n```\n\nThe next example is self explanatory.\n\n```\n\tjshell\u003e i = i - i\n\ti ==\u003e 0\n```\n\n#### Variable Increment and Decrement\n\nWe have already seen increment by assignment:\n\n```java\n\n\tjshell\u003e int i = 0\n\ti ==\u003e 0\n\tjshell\u003e i = i + 1\n\ti ==\u003e 1\n\tjshell\u003e i = i + 1\n\ti ==\u003e 2\n\tjshell\u003e i = i + 1\n\ti ==\u003e 3\n\tjshell\u003e\n\n```\n\nConversely, the statement ```i = i - 1``` is called a variable **decrement**. This can also be done repeatedly, and ```i``` changes  value every time.\n\n\n```java\n\n\tjshell\u003e i = i - 1\n\ti ==\u003e 2\n\tjshell\u003e i = i - 1\n\ti ==\u003e 1\n\tjshell\u003e i = i - 1\n\ti ==\u003e 0\n\tjshell\u003e\n\t\n```\n\n#### Summary \n\nIn this step, we:\n\n* Looked at the assignment operator ```=``` in a more formal way\n* Looked at heavily used scenarios for assignment, such as increment and decrement\n\n### Step 21: Assignment Puzzles, and *PMT-Challenge* revisited\n\nNow that we understand how to define, assign to, and use variables in expressions, it's time to push the boundaries a bit. The following examples explore how we could play around with variables in our code.\n\n##### Snippet-1 : Pre- and Post- Increment and Decrement\n\nThere are two short-hand versions for increment. ```number++``` denotes *post-increment*. Conversely, ```++number``` means **pre-increment**.\n\nOperator ```++``` can be applied only to variables of integer types, which are ```byte```, ```short```, ```int``` and ```long```.\n\n```number++``` is equivalent to the statement ```number = number + 1```\n\n```java\n\n\tjshell\u003e int number = 5\n\tnumber ==\u003e 5\n\tjshell\u003e number++\n\t$1 ==\u003e 5\n\tjshell\u003e number\n\tnumber ==\u003e 6\n\tjshell\u003e ++number\n\t$2 ==\u003e 7\n\tjshell\u003e number\n\tnumber ==\u003e 7\n\tjshell\u003e\n\n```\n\n```number--``` is *post-decrement*. On the other hand, ```--number``` is **pre-decrement**.\n\n```java\n\n\tjshell\u003e number--\n\t$3 ==\u003e 7\n\tjshell\u003e number\n\tnumber ==\u003e 6\n\tjshell\u003e --number\n\t$4 ==\u003e 5\n\tjshell\u003e number\n\tnumber ==\u003e 5\n\tjshell\u003e\n\n```\n\n***What is the difference between prefix and postfix vesions?***\n\nAlthough both prefix and postfix versions achieve the same visible result in above examples, there is a slight difference. We will explore this later.\n\n##### Snippet-2 : Compound Assignment Operators\n\nThe compound assignment operator combines the ```=``` with a numeric operator. \n\n```i += 2``` : Add ```2``` to the current value of ```i```\n\n```java\n\n\tjshell\u003e int i = 1\n\ti ==\u003e 1\n\tjshell\u003e i = i + 2\n\ti ==\u003e 3\n\tjshell\u003e i += 2\n\t$1 ==\u003e 5\n\tjshell\u003e\n\n```\n\n\n```i -= 1``` : Subtract ```1``` from the current value of ```i```\n\n```java\n\n\tjshell\u003e i\n\ti ==\u003e 5\n\tjshell\u003e i -= 1\n\t$2 ==\u003e 4\n\tjshell\u003e i\n\ti ==\u003e 4\n\tjshell\u003e\n\n```\n\n\n```i *= 4``` : Multiply ```i``` with ```4```, and store the result back into ```i```\n\n```java\n\n\tjshell\u003e i *= 4\n\t$3 ==\u003e 20\n\tjshell\u003e i\n\ti ==\u003e 20\n\tjshell\u003e\n\n```\n\n```i /= 4``` : Divide ```i``` by ```4```, and store the result back into ```i```\n\n```java\n\n\tjshell\u003e i /= 4\n\t$4 ==\u003e 5\n\tjshell\u003e i\n\ti ==\u003e 5\n\tjshell\u003e\n\n```\n\n```i %= 2``` : Divide ```i``` by ```2```, and store the **remainder** back into ```i```\n\n```java\n\n\tjshell\u003e i %= 2\n\t$5 ==\u003e 1\n\tjshell\u003e i\n\ti ==\u003e 1\n\tjshell\u003e\n\n```\n#### Summary\n\nIn the step, we:\n\n* Looked at the built-in Java increment and decrement operators\n* Explored the side-effects of prefix and postfix versions of these operators\n* Seen the advantages of compound assignment\n\n### Step 22: Some ```JShell``` Usage Tips \n\n* Shortcuts\n\t1. Toggling to limits of current prompt entry\n\t\t* '```Ctrl+a```' : to start of line\n\t\t* '```Ctrl+e```' : to end of line\n\t2. Moving up and down history of completed prompt inputs \n\t\t* *up-arrow* key : move back in time\n\t\t* *down-arrow* key : move forward in time\n\t3. Reverse-keyword-search\n\t\t* Search for a term, in reverse order of JShell prompt inputs history : input '```Ctrl+r```'\n\t\t* Scrolling within matches (in reverse order of history) : repeatedly input '```Ctrl+r```'\n* ```/exit``` : resets and exits the JShell session, clearing all stored variables values.\n* JShell internal variables : ```$1```, ```$2```, and so on.\n\t* When expressions involving literals and/or previously declared variables are entered as-is, without assignment, those expressions are still evaluated. The result is stored in such an internal variable, and is available for use until the JShell session is reset.\n* Variable Declaration rules relaxation\n\t1. Single Java statements need not be terminated with the separator '```;```'.\n\t2. If multiple statements are entered on a single line at the prompt, successive statements must be separated by the '```;```'. However, the trailing '```;```' can still be omitted.\n\n#### Summary\n\nIn this step, we:\n\n* Explored some useful keyboard shortcuts for ```JShell``` commands\n* Understood the idea behind ```JShell``` internal variables\n* Observed how ```JShell``` reduces typing effort, by relaxing some coding rules\n\n### Step 23: Introducing Conditionals - the ```if```\n\nThe *PMT-Challenge* needs us to print a total of 10 table entries. The  ```for``` **loop** is a suitable iteration mechanism to get this done. The word *loop* means exactly what the English dictionary says. \n\n*As ```i``` varies from ```1``` through ```10```, do some stuff involving ```i```*\n\nFor the *PMT-Challenge*, ```do some stuff``` would be the call to ```System.out.printf()```.\n\nThe way a ```for``` loop is structured is:\n\n```java\n\n\tfor(initialization; condition; update) {\n\t\tstatement1;\n\t\tstatement2;\n\t}\n\n```\n\nHere's how above code runs\n1. Execute ```initialization``` code. \n2. If ```condition``` evaluates to true, execute ```statements```. Else, go out of loop.\n3. Execute ```update```\n4. Repeat 2 and 3\n\n***Does it sound complex?*** Let's break it down.\n\nLet's start with understanding what ```condition``` is all about.\n\n#### Logical Operators\n\n```condition``` represents a logical value(a ```true``` or  a ```false```). \n\nTurns out Java has a class of **logical operators**, which can be used with operands within **logical expressions**, evaluating to a ```boolean``` value. \n\nWhile in school, you probably used the ```=``` symbol to compare numbers. \n\n***The world of Java is a little different.***  ```=``` is assignment operator. ```==``` is the comparison operator. \n\n```java\n\n\tjshell\u003e int i = 10\n\ti ==\u003e 10\n\tjshell\u003e i == 10\n\t$1 ==\u003e true\n\tjshell\u003e i == 11\n\t$2 ==\u003e false\n\n```\n\nThese are other comparison operators as well, such as ```\u003c``` and ```\u003e```. \n```java\n\n\tjshell\u003e i \u003c 5\n\t$3 ==\u003e false\n\tjshell\u003e i \u003e 5\n\t$4 ==\u003e true\n\n```\n\n```\u003c=``` and ```\u003e=``` are simple extensions.\n\n```java\n\n\tjshell\u003e i \u003c= 5\n\t$4 ==\u003e false\n\tjshell\u003e i \u003c= 10\n\t$5 ==\u003e true\n\tjshell\u003e i \u003e= 10\n\t$6 ==\u003e true\n\tjshell\u003e\n\n```\n\n#### Conditionals: The \"if\" Statement \n\nWe would want to execute specific lines of code only when a condition is true. \n\nEnter ```if``` statement.\n\nAn ```if``` statement is structured this way:\n\n```java\n\n\tif (condition) {\n\t\tstatement;\n\t}\n\n```\n\n```statement``` is executed only if ```condition``` evaluates to ```true```.\n\n\nTypically, all the code that we write is executed always. \n\nIn the example below, ```i is less than 5``` is always printed.  \n\n```java\n\n\tjshell\u003e int i = 10\n\ti ==\u003e 10\n\tjshell\u003e System.out.println(\"i is less than 5\")\n\ti is less than 5\n```\n\nUsing the ```if``` statement, we can control the execution of ```System.out.println(\"i is less than 5\");```.\n\n```java\n\n\tjshell\u003e if (i \u003c 5)\n\t   ...\u003e System.out.println(\"i is less than 5\");\n\tjshell\u003e \n```\n\nThe condition ```i \u003c 5``` will evaluate to ```false```, since ```i``` is currently ```10```. Nothing is printed to console.\n\n\nLet's change ```i``` to ```4``` and execute the ```if``` condition.\n\n```java\n\n\tjshell\u003e i = 4\n\ti ==\u003e 4\n\tjshell\u003e if (i \u003c 5)\n\t   ...\u003e System.out.println(\"i is less than 5\");\n\ti is less than 5\n\tjshell\u003e\n\n```\n\n```i is less than 5``` is printed to console.\n\nBy controlling the value stored in the variable ```i```, we are able to control whether the statement  ```System.out.println(\"i is less than 5\");``` actually runs. \n\n***Hurrah! We just achieved *conditional execution*!***\n\n\nJust as we can compare a variable with a literal, it is possible to compare the values of two variables. The same set of comparison operators, namely ```==```, ```\u003c```, ```\u003e```, ```\u003c=``` and ```\u003e=``` can be used.  \n\n```java\n\n\tjshell\u003e int number1 = 5\n\tnumber1 ==\u003e 5\n\tjshell\u003e int number2 = 7\n\tnumber2 ==\u003e 7\n\tjshell\u003e if (number2 \u003e number1)\n\t   ...\u003e System.out.println(\"number2 is greater than number1\");\n\tnumber2 is greater than number1\n\n\tjshell\u003e number2 = 3\n\tnumber2 ==\u003e 3\n\tjshell\u003e if (number2 \u003e number1)\n\t   ...\u003e System.out.println(\"number2 is greater than number1\");\n\n\tjshell\u003e\n\n```\n\n#### Summary\n\nIn this step, we:\n\n* Understood the need for a conditionals\n* Were introduced to the concept of logical expressions, and conditional operators\n* Explored usage of the Java ```if``` statement\n\n### Step 24: Programming Exercise PE-04 \n- - - \n\n1. Create four integer variables ```a```, ```b```, ```c``` and ```d```. Write an ```if``` statement to print if the sum of ```a``` and ```b``` is greater than the sum of ```c``` and ```d```.\n2. Store three numerical values as proposed angles of a triangle in integer variables ```angle1```, ```angle2``` and ```angle3```. Create an ```if``` statement to state whether these three angles together can form a triangle.\n\n\t_Hint: A triangle is a closed geometric figure with three angles, whose sum must  exactly equal ```180 degrees```._\n3. Have a variable store an integer. Create an ```if``` statement to find out if it's an even number.\n\n\t_Hint: Use operator ```%```._\n\n### Step 25: Solution to PE-04\n\n#### Solution 1\n\n```java\n\n\tjshell\u003e int a = 5\n\ta ==\u003e 5\n\tjshell\u003e int b = 7\n\tb ==\u003e 7\n\tjshell\u003e int c = 4\n\tc ==\u003e 4\n\tjshell\u003e int d = 3\n\td ==\u003e 3\n\tjshell\u003e if (a + b \u003e c + d)\n\t   ...\u003e System.out.println(\"a and b together tower above c plus d\");\n\ta and b together tower above c plus d\n\n\tjshell\u003e\n\n```\n\n#### Solution 2\n\n```java\n\n\tjshell\u003e int angleOne = 55\n\tangleOne ==\u003e 55\n\tjshell\u003e int angleTwo = 65\n\tangleOne ==\u003e 55\n\tjshell\u003e int angleThree = 60\n\tangleOne ==\u003e 55\n\tjshell\u003e if (angleOne + angleTwo + angleThree == 180)\n\t   ...\u003e System.out.println(\"The three angles together form a triangle\");\n\tThe three angles together form a triangle\n\n\tjshell\u003e angleThree = 75\n\tangleOne ==\u003e 55\n\tjshell\u003e if (angleOne + angleTwo + angleThree == 180)\n\t   ...\u003e System.out.println(\"The three angles together form a triangle\");\n\n\tjshell\u003e\n\n```\n\n#### Solution 3\n\n```java\n\n\tjshell\u003e int num = 10\n\tnum ==\u003e 10\n\tjshell\u003e if (num % 2 == 0)\n\t   ...\u003e System.out.println(\"The number is even\");\n\tThe number is even\n\n\tjshell\u003e num++\n\tnum ==\u003e 11\n\tjshell\u003e if (num % 2 == 0)\n\t   ...\u003e System.out.println(\"The number is even\");\n\n\tjshell\u003e\n```\n\n### Step 26:  ```if``` Statement again\n\nLet's look at a few more examples of if statements.\n\n##### Snippet-1 \n\nHere's a basic example of conditional execution.\n\n```java\n\n\tjshell\u003e int i = 5\n\ti ==\u003e 5\n\tjshell\u003e if (i == 5)\n\t   ...\u003e System.out.println(\"i is odd\");\n\ti is odd\n```\n\nLet's add two statements to the second line.\n```java\n\tjshell\u003e if (i == 5)\n\t   ...\u003e System.out.println(\"i is odd\"); System.out.println(\"i is prime\");\n\ti is odd\n\ti is prime\n\n\tjshell\u003e\n\n``` \nBoth text messages are printed out.\n\nLet's change value of ```i``` to ```6``` and execute again.\n\n```java\n\n\tjshell\u003e i = 6\n\ti ==\u003e 6\n\tjshell\u003e if (i == 5)\n\t   ...\u003e System.out.println(\"i is odd\"); System.out.println(\"i is prime\");\n\ti is prime\n\n\tjshell\u003e\n\n```\n\n```i is prime``` is printed to console. Why? \n\nWhy is this statement executed when the condition is ```false```?\n\n\nThe ```if``` statement, by default, binds only to the next statement. \n\nIt does not control the execution of ```System.out.println(\"i is prime\");```, which in fact runs unconditionally, always.\n\nIs there a way we can ensure conditional execution of a two statements? And more than two? \n \n##### Snippet-2 : ```if``` with statement blocks\n\nWe seem to have pulled a rabbit out of the hat here, haven't we! The rabbit lies in the  pair of *braces* : '```{```' and '```}```'. \n\nThey are used to group a sequence of statements together, into a **block**. Depending on the condition value (```true``` or ```false```), either all the statements in this block are run, or none at all. \n\n```java\n\n\tjshell\u003e int i = 5\n\ti ==\u003e 5\n\tjshell\u003e if (i == 5) {\n\t   ...\u003e System.out.println(\"i is odd\");\n\t   ...\u003e System.out.println(\"i is prime\");\n\t   ...\u003e }\n\ti is odd\n\ti is prime\n\n\tjshell\u003e i = 6\n\ti ==\u003e 6\n\tjshell\u003e if (i == 5) {\n\t   ...\u003e System.out.println(\"i is odd\");\n\t   ...\u003e System.out.println(\"i is prime\");\n\t   ...\u003e }\n\n\tjshell\u003e\n\n```\n\nIt is considered good programming practice to *always* use blocks in an ```if``` conditional. Here is an example:\n\n```java\n\n\tif (i == 5) {\n\t\tSystem.out.println(\"i is odd\");\n\t}\n\n```\n\t\nA block can also consist of a single statement! This improves readability of code.\n\n#### Summary\n\nIn this step, we:\n\n* Saw the importance of using statement blocks with ```if``` conditionals\n* Understood how control flow can be made more readable\n\n### Step 27: Introducing Loops: The ```for``` Statement \n\nThe *PMT-Challenge* needs us to print a total of 10 table entries. The  ```for``` **loop** is a suitable iteration mechanism to get this done. \n\nThe word *loop* means exactly what the English dictionary says. \n*As ```i``` varies from ```1``` through ```10```, do some stuff involving ```i```*\n\n```for``` loop is built this way:\n\n```java\n\n\tfor(initialization; condition; update) {\n\t\tstatement1;\n\t\tstatement1;\n\t}\n\n```\n\n***Here's how above code runs:***\n1. Execute ```initialization``` code. \n2. If ```condition``` evaluates to true, execute ```statements```. Else, go out of loop.\n3. Execute ```update```\n4. Repeat 2 and 3\n\nWe've already seen these components in isolation:\n\n* _initialization_ : ```int i = 1```\n* _condition_ : ```i \u003c= 10```\n* _update_ : ```i++```\n\nLet's now put them together to get the bigger picture. Here is how it might look:\n\n```java\n\n\tfor (int i = 1; i \u003c= 10; i++) {\n\t\tSystem.out.println(\"Hello World\");\n\t}\n\n```\n\nThis loop, when executed, prints the message \"Hello World\" on a separate line, for a total of ```10``` times. \n\n##### Snippet-1 : *PMT-Challenge* Solution\n\nWe need to replace the \"Hello World\" message with the console print of a table entry. This print is controlled by ```i``` taking values from ```1``` through ```10```.\n\n```java\n\n\tjshell\u003e int i\n\ti ==\u003e 0\n\tjshell\u003e for (i=0; i\u003c=10; i++) {\n\t   ...\u003e System.out.printf(\"%d * %d = %d\", 5, i, 5*i).println();\n\t   ...\u003e }\n\t5 * 1 = 5\n\t5 * 2 = 10\n\t5 * 3 = 15\n\t5 * 4 = 20\n\t5 * 5 = 2\n\t5 * 6 = 30\n\t5 * 7 = 35\n\t5 * 8 = 40\n\t5 * 9 = 45\n\t5 * 10 = 50\n\n```\n\n##### Snippet-1 Explained \n\n1. The first step is the initialization: ```i = 1```. \n2. After this, the statement ```System.out.printf(\"%d * %d = %d\", 5, i, 5*i).println();```  is executed once. \n3. Then, the update occurs: ```i++```.\n4. Immediately after, the condition ```i\u003c=10``` is evaluated. It returns ```true```. Progress happens. Since it is a ```for``` *loop*, the statement is executed again.\n5. Thereafter, this sequence is executed until ```i``` gets a value of ```11``` (due to successive updates).\n6. The moment ```i``` reaches ```11```, , the condition becomes ```false```. The looping within the ```for``` terminates.\n\nMeanwhile, the Multiplication Table for ```5```, for entries ```1``` through ```10``` has been displayed! \n\nNow, wasn't that really elegant? It sure was! \n\nLet's pat ourselves on the back for having reached this stage of learning. This elegant, yet powerful technique (*loops*) is used in almost every Java program that's written. \n\n#### Summary\n\nIn this step, we:\n\n* Observed why we need a looping construct, such as the ```for```\n* Understood the mechanism of a ```for``` loop\n* Used a ```for``` loop in iteration, to solve our *PMT-Challenge*\n\n### Step 28: Programming Exercise PE-05\n\n1. Repeat the entire process at arriving at the Multiplication Table Print problem, now for the number ```7```. Start with a fresh ```JShell``` session, if you're still using an existing one for quite some time (Rinse, and repeat!).\n2. Use the final solution to print Multiplication Tables for ```6``` and ```10```.\n3. Print the integers from ```1``` to ```10```.\n4. Print the integers from ```10``` to ```1```.\n5. Print the squares of the integers from ```1``` to ```10```.\n6. Print the squares of the first ```10``` even integers.\n7. Print the squares of the first ```10``` odd integers.\n\n### Step 29: Solution to PE-05\n\n#### Solution 2\n\n```java\n\n\tjshell\u003e int i\n\ti ==\u003e 0\n\tjshell\u003e for (i=0; i\u003c=10; i++) {\n\t   ...\u003e System.out.printf(\"%d * %d = %d\", 6, i, 6*i).println();\n\t   ...\u003e }\n\t6 * 1 = 6\n\t6 * 2 = 12\n\t6 * 3 = 18\n\t6 * 4 = 24\n\t6 * 5 = 30\n\t6 * 6 = 36\n\t6 * 7 = 42\n\t6 * 8 = 48\n\t6 * 9 = 54\n\t6 * 10 = 60\n\n\tjshell\u003e i = 0\n\ti ==\u003e 0\n\tjshell\u003e for (i=0; i\u003c=10; i++) {\n\t   ...\u003e System.out.printf(\"%d * %d = %d\", 10, i, 10*i).println();\n\t   ...\u003e }\n\t10 * 1 = 10\n\t10 * 2 = 20\n\t10 * 3 = 30\n\t10 * 4 = 40\n\t10 * 5 = 50\n\t10 * 6 = 60\n\t10 * 7 = 70\n\t10 * 8 = 80\n\t10 * 9 = 90\n\t10 * 10 = 100\n\n```\n\n#### Solution 3\n\n```java\n\n\tjshell\u003e for (int i=1; i\u003c=10; i++) {\n\t   ...\u003e System.out.printf(i).println();\n\t   ...\u003e }\n\t1\n\t2\n\t3\n\t4\n\t5\n\t6\n\t7\n\t8\n\t9\n\t10\n\n```\n\n#### Solution 4\n\nThis is the first time we are using ```i--```. Isn't this interesting?\n\n```java\n\n\tjshell\u003e for (int i=10; i\u003e0; i--) {\n\t   ...\u003e System.out.printf(i).println();\n\t   ...\u003e }\n\t10\n\t9\n\t8\n\t7\n\t6\n\t5\n\t4\n\t3\n\t2\n\t1\n\n```\n\n#### Solution 5\n\n```java\n\n\tjshell\u003e for (int i=1; i\u003c=10; i++) {\n\t   ...\u003e System.out.printf(i*i).println();\n\t   ...\u003e }\n\t1\n\t4\n\t9\n\t16\n\t25\n\t36\n\t49\n\t64\n\t81\n\t100\n\n```\n\n#### Solution 6\n\n```update``` of a for loop can do a lot of things. Here, we are using ```i += 2```.\n\n```java\n\n\tjshell\u003e for (int i=2; i\u003c20; i += 2) \n\t   ...\u003e System.out.printf(i*i).println();\n\t   ...\u003e }\n\t4\n\t16\n\t36\n\t64\n\t100\n\t144\n\t196\n\t256\n\t324\n\t400\n\n```\n\n#### Solution 7\n\n```java\n\n\tjshell\u003e for (int i=1; i\u003c=19; i += 2) {\n\t   ...\u003e System.out.printf(i*i).println();\n\t   ...\u003e }\n\t1\n\t9\n\t25\n\t49\n\t81\n\t121\n\t169\n\t225\n\t289\n\t361\n\n```\n\n### Step 30: Puzzling You With ```for``` \n\nIn the conceptual form of the ```for``` construct:\n\n```java\n\n\tfor (initialization; condition; updation) {\n\t\tstatement;\n\t\tstatement;\n\t\t//...\n\t\tstatement;\n\t}\n\n```\n  \nIt may surprise you that each one of *initialization*, *condition*, *updation* and *statements block* is **optional**. They can all be left out individually, in combination, or all altogether!! Let's examine a few interesting cases in code.\n\n1. Empty initialization, Empty Statement\n\nIncrements the control variable in quick succession until the condition evaluates to false.\n```java\n\n\tjshell\u003e int i = 1\n\ti ==\u003e 1\n\tjshell\u003e for (; i\u003c=10; i++);\n\tjshell\u003e i\n\ti ==\u003e 11\n\tjshell\u003e\n\n```\n\n2. Multiple initializations, Empty Statement\n\nYou can have multiple statements in ```initialization``` and ```update``` separated by ```,```.\n\n```java\n\n\tjshell\u003e int j\n\ti ==\u003e 11\n\tjshell\u003e for (i=1, j=2; i\u003c=10; i++, j++);\n\tjshell\u003e i\n\ti ==\u003e 11\n\tjshell\u003e j\n\tj ==\u003e 12\n\tjshell\u003e\n\n```\n\n\nIn the example below, i is incremented and j is decremented.\n\n```java\n\n\tjshell\u003e for (i=1, j=2; i\u003c=10; i++, j--);\n\tjshell\u003e i\n\ti ==\u003e 11\n\tjshell\u003e j\n\tj ==\u003e -8\n\tjshell\u003e\n\n```\n\n3. Infinite Loop\n\nAn infinite loop is one where the *condition* is left *empty*. An empty condition always evaluates to ```true```. Since a ```for``` loop only terminates when the condition becomes ```false```, such a loop this never terminates. \n\nIt can only be terminated externally with a keyboard interrupt (```CTRL + c```).\n\n```java\n\n\tjshell\u003e for (;;);\n\n\t^C\n\tjshell\u003e\n\n```\n\n\n4. Statement Block in for\n\nAs in case of the ```if``` conditional statement, we can have statement blocks in ```for``` loops as well. As before, we enclose the statement set between braces ('```{```' and '```}```'). The statements are executed repeatedly, in the same order as they appear in the block.\n\n```java\n\n\tjshell\u003e for (i=1; i\u003c=5; i++) {\n\t   ...\u003e System.out.println(\"No 1\");\n\t   ...\u003e System.out.println(\"No 2\");\n\t   ...\u003e }\n\tNo 1\n\tNo 2\n\tNo 1\n\tNo 2\n\tNo 1\n\tNo 2\n\tNo 1\n\tNo 2\n\tNo 1\n\tNo 2\n\n```\n\n\n#### Summary\n\nIn this step, we saw that all components of a ```for``` loop are optional:\n* *initialization*\n* *condition*\n* *updation*\n* *statement block*\n\n### Step 31: A Review Of Basic Concepts\nBefore we go further, let's quickly get a Big Picture of what we are doing here!\n\nA **computer** is a *machine* that does a job for you and me. It is can be used to run tasks that we find complicated, time-consuming, or even boring! For instance, a laptop can play music from a CD, videos from the web, or fire a print job. \n\nWe have mobile phones around us, which are mini versions of computers. Then there are others, ranging from blood-sugar monitors to weather-forecast systems. Computers surround us, wherever we go!\n\nAny computer is made up of two basic layers: \n\n* The **hardware**: Consists of all the *electronic* and *mechanical* parts of the computer, including the *electronic circuits*.\n* The **software**: Describes the *instructions* fed into the computer, which are stored and run on its *hardware*.\n\nIf the human body were a computer,\n\n* Its *hardware* would consist of the various organs (such as limbs, blood and heart)\n* Its *software* would be the signals from the nervous system, which drive these organs.\n\n**Computer programming** involves writing software instructions to run tasks on a computer. The user who gives these instructions is called the **programmer**. Often, computer programming  involves solving challenging, and very interesting problems.\n\n\nIn the previous steps, we introduced you to the basic Java language concepts and constructs.\n\nWe solved a programming challenge, the *PMT-Challenge* using basic Java constructs.\n\nWe used JShell REPL to learn the following concepts, Step by-step:\n* Expressions, Operators and Statements\n* Variables and Formatted Output\n* Conditionals and Loops\n\nAt each step, we applied fresh knowledge to enhance our solution to the *PMT-Challenge*\n\nHope you liked the journey thus far. Next sections delve deeper into Java features, using the same Step by-step approach. We will catch up again soon, hopefully!\n\n## Understanding Methods\n\nFeeling good about where you are right now? You just created an elegant, yet powerful solution to the *PMT-Challenge*, using:\n\n* Operators, variables and expressions\n* Built-in formatted output\n* Conditionals for control-flow, and \n* Iteration through loops\n \nAnd guess what we ended up with? A good-looking display of a Multiplication Table! There's a good chance people in your circles want to see it, use it and maybe share it among their friends. \n\nHowever, some might be unhappy that it works only for ```5```, and not for ```8``` and ```7```. Maybe it would, but then they would need to type in those lines of code again. This might disappoint them, and your new found popularity would slide downhill. \n\nSurely a more elegant solution exists, a pattern waiting to unravel itself.\n\nExist it does, and the mechanism to use it lies with Java **methods**. A ```method``` is a feature that allows you to group together a set of statements, and give it a name. This name represents the *functionality* of that set, which can be re-used when necessary.\n\nA method is essentially a *routine* that performs a certain task, and can do it any number of times it is asked to. It may also return a result for the task it performs. The syntax for a ***method definition*** is along these lines:\n\n```\nReturnType   methodName () {\n  method-body\n}\n\n```\n\nWhere \n\n* ```methodName``` is the name of the routine\n* ```method-body``` is the set of statements\n* a pair of braces ```{``` and ```}``` enclose ```method-body```\n* ```ReturnType``` is the type of ```methodName```'s return value\n\n\n#### Summary\n\nIn this step, we:\n\n* Examined the need for labeling code, and its reuse\n* Learned that a Java method fits the bill\n* Saw how a method definition looks like, conceptually\n\n### Step 01 : Defining A Simple Method\n\nWe will start off, by writing a simple method that prints \"```Hello World```\" twice on your screen.\n\n```java\n\n\tjshell\u003e void sayHelloWorldTwice() {\n\t   ...\u003e System.out.println(\"Hello World\");\n\t   ...\u003e System.out.println(\"Hello World\");\n\t   ...\u003e }\n\t| created method sayHelloWorldTwice()\n\n```\n\nA little bit of theory:\n* Above code for the method is called **method definition**. \n* ```void``` indicates that the method does not return any computed result - We will examine return values from methods, a little later.\n\n***When the code ran, it didn't exactly welcome us twice, did it?*** All we got was a boring message from ```JShell```, mumbling ```created method sayHelloWorldTwice()```. \n\nThat's because defining a method ***does NOT*** execute its statement body.\n\nSince the statement block is not stand-alone anymore, its functionality needs to be **invoked**. This is done by writing a **method call**. \n\nLet's look at a few examples for **method calls**.\n \n```java\n\n\tjshell\u003e sayHelloWorldTwice\n\t| Error:\n\t| cannot find symbol\n\t| symbol: variable sayHelloWorldTwice\n\t| sayHelloWorldTwice\n\t| ^----------------^\n\n\tjshell\u003e sayHelloWorldTwice()\n\tHello World\n\tHello World\n\t\n``` \n\nAll that we had to do was to add parantheses to name of the method.\n\n\u003e The trailing '```;```' can be left out in ```JShell```, and is another example of syntax rules being relaxed.\n\n\u003e Method names need to follow the same rules as variable names.\n\n#### Summary\n\nIn this step we:\n\n* Got our hands dirty coding our first method\n* Learned that defining and invoking methods are two different steps\n\n### Step 02: Exercise-Set PE-01\n\nLet's now reinforce our basic understanding of methods, by trying out a few exercises.\n\n#### Exercise Set -5\n\n1. Write and execute a method named ```sayHelloWorldThrice``` to print ```Hello World``` thrice.\n\n2. Write and execute a method that prints the following four statements:\n\t\n\t```I've created my first variable```\n\n\t```I've created my first loop```\n\t\n\t```I've created my first method```\n\t\n\t```I'm excited to learn Java```\t\n\n#### Solutions to PE-01\n\n#### Solution-1\n\n```java\n\n\tjshell\u003e void sayHelloWorldThrice() {\n\t   ...\u003e System.out.println(\"Hello World\");\n\t   ...\u003e System.out.println(\"Hello World\");\n\t   ...\u003e System.out.println(\"Hello World\");\n\t   ...\u003e }\n\t| created method sayHelloWorldThrice()\n\n\tjshell\u003e sayHelloWorldThrice()\n\tHello World\n\tHello World\n\tHello World\n\n```\n \n#### Solution-2\n\n```java\n \n\tjshell\u003e void sayFourThings() {\n\t   ...\u003e System.out.println(\"I've created my first variable\");\n\t   ...\u003e System.out.println(\"I've created my first loop\");\n\t   ...\u003e System.out.println(\"I've created my first method\");\n\t   ...\u003e System.out.println(\"I'm excited to learn Java\");\n\t   ...\u003e }\n\t| created method sayFourThings()\n\n\tjshell\u003e sayFourThings()\n\tI've created my first variable\n\tI've created my first loop\n\tI've created my first method\n\tI'm excited to learn Java\n\n```\n\n### Step 03: Editing A Method Definition (```Jshell``` Tips)\n\n##### Snippet-01: Editing sayHelloWorldTwice()\n\n```java\n\n\tjshell\u003e void sayHelloWorldTwice() {\n\t   ...\u003e System.out.println(\"Hello World\");\n\t   ...\u003e System.out.println(\"Hello World\");\n\t   ...\u003e }\n\t| created method sayHelloWorldTwice()\n```\n\nThe ```/methods``` command lists out the methods defined in the current session. \n```\n\tjshell\u003e /methods\n\t| void sayHelloWorldTwice()\n\tjshell\u003e\n\n```\n\nThe ```/list``` command lists the code of the specified method.\n\n```java\n\n\tjshell\u003e /list sayHelloWorldTwice\n\t59 : void sayHelloWorldTwice() {\n\tSystem.out.println(\"HELLO WORLD\");\n\tSystem.out.println(\"HELLO WORLD\");\n\t}\n\tjshell\u003e\n\n```\n\n\nThe ```/edit``` command allows you to modify the method definition, in a separate editor window.\n\n```java\n\n\tjshell\u003e /edit sayHelloWorldTwice\n\t| modified method sayHelloWorldTwice\n\tjshell\u003e sayHelloWorldTwice()\n\tHELLO WORLD\n\tHELLO WORLD\n\tjshell\u003e\n\n```\n\nThe ```/save``` method takes a file name as a parameter. When run, it saves the session method definitions to a file.\n\n```java\n\t\n\tjshell\u003e /save backup.txt\n\tjshell\u003e /exit\n\t| Goodbye\n\nin28minutes$\u003e\n\n```\n\n#### Summary\n\nIn this step, we explored a few ```JShell``` tips that make life easier for you while defining methods\n\n### Step 04: Methods with Arguments\n\nWe wrote the method ```sayHelloWorldTwice``` to say ```Hello World``` twice. In the programming exercise, we wanted to print ```Hello World``` thrice and we wrote a new method  ```sayHelloWorldThrice```. \n\nImagine you're in the Java classroom, where your teacher wants to test your Java skills by saying: \n_\"I want you to print_ ***```Hello World```*** _an arbitrary number of times\"_.\n\nNow, that probably would test your patience as well!\n\nHow to write a method to print ```Hello World``` an arbitrary number of times? \n\nThe thing to note is the word \"arbitrary\", which means the method body should have no clue! This number has to come from outside the method, which can only happen with a method call. \n\nExternal input to a method is given as a **method argument**, or *parameter*. \n\nTo support arguments during a call, the concept of a method needs to be tweaked to:\n\n```java\n\n\tReturnType methodName(ArgType argName) {\n\n\t\tmethod-body\n\n\t}\n\n``` \n\nThe only addition to the concept of a method, is the phrase\n\n```ArgType argName``` \n\nwithin the parentheses. ```argName``` represents the argument, and ```ArgType``` is its type. The next example should clear the air for you.\n\n##### Snippet-01: Method with an argument: Definition\n\nLet's look at a method definition using an argument ```numOfTimes```.\n\n```java\n\n\tjshell\u003e void sayHelloWorld(int numOfTimes) {\n\t   ...\u003e }\n\t| created method sayHelloWorld(int)\n```\n\nLet's try to call the method.\n```java\n\tjshell\u003e sayHelloWorld()\n\t| Error:\n\t| method sayHelloWorld in class cannot be applied to given types;\n\t| required : int\n\t| found : no arguments\n\t| reason : actual and formal argument lists differ in length\n\t| sayHelloWorld(\n\t|^-----------------^\n\tjshell\u003e sayHelloWorld(1)\n\tjshell\u003e\n\n```\n\nMethod call must include the same number and types of arguments, that it is defined to have. ```sayHelloWorld()``` is an error because ```sayHelloWorld``` is defined to accept one parameter. ```sayHelloWorld(1)``` works.\n\nHowever, the method does not do anything. Isn't it sad?\n\n##### Snippet-02 : Passing and accessing a parameter\n\nThe next example will show you how method body code can access arguments passed during a call. Not only that, the argument values can be used during computations.\n\n```java\n\nvoid sayHelloWorld(int numOfTimes) {\n\tSystem.out.println(numOfTimes);\n}\n\n```\n\n`System.out.println(numOfTimes)` prints the value of argument passed.\n\nA method can be invoked many times within a program, and each time different values could be passed to it. The following example will illustrate this fact.\n\n```java\n\n\tjshell\u003e sayHelloWorld(1)\n\t1\n\tjshell\u003e sayHelloWorld(2)\n\t2\n\tjshell\u003e sayHelloWorld(4)\n\t4\n\tjshell\u003e /edit sayHelloWorld\n\t| modified method sayHelloWorld(int)\n\tjshell\u003e\n\n```\n\n##### Snippet-03: More complex method\n\nCode inside a method can be any valid Java code! For instance, you could write code for iteration, such as a ```for``` loop.\n\nLet's look at an example:\n\n```java\n\n\tvoid sayHelloWorld(int numOfTimes) {\n\t\tfor (int i=1; i\u003c=numOfTimes; i++) {\n\t\t\tSystem.out.println(numOfTimes);\n\t\t}\n\t}\n\n```\n\nIn the above example, we printed ```numOfTimes``` a total of ```numOfTimes``` for each method call. \n \nWe print ```2``` two times and ```4``` four times.\n\n```java\n\n\tjshell\u003e sayHelloWorld(2)\n\t2\n\t2\n\tjshell\u003e sayHelloWorld(4)\n\t4\n\t4\n\t4\n\t4\n\tjshell\u003e\n\n```\n\n##### Snippet-4 : Saying \"Hello World\", Again and again...\n\nWe wanted to print \"Hello World\" multiple times. Let's update the method:\n\n```java\n\tvoid sayHelloWorld(int numOfTimes) {\n\t\tfor (int i=1; i\u003c=numOfTimes; i++) {\n\t\t\tSystem.out.println(\"Hello World\");\n\t\t}\n\t}\n```\n\nIsn't this cool?\n\n```java\n\tjshell\u003e sayHelloWorld(1)\n\tHello World\n\tjshell\u003e sayHelloWorld(2)\n\tHello World\n\tHello World\n\tjshell\u003e sayHelloWorld(4)\n\tHello World\n\tHello World\n\tHello World\n\tHello World\n\tjshell\u003e\n\n```\n\nYou can now proudly demonstrate this code to your Java instructor. Your program can print \"Hello World\" an arbitrary number of times! \n\nWhat started off giving you a headache, will probably keep you in her good books, for the rest of your course!\n\nArmed with this confidence booster, let's now see how Java treats mistakes you may make. \n.\n  \n##### Snippet-5 : Parameter type mismatch\n\nJava is a strongly typed language, with strict rules laid out for type compatibility. We saw that with variables, and how they play out with expressions and assignments. The same type compatibility rules are enforced by the compiler, when it needs to match the arguments from method calls with method definition.\n\n```java\n\n\tjshell\u003e sayHelloWorld(\"value\")\n\t| Error:\n\t| incompatible types: java.lang.String cannot be converted to int\n\t| sayHelloWorld(\"value\")\n\t|               ^-----^\n\tjshell\u003e sayHelloWorld(4.5)\n\t| Error:\n\t| incompatible types: possibly lossy conversion from double to int\n\t| sayHelloWorld(4.5)\n\t|               ^-^\n\tjshell\u003e\n\n```\n\n#### Summary\n\nIn this step, we:\n\n* Understood why Java supports method arguments, and how we may use them\n* Observed how method arguments lead to convenience and reuse\n* Decided to abide by type compatibility for actual arguments\n\n### Step 05: Exercise Set PE-02 (With Solutions)\n\n#### Exercises\n\n1. Write a method ```printNumbers(int n)``` that prints all successive integers from ```1``` to ```n```.\n2. Write a method ```printSquaresOfNumbers(int n)``` that prints the squares of all successive integers from ```1``` to ```n```.\n\n#### Solution-01\n\n```java\n\n\tjshell\u003e void printNumbers(int n) {\n\t   ...\u003e for(int i=0; i\u003c n; i++) {\n\t   ...\u003e System.out.println(i);\n\t   ...\u003e }\n\t   ...\u003e }\n\t| created method printNumbers(int)\n\t\n```\n\n**jshell\u003e**\n\n#### Solution 2\n\n```java\n\n\tjshell\u003e void printSquaresOfNumbers(int n) {\n\t   ...\u003e for(int i=0; i\u003c n; i++) {\n\t   ...\u003e System.out.println(i*i);\n\t   ...\u003e }\n\t   ...\u003e }\n\t| created method printSquaresOfNumbers(int)\n\tjshell\u003e\n\n```\n\n### Step 07: *PMT-Challenge* Revisited (And Some Puzzles)\n\nA method, in its own right, provides an elegant way to name and reuse a code block. In addition, its behavior can be controlled with parameters. \n\nCan we top-up the existing solution to the *PMT-Challenge*, with even more elegance? You're right, we're talking about:\n1. Writing a method to print the multiplication table for 5.\n2. Using this method to print the multiplication table for any number.\n\nWant to take a look? Dive right in.\n\nHere's what we did earlier:\n\n```java\n\n\tjshell\u003e for (int i=1; i\u003c=10; i++) {\n\t   ...\u003e System.out.printf(\"%d * %d = %d\", 5, i, 5*i).println();\n\t   ...\u003e }\n\t5 * 1 = 5\n\t5 * 2 = 10\n\t5 * 3 = 15\n\t5 * 4 = 20\n\t5 * 5 = 25\n\t5 * 6 = 30\n\t5 * 7 = 35\n\t5 * 8 = 40\n\t5 * 9 = 45\n\t5 * 10 = 50\n\n```\n\nLet's wrap this in a method:\n\n```java\n\n\tvoid printMultiplicationTable() {\n\t\tfor (int i=1; i\u003c=10; i++) {\n\t\tSystem.out.printf(\"%d * %d = %d\", 5, i, 5*i).println();\n\t\t}\n\t}\n\n```\n\nYou can call it to print 5 table.\n\n```java\n\n\tjshell\u003e printMultiplicationTable()\n\t5 * 1 = 5\n\t5 * 2 = 10\n\t5 * 3 = 15\n\t5 * 4 = 20\n\t5 * 5 = 25\n\t5 * 6 = 30\n\t5 * 7 = 35\n\t5 * 8 = 40\n\t5 * 9 = 45\n\t5 * 10 = 50\n\tjshell\u003e\n\t\n```\n\n#### Summary\n\nIn this step, we:\n\n* Revisited the *PMT-Challenge* solution we had earlier\n* Enclosed its logic within a method definition, ```printMultiplicationTable()```\n* Haven't fully explored its power yet!\n\n### Step 08: Methods With Arguments, And Overloading\n\nThe real power of a definition such as ```printMultiplicationTable()``` is when we arm it with arguments. Not verbal arguments, but \"value\" ones. That's right! \n\nWe will modify ```printMultiplicationTable()``` to have it accept a parameter, which would make it more flexible. \n\n```java\n\tvoid printMultiplicationTable(int number) {\n\t\tfor (int i=1; i\u003c=10; i++) {\n\t\t\tSystem.out.printf(\"%d * %d = %d\", number, i, number*i).println();\n\t\t}\n\t}\n```\n\nWe can now print the multiplication table of any number, by calling the method ```printMultiplicationTable(number)```.\n\n```java\n\n\tjshell\u003e printMultiplicationTable(6)\n\t6 * 1 = 6\n\t6 * 2 = 12\n\t6 * 3 = 18\n\t6 * 4 = 24\n\t6 * 5 = 30\n\t6 * 6 = 36\n\t6 * 7 = 42\n\t6 * 8 = 48\n\t6 * 9 = 54\n\t6 * 10 = 60\n\tjshell\u003e\n\t\n```\n\n Nothing new to explain here. We have only combined stuff you have been learning so far, most recently adding the flavor of methods to the existing  code. \n\n Soak in the power, simplicity and elegance of this program, folks!\n\n#### Overloaded Methods\n\nIt turns out we can call both versions of the method, `printMultiplicationTable()` and `printMultiplicationTable(5)` : \n\n```java\n\n\tjshell\u003e printMultiplicationTable()\n\t5 * 1 = 5\n\t5 * 2 = 10\n\t5 * 3 = 15\n\t5 * 4 = 20\n\t5 * 5 = 25\n\t5 * 6 = 30\n\t5 * 7 = 35\n\t5 * 8 = 40\n\t5 * 9 = 45\n\t5 * 10 = 50\n\tjshell\u003e\n\n```\n\n and \n\n```java\n\n\tjshell\u003e printMultiplicationTable(5)\n\t5 * 1 = 5\n\t5 * 2 = 10\n\t5 * 3 = 15\n\t5 * 4 = 20\n\t5 * 5 = 25\n\t5 * 6 = 30\n\t5 * 7 = 35\n\t5 * 8 = 40\n\t5 * 9 = 45\n\t5 * 10 = 50\n\tjshell\u003e\n\n```\n\nYou can have multiple methods with same name but different number of parameters. This is called ***method overloading***. \n\n#### Summary\n\nIn this step, we:\n\n* Enhanced the logic of ```printMultiplicationTable()``` by passing arguments\n* Added flexibility to the *PMT-Challenge* solution \n* Were introduced to the concept of method overloading\n\n### Step 09:  Methods With Multiple Arguments\n\nIt is possible, and pretty useful, to define methods that accept more than one argument. \n\nWe have already seen how to call two in-built Java methods, ```Math.max``` and ```Math.min```, which accept 2 arguments each. \n\nTime now to enrich our understanding, by writing one such method ourselves as well. \n\nA method ```void sum(int, int)``` that computes the sum of two integers, and prints their output.\n\n```java \n\n\tjshell\u003e void sum(int firstNum, int secondNum) {\n\t   ...\u003e int sum = firstNum + secondNum;\n\t   ...\u003e System.out.println(sum);\n\t   ...\u003e }\n\t| created method sum(int, int)\n\tjshell\u003e sum(5, 10)\n\t15\n\tjshell\u003e\n\n```\n\nA method ```void sum(int, int, int)``` that computes the sum of three integers, and prints their output.\n```java\n\n\tjshell\u003e void sum(int firstNum, int secondNum, int thirdNum) {\n\t   ...\u003e int sum = firstNum + secondNum + thirdNum;\n\t   ...\u003e System.out.println(sum);\n\t   ...\u003e }\n\t| created method sum(int,int,int)\n\tjshell\u003e sum(5, 10, 15)\n\t30\n```\n\nThere are overloaded methods. They have same name ```sum``` and have different number of arguments. \n\n#### Summary\n\nIn this step, we:\n\n* Used our understanding of method overloading to define our own methods\n\n### Step 10: Returning From A Method\n\nA method can also be coded to return the result of its computation. Such a result is called a  **return value**. \n\nA lot of built-in Java methods have return values, the most notable we have seen being ```Math.min()``` and ```Math.max()```. \n\n```java\n\tjshell\u003e Math.max(15, 25)\n\t$1 ==\u003e 25\n\tjshell\u003e $1\n\t$1 ==\u003e 25\n\n```\n\n```Math.max()``` does return a value, which is stored in the ```JShell``` variable ```$1```.\n\nA return mechanism is quite important, as it provides you the flexibility of:\n* Sharing computed results with other code and methods\n* Improving the breaking down of a problem, into sub-problems\n\nThe next example explains how you can collect a method's return value.\n\n```java\n\tjshell\u003e int max = Math.max(15, 25)\n\tmax ==\u003e 25\n\tjshell\u003e max\n\tmax ==\u003e 25\n\tjshell\u003e\n\n```\n\nWe are storing the return value in a variable ```int max```.\n \nWe could define our own method that returns a value, in a similar manner. In the method  ```sumOfTwoNumbers``` above, instead of displaying ```sum``` at once, we could ```return``` it to the calling-code. \n\n```java\n\n\tjshell\u003e int sumOfTwoNumbers(int firstNum, int secondNum) {\n\t   ...\u003e int sum = firstNum + secondNum;\n\t   ...\u003e return sum;\n\t   ...\u003e }\n\t| created method sumOfTwoNumbers(int,int)\n\tjshell\u003e sumOfTwoNumbers(1, 10)\n\t$2 =\u003e 11\n```\n\nThe statement ```return sum;``` is called a **return statement**.\n\nWhen the code ```sum = sumOfTwoNumbers(1, 10)``` is run, ```sum``` collects the result returned by ```sumOfTwoNumbers()```. You could now print ```sum``` on the console, store it in another variable, or even invoke a different method by passing it as an argument!\n\n```\n\tjshell\u003e sum = sumOfTwoNumbers(1, 10)\n\tsum =\u003e 11_\n\tjshell\u003e sum = sumOfTwoNumbers(15, 15)\n\tsum =\u003e 30\n\tjshell\u003e\n```\n\n#### Summary\n\nIn this step, we:\n* Understood the need for a return mechanism with methods\n* Explored the syntax for a return statement\n* Wrote our own method ```sumOfTwoNumbers()``` with a return value, and saw how it became more flexible\n\n### Step 11: Exercise-Set PE-04 (With Solutions)\n\nLet's now try a few exercises on methods that return values.\n\n#### Exercises\n\n1. Write a method that returns the sum of three integers.\n2. Write a method that takes as input two integers representing two angles of a triangle, and computes the third angle. *Hint: The sum of the three angles of a triangle is 180 degrees*. \n\n#### Solution-01\n\n```java\n\n\tjshell\u003e int sumOfThreeNumbers(int firstNum, int secondNum, int thirdNum) {\n\t   ...\u003e int sum = firstNum + secondNum + thirdNum;\n\t   ...\u003e return sum;\n\t   ...\u003e }\n\t| created method sumOfThreeNumbers(int,int, int)\n\tjshell\u003e\n\n```\n\n#### Solution-02\n\n```java\n\n\tjshell\u003e int getThirdAngle(int firstAngle, int secondAngle) {\n\t   ...\u003e int sumOfTwo = firstAngle + secondAngle;\n\t   ...\u003e return 180 - sum;\n\t   ...\u003e }\n\t| created method getThirdAngle(int,int)\n\tjshell\u003e\n\t\n```\n\n### Step 12: Java Methods, A Review\nIn this section, we introduced you to the concept of methods in Java.\n* We understood that methods are routines that perform a unit of computation. They group a set of statements together into a block, and need to be run by being invoked, through a method call. \n* We can define methods that accept no arguments, a single argument and multiple arguments.\n* A method can also be defined to return results of its computation, and this makes it your program more flexible.\n\n## Understanding the Java Platform\n\nJShell is amazing to start with the basics of Java programming. It abstracts all complexities behind writing, compiling and running Java code.\n\nWhat's happening behind the screens? Let's find out.\n\n### Step 01: The Java Platform - An Introduction\n\nA computer only understands binary code, which are sequences of ```0```’s and ```1```’s (called **bits**).  All instructions to a computer should be converted to ```0```’s and ```1```’s before execution.\n\n***When we wrote our code in JShell, how was it converted to binary code?***\n\nWe write our programs in a high-level language, such as Java, as it is easier to learn, remember and maintain. \n\nWho converts it to binary code?\n\nTypically, **Compiler** is a program which understands the syntax of your programming language and converts it into binary code.\n\nJava designers wanted it to be Platform independent. Compile the code once and run it anywhere.\n\nHowever, different Operating Systems have different instruction sets - different binary code. \n\nJava provides an interesting solution:\n- All Java compilers translate source code to an **intermediate representation** ( **bytecode** ). \n- To run Java programs (**bytecode**), you need a ***JVM*** (Java Virtual Machine). \n\t- ***JVM*** understands **bytecode** and runs it. \n\t- There are different JVM's for different operating systems. Windows JVM converts **bytecode** into Windows executable instructions. Linux JVM converts **bytecode** into Linux executable instructions. \n\nThe Java compiler translates Java source code to **bytecode**, which is stored as a **.class** file on the computer.\n\n#### Summary\n\nIn this step, we:\n\n* Understood the role of the Java compiler in translating source code\n* Realized the need for an Intermediate Representation (IR) such as bytecode\n* Understood how the (Compiler + JVM + OS) combination ensure source code portability\n\n### Step 02: Creating a Java ```class```\n\nFirst, let's understand the concept of a `class`.\n\nLet's consider an example: \n\nA **Country** is a *concept*. **India**, **USA** and **Netherlands** are *examples* or *instances* of **Country**.\n\nSimilarly, a `class` is a template. `Objects` are `instances` of a `class`.\n\nWe will discuss more about `class` and `object` in the section on Object Oriented Programming.\n\nThe syntax to create a class, and its objects, is very simple.\n\n```java\n\n\tjshell\u003e class Country {\n\t   ...\u003e }\n\tcreated class Country\n```\n\nLet's create an instance of the class:\n```java\n\tjshell\u003e Country india = new Country();\n\tindia ==\u003e Country@6e06451e\n```\n\nThe syntax is simple - `ClassName objectName = new ClassName()`.\n\n```india``` is an object of type ```Country```, and is stored in memory at a location indicated by ```6e06451e```.\n\nLet's create a few more instances of the class:\n```java\n\tjshell\u003e Country usa = new Country();\n\tusa ==\u003e Country@6e1567f1\n\tjshell\u003e Country netherlands = new Country();\n\tnetherlands ==\u003e Country@5f134e67\n\tjshell\u003e\n\n```\n\n ```india```, ```usa``` and ```netherlands``` are all different objects of type ```Country```. \n\n We actually left the contents of the ```class``` ```Country``` bare. \n\n A ```class``` does often include both data (member variables) and method definitions. More on this at a relevant time.\n\nLet's consider another example:\n\n```java\n\n\tjshell\u003e class Planet {\n\t   ...\u003e}\n\tcreated class Planet\n\tjshell\u003e Planet planet = new Planet();\n\tplanet ==\u003e Planet@56ef9176\n\tjshell\u003e Planet earth = new Planet();\n\tearth ==\u003e Planet@1ed4004b\n\tjshell\u003e Planet planet = new Planet();\n\tvenus ==\u003e Planet@25bbe1b6\n\n```\n\nWe can also create a ```class``` for a different concept, like a ```Planet```. \n\n```Planet``` is now a different template. ```planet```, ```earth``` and ```venus``` are instances of `Planet` class. \n\n#### Summary\n\nIn this step, we:\n\n* Saw how ```class``` creation actually creates a new type\n* Understood how to create instances of classes - objects\n\n### Step 03: Adding A Method To A ```class``` \n\nA method defined within a ```class```, denotes an action than can be performed on objects of that ```class```.\n\nLet's define a method inside ```Planet``` - to ```revolve()```!\n\n```java\n\n\t\tjshell\u003e class Planet {\n\t   ...\u003e void revolve() {\n\t   ...\u003e System.out.println(\"Revolve\");\n\t   ...\u003e }\n\t   ...\u003e }\n\treplaced class Planet\n\tupdate replaced variable planet, reset to null\n\tupdate replaced variable earth, reset to null\n\tupdate replaced variable venus, reset to null\n```\nSyntax of `revolve()` is similar to other methods we've created before. \n\n\u003e The ```class``` template got updated as a result of adding new method.\n\u003e Earlier instances ```planet```,```earth``` and ```venus``` got reset to ```null``` as they are based on the old template\n\nLet's re-instantiate a few objects.\n\n```java\n\tjshell\u003e Planet earth = new Planet();\n\tearth ==\u003e Planet@192b07fd\n\tjshell\u003e Planet planet = new Planet();\n\tvenus ==\u003e Planet@64bfbc86\n\tjshell\u003e\n\n```\n\nHow do we call the ```revolve``` method?\n\n```java\n\n\tjshell\u003e Planet.revolve();\n\t| Error:\n\t| non-static method revolve() cannot be referenced from a static context\n\t| Planet.revolve();\n\t|^-----------------^\n\tjshell\u003e earth.revolve();\n\tRevolve\n\tjshell\u003e venus.revolve();\n\tRevolve\n\tjshell\u003e\n\n```\n\nOur attempt to perform ```revolve()``` did not work with the syntax ```Planet.revolve()``` as it is not a static method (more on that in a later section). \n\nInvoking ```revolve()``` through syntax such as ```earth.revolve()``` succeeds, because ```earth``` is an object of type ```Planet```. \n\n#### Summary\n\nIn this step, we:\n\n* Learned how to add a method definition to an existing ```class```\n* Discovered how to invoke it, on objects of the ```class```\n\n### Step 04: Writing and Running Java Code in separate Source Files\n\nSo far, we have enjoyed creating classes and defining methods within them, all with our friendly neighborhood ```JShell```. \n\n```JShell``` kind of spoiled us kids, by relaxing some Java syntax rules, invoking the compiler on our behalf, and also running the code like room service.\n\nThe time has come for us frog princes to outgrow the proverbial well. Yes, you're right! Time to start writing code in a proper code editor, and smell the greener grass on that side.\n\nLet's start with creating a new source code file - 'Planet.java'. Choose any folder on your hard-disk and create the file shown below:\n\n_**Planet.java**_\n\n```java\n\n\tclass Planet {\n\t\tvoid revolve() {\n\t\t\tSystem.out.println(\"Revolve\");\n\t\t}\n\t}\n\n```\n\n\u003e You can get the code that we wrote earlier in JShell for ```Planet``` by running the command ```/list Planet```, and copying the code. \n\n\u003e You can use any text editor of your choice, for now. \n\nThe source file name must match the ```class``` name it contains. Here, we must name the file `Planet.java`.\n\nThe next course of action would be to compile this code (Stage 2). For that, exit out of ```JShell```, and run back to your system terminal or command prompt. Now, see what plays out!\n\n```java\n\n\tjshell\u003e /exit\n\t|  Goodbye\n```\n\n```cd``` to the folder where you have created the file `Planet.java`\n\n```\n\tin28minutes$\u003e cd in28Minutes/git/JavaForBeginners/\n\tcommand-prompt\u003e ls\n\tPlanet.java\n```\n\nCheck Java version.\n```\n\tcommand-prompt\u003e java -version\n\tjava version \"x.0.1\"\n\tJava(TM) SE Runtime Environment (build x.0.1+11)\n\tJava HotSpot(TM) 64-bit Server VM (build x.0.1+11, mixed mode)\n```\n\nYou can compile java code using ```javac Planet.java```. You can see that a new file is created `Planet.class`. This contains your `bytecode`.\n\n```\n\tcommand-prompt\u003e javac Planet.java\n\tcommand-prompt\u003e ls\n\tPlanet.class         Planet.java_\n```\n\nYou can run the class using command `java Planet`.\n\n```java\n\tcommand-prompt\u003e java Planet\n\tError: Main method not found inside class Planet, please define the main method as\n\tpublic static void main(String[] args)\n\tor a JavaFX application class must extend javax.application.Application\n\tcommand-prompt\u003e\t\n```\n\nWhy is there an error? Let's discuss that in the next step.\n\n#### Summary\n\nIn this step, we:\n\n* Ventured out of ```JShell``` into unexplored territory, to write source code\n* Learned how to invoke the compiler to compile source files, from the terminal\n\n### Step 05: Introducing ```main()```, And Running Bytecode\n\nIn the previous step, we compiled **_Planet.java_**. In this step, let's run the bytecode generated, which lies inside **_Planet.class_**.\n\n##### Snippet-01: Running ```Planet```\n\n**_Console Commands_**\n\n```java\n\n\tcommand-prompt\u003e ls\n\tPlanet.class         Planet.java\n\tcommand-prompt\u003e java Planet\n\tError: Main method not found inside class Planet, please define the main method as\n\tpublic static void main(String[] args)\n\tor a JavaFX application class must extend javax.application.Application\n\tcommand-prompt\u003e\n\n```\n\nThe code may have compiled without any errors, but what's the use if we cannot run the program to see what stuff it's got!\n\n**_The ```main()``` method is essential to run code defined within any ```class```._**\n\nThe definition of ```main()``` needs to have this exact synatx:\n\n`public static void main(String[] args) {  /* \u003cSome Code Goes In Here\u003e */ }`\n\nA few details:\n* `void` is its return type\n* `main` is its name\n* `args` is its formal argument. Here, it's an **array** of ```String```.\n* `public``` and ```static``` are reserved Java keywords. More on these later sections.\n\n\nLet's add one such definition within the ```Planet``` code. Open up your text editor and add the ```main``` method as shown below.\n\n**_Planet.java_**\n\n```java\n\n\tclass Planet {\n\t\tvoid revolve() {\n\t\t\tSystem.out.println(\"Revolve\");\n\t\t}\n\t\tpublic static void main(String[] args) {\n\n\t\t}\n\t}\n\n```\n\nLet's run it now:\n\n```java\n\n\tcommand-prompt\u003e java Planet\n\tError: Main method not found inside class Planet, please define the main method as\n\tpublic static void main(String[] args)\n\tor a JavaFX application class must extend javax.application.Application\n```\n\nWhy is there no change in result?\n\nAfter changing your Java source file, you need to compile the code again to create a new class file.\n\n```\n\tcommand-prompt\u003e javac Planet.java\n\tcommand-prompt\u003e ls\n\tPlanet.class         Planet.java_\n```\n\nLet's try it again.\n```\n\tcommand-prompt\u003e java Planet\n\tcommand-prompt\u003e\n\n```\n\nWe got a blank stare from the terminal. Why?\n\nWhat did we write in the ```main``` method? Nothing.\n\n```java\n\t\tpublic static void main(String[] args) {\n\n\t\t}\n\n```\n\nLet's fix it. We need to edit **_Planet.java_** once again!\n\n**_Planet.java_**\n\n```java\n\n\tclass Planet {\n\t\tvoid revolve() {\n\t\t\tSystem.out.println(\"Revolve\");\n\t\t}\n\t\tpublic static void main(String[] args) {\n\t\t\tPlanet earth = new Planet();\n\t\t\tearth.revolve();\n\t\t}\n\t}\n\n```\n\n**_Console Commands_**\n\n```java\n\n\tcommand-prompt\u003e javac Planet.java\n\tcommand-prompt\u003e ls\n\tPlanet.class         Planet.java\n\tcommand-prompt\u003e java Planet\n\tRevolve\n\tcommand-prompt\u003e\n\n```\n\nBingo! We finally got what we wanted to see!\n\n#### Summary\n\nIn this step, we:\n\n* Learned that we need a ```main()``` method to run a Java program\n* Discovered that after every code update, we need to compile that source file\n\n### Step 06: Puzzles About ```Planet```\n\nIn this step, let's play with ```Planet``` source code. Get ready for a comedy of errors, by trial-and-error!\n\nBelow is the source code for ```Planet``` that worked so well for us:\n\n**_Planet.java_**\n\n```java\n\n\tclass Planet {\n\t\tvoid revolve() {\n\t\t\tSystem.out.println(\"Revolve\");\n\t\t}\n\t\t\n\t\tpublic static void main(String[] args) {\n\t\t\tPlanet earth = new Planet();\n\t\t\tearth.revolve();\n\t\t}\n\t}\n\n```\n\nHere starts our nut-job.\n\n##### Snippet-01: Messing-up ```main()``` - v1\n\nChange method name from `main` to `main1`\n\n**_Planet.java_**\n\n```java\n\n\tclass Planet {\n\t\tvoid revolve() {\n\t\t\tSystem.out.println(\"Revolve\");\n\t\t}\n\n\t\tpublic static void main1(String[] args) {\n\t\t\tPlanet earth = new Planet();\n\t\t\tearth.revolve();\n\t\t}\n\t}\n\n```\n\n**_Console Commands_**\n\n```java\n\n\tcommand-prompt\u003e javac Planet.java\n\tcommand-prompt\u003e java Planet\n\tError: Main method not found inside class Planet, please define the main method as\n\tpublic static void main(String[] args)\n\tor a JavaFX application class must extend javax.application.Application\n\tcommand-prompt\u003e\n\n```\n\nDon't mess with the method-name of ```main()```.\n\nOther parts also need to remain the same, such as:\n* The return-type: ```void```\n* Argument type: ```String[]```\n* The presence of keywords ```public``` and ```static```.\n\n##### Snippet-02: Messing-up ```main()``` - v2\n\nRemove semicolons after statements `Planet earth = new Planet()` and `earth.revolve()`.\n\n**_Planet.java_**\n\n```java\n\n\tclass Planet {\n\t\tvoid revolve() {\n\t\t\tSystem.out.println(\"Revolve\");\n\t\t}\n\n\t\tpublic static void main(String[] args) {\n\t\t\tPlanet earth = new Planet()\n\t\t\tearth.revolve()\n\t\t}\n\t}\n\n```\n\n**_Console Commands_**\n\n```java\n\n\tcommand-prompt\u003e javac Planet.java\n\tPlanet.java:6: error: ';' expected\n\tPlanet earth =  new Planet()\n\t|_______________________^\n\tPlanet.java:7: error: ';' expected\n\tearth.revolve()\n\t|_____________^\n\t2 errors\n\tcommand-prompt\u003e\n\n```\n\nThe ```;``` symbol is the Java statement separator, which is mandatory. \n\nIt is not needed in JShell but mandatory when you write separate Java source files.\n\n##### Snippet-03: Messing-up ```main()``` - v3\n\nMake a typo `Planet earth = new Plane();`\n\n**_Planet.java_**\n\n```java\n\n\tclass Planet {\n\t\t\n\t\tvoid revolve() {\n\t\t\tSystem.out.println(\"Revolve\");\n\t\t}\n\n\t\tpublic static void main(String[] args) {\n\t\t\tPlanet earth = new Plane();\n\t\t\tearth.revolve();\n\t\t}\n\t}\n\n```\n\n**_Console Commands_**\n\n```java\n\n\tcommand-prompt\u003e javac Planet.java\n\tPlanet.java:6: error: cannot find symbol\n\tPlanet earth =  new Plane();\n\t|________________^\n\tsymbol: class Plane\n\tlocation: class Planet\n\t1 error\n\tcommand-prompt\u003e\n\n```\n\nWe misspelled ```Planet``` as **```Plane```**, and the compiler trapped this error. It shows us a red flag with a message to help us correct our mistake. \n\n##### Snippet-04: Messing-up ```main()``` - v4\n\nCall a non existing method `earth.revolve1();`.\n\n**_Planet.java_**\n\n```java\n\n\tclass Planet {\n\t\tvoid revolve() {\n\t\t\tSystem.out.println(\"Revolve\");\n\t\t}\n\n\t\tpublic static void main(String[] args) {\n\t\t\tPlanet earth = new Planet();\n\t\t\tearth.revolve1();\n\t\t}\n\t}\n\n```\n\n**_Console Commands_**\n\n```java\n\n\tcommand-prompt\u003e javac Planet.java\n\tPlanet.java:7: error: cannot find symbol\n\tearth.revolve1();\n\t|_____^\n\tsymbol: method revolve1()\n\tlocation: variable earth of type Planet\n\t1 error\n\tcommand-prompt\u003e\n\n```\n\nWe misspelled the name of the ```revolve()``` method, to **```revolve1()```**. Rightly, got rapped on our knuckles by the compiler.\n\n#### Summary\n\nIn this step, we:\n\n* Learned that the best way to learn about language features is to play around with working code\n* Observed that ```JShell``` simplifies coding for us, even relaxing some syntax rules\n* Concluded that developing Java code in code-editors is an empowering feeling!\n\n### Step 07: The JVM, JRE And JDK\n\nWhat are *JVM*, *JRE* and the *JDK*? \n\nApart from the fact that all start with a '*J*', there are important differences in what they contain, and what they do. \n\nThe following list gives you a bird's eye view of things.\n\nThe **JVM** runs your program bytecode.\n\n\n**JRE** = **JVM** + **Libraries** + **Other Components**\n\n* *Libraries* are built-in Java utilities that can be used within any program you create. ```System.out.println()``` was a method in ```java.lang```, one such utility.\n* *Other Components* include tools for debugging and code profiling (for memory management and performance).\n\n\n**JDK** = **JRE** + **Compilers** + **Debuggers**\n\n* *JDK* refers to the **Java Development Kit**. It's an acronym for the bundle needed  to compile (with the compiler) and run (with the *JRE* bundle) your Java program.\n\nAn interesting way to remember this organization is:\n\n* **JDK** is needed to **Compile and Run** Java programs\n\n* **JRE** is needed to **Run** Java Programs\n\n* **JVM** is needed to **Run Bytecode** generated from Java programs\n\nLet's check a couple of scenarios to test your understanding.\n\n**Scenario 1**: You give *Planet.class* file to a friend using a different operating system. What does he need to do to run it? \n\nFirst, install **JRE** for his operating system. Run using *java Planet* on the terminal. He does not need to run  *javac*, as he already has the bytecode. \n\n**Scenario 2**: You gave your friend the source file *Planet.java*. What does he need to do to run it? \n\nInstall *JDK* of a compatible version. Compile code using *javac Planet.java*. Run *java Planet* on his terminal.\n\nIn summary\n\n* **Application Developers** _need_ **==\u003e JDK**\n\n* **Application Users** _need_ **==\u003e JRE**\n\n#### Summary\n\nIn this step, we:\n* Understood the differences in the scope-of-work done by the JVM, JRE and JDK\n* Realized how each of them could be invoked by different terminal commands, such as *javac* and *java*.\n\n## Eclipse\n\nTODO - Need Revision \n\n### Introducing Java Software Development with Eclipse\n\n* Features of the Eclipse IDE (Integrated Development Environment)\n\t* Installation \u0026 Configuration\n\t* Workspace Creation \u0026 Configuration\n\t* Project Creation \u0026 Organization\n\t\t* JRE Version Selection and Included Libraries \n\t\t* Eclipse Java Perspectives\n\t\t* Source Files Organization into Folders\n\t\t* Packages?\n\t* IDE User Interface Description\n\t\t* Perspective\n\t\t* Views\n\t\t* Console Content and Display Options\n\n* Creating a new Java ```class``` in Eclipse (And related source file)\n\t* Package name\n\t\t* A Java solution to solving a problem could be composed of several application components. It is considered good programming arctice to identify a class for each distinct component. Package is the Java way to organize classes in source code.\n\t\t* Analogy: Eatables in a Refrigerator (Freezer, Chill-Tray, Vegetable-Tray, Bottle-Rack)\n\t* Public method stub : can be used to create a default ```public static void main(String[] args)``` signature\n\t* (Include Snapshots)\n\t\t* Class creation pop-up, with selected options\n\t\t* Default generated source code in editor window\n\n\t* Customizing the generated source code to our needs\n\t\t* Syntax Highlighting\n\t\t\t* Keywords\n\t\t\t* Built-in Types\n\t\t\t* Constant literals: numbers, strings\n\t\t* Auto-suggest feature of eclipse as code is being typed in\n\n\t* The \"Run as --\u003e Java Application\" Option to compile-and-run the source code\n\t\t* Option is avaibale only for classes that have a main() method\n\n\n#### Using Eclipse in Debug Mode\n\nExecution of the Multiplication Table Program can be done Step by-step. That is, the entire application dies not execute at one go, printing the final output onto the console. We can stall its flow at several steps, by taking control of its execution using the Eclipse IDE. This is possible in a special mode of Eclipse, called **Debug Mode**. \n\nThe process is called **Debugging**, because this mode is heavily used not just to have fun seeing what happens, but also to detect and fix software **bugs**. A bug is a defect in the program being written, that leads to its incorrect execution. The process of removing bugs is called debugging. Humans being humans, programming errors are but natural, and a debug mode in the IDE is worth its wight in gold to the programmer. Here is how Eclipse facilitates debugging of Java applications.\n\n* Prior to debugging application, we need to set few **Break-Points**. A Break-Point is a statement in the source of the program, before which execution under debug mode is suspended, and control is passed to the programmer.\n* The overall state of the data in the suspended program is available to the programmer at that particular break-point. He/she gets to specify one or more break-points in the program, and when the execution is suspended, a list of possible actions can be performed, including: \n\t* Reading \u0026 modifying data variables \n\t* Resuming program execution \n\t* Re-executing current statement\n\t* Skipping all statements till the next break-point\n\t\n\tand others.\n\n* The Eclipse IDE provides a very user-friendly and intuitive interface to the programmer for controlling execution of a program in Debug Mode (Provide Snapshots of IDE at various stages of Debug Mode execution).\n\t* Setting and Removing a Break-point (also Toggling)\n\t* Stepping over a method call, or into and out of a method body (during a method call)\n\t\t* Stepping into ```int print()``` and ```int print(int)``` and ```int print(int,int,int)``` gives us interesting infromation, but stepping into ```System.out.printf``` can freak you out! So, you may want to step over it. \n\t* For nested method calls, examine the method call **Stack Trace** (Call child, call parent relationship)\n\t\t* Example : ```int print()```, ```int print(int)``` and ```int print(int,int,int)``` method call chain of ```class MultiplicationTable```.\n\t* Viewing and Modifying current state of data variables, at a break point\n\t* Stepping through from one statement to another in the source code\n\t\t* As we step through, observe the view displaying changes in data variable values\n\t\t* Example of ```for``` loop control variable ```i```, inside method ```int print(int,int,int)``` of ```class MultiplicationTable```\n\t\t* Observe that execution exits from the ```for``` loop when the condition ```i\u003c=10``` is no longer ```true```.\n\t* Re-executing a line of code\n\t* Skipping execution of all statements till next break-point\n\t* Ignoring all remaining breakpoints, resume execution of code till completion\n\n### Eclipse IDE Keyboard Shortcuts\n\n* Code Text Editor Shortcuts\n* New Project/Class Creation Shortcuts\n* Search for a Class\n\n### Differences between JShell and IDE\n\nVariables just declared, but used without an initialization, will flag a compilation  error in an IDE! But not so, it seems, in JShell. In regular software, variable initialization at point of declaration (called a \"defintion\", as we already know) is mandatory. \n\n##### Snippet-1 : JShell redefines variables on demand\n\n```java\n\n\tjshell\u003e int i = 2\n\t$1 ==\u003e 2\n\tjshell\u003e int i = 4\n\t$2 ==\u003e 4\n\tjshell\u003e long i = 1000\n\t$3 ==\u003e 1000\n\tjshell\u003e\n\n```\n\n\nWhen the following code (similar to the one given to JShell) is compiled manually or by IDEs such as Eclipse, it will flag errors! \n\n```java\n\n\tpackage com.in28minutes.firstjavaproject;\n\t\n\tpublic class RedefineTestRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tint i = 2;\n\t\t\tint i = 4;\n\t\t\tlong i = 1000;\n\t\t\tSystem.out.println(i);\n\t\t}\n\t}\n\n```\n\nThat is because Java source code is governed by strict **Scope Rules**.\n\n\n\nLet's have another look at where we have reached with our solution, to the *PMT-Challenge* problem. Only now, let's change the code arrangement.\n\n##### Snippet-01: Revisited - The *PMT-Challenge*\n\n**_MultiplicationTable.java_**\n\n```java\n\n\tpackage com.in28minutes.firstjavaproject;\n\tpublic class MultiplicationTable {\n\t\tpublic static void print() {\n\t\t\tfor(int i=1; i\u003c=10;i++) {\n\t\t\t\tSystem.out.printf(\"%d * %d = %d\", 5, i, 5*i).println();\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_MultiplicationRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.firstjavaproject;\n\n\tpublic class MultiplicationRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMultiplicationTable table = new MultiplicationTable();\n\t\t\ttable.print();\t\n\t}\t\n}\n\n```\n\n**_Console Output_**\n\n_5 * 1 = 5_\n\n_5 * 2 = 10_\n\n_5 * 3 = 15_\n\n_5 * 4 = 20_\n\n_5 * 5 = 25_\n\n_5 * 6 = 30_\n\n_5 * 7 = 35_\n\n_5 * 8 = 40_\n\n_5 * 9 = 45_\n\n_5 * 10 = 50_\n\n##### Snippet-01 Explained\n\n* We have now split the code into two source files: \n\t* **_MultiplicationTable.java_**: Houses the ```MultiplicationTable``` ```class``` definition, with some methods we need.\n\t* **_MultiplicationRunner.java_**: Acts as the client of the ```MultiplicationTable``` ```class```, to invoke its functionality. It defines a ```main()``` method, that instantiates a ```MultiplicationTable```object, and invokes its ```print()``` method.\n* After this code was rearranged, we still got it to work!\n\n#### Print-Multiplication-Table: Enhancements\n\n* We now want to enhance our current solution to this challenge, even though we've come a long way. **\"Once you get the whiff of success, sky is the limit!\"**. Here is the changes we need:\n\t* Pass the number whose table needs to be printed, as an argument\n\t* Pass the (continuous) range of numbers, whose index entries in the table are to be printed. (For example, printing the table entries for ```6```, with entries for indexes between ```15``` to ```30```).\n\nOne way to achieve all this, would involve overloading the ```print()``` method. The next example is one such attempt.\n\n##### Snippet-02: print() overloaded\n\nOverloading ```print()``` works for us, and we now support three ways in which to display  any table:\n\n```java\n\n\t\tpublic static void print() {\n\t\t\tfor(int i=1; i\u003c=10;i++) {\n\t\t\t\tSystem.out.printf(\"%d * %d = %d\", 5, i, 5*i).println();\n\t\t\t}\n\t\t}\n\n```\t\n\n**_Console Output_**\n\n_5 * 1 = 5_\n\n_5 * 2 = 10_\n\n_5 * 3 = 15_\n\n_5 * 4 = 20_\n\n_5 * 5 = 25_\n\n_5 * 6 = 30_\n\n_5 * 7 = 35_\n\n_5 * 8 = 40_\n\n_5 * 9 = 45_\n\n_5 * 10 = 50_\n\nThe default table for ```5```, with entries fixed within ```1``` to ```10```. \n\n```java\n\n\t\tpublic static void print(int number) {\n\t\t\tfor(int i=1; i\u003c=10;i++) {\n\t\t\t\tSystem.out.printf(\"%d * %d = %d\", number, i, number*i).println();\n\t\t\t}\n\t\t}\n\n```\n\n**_Console Output_**\n\n_8 * 1 = 8_\n\n_8 * 2 = 16_\n\n_8 * 3 = 24_\n\n_8 * 4 = 32_\n\n_8 * 5 = 40_\n\n_8 * 6 = 48_\n\n_8 * 7 = 56_\n\n_8 * 8 = 64_\n\n_8 * 9 = 72_\n\n_8 * 10 = 80_\n\nPrinting a table for any number, but with entries fixed between ```1``` and ```1```.\n\n```java\n\n\t\tpublic static void print(int number, int from, int to) {\n\t\t\tfor(int i=from; i\u003c=to;i++) {\n\t\t\t\tSystem.out.printf(\"%d * %d = %d\", number, i, number*i).println();\n\t\t\t}\n\t\t}\n\n```\n\n**_Console Output_**\n\n_6 * 11 = 66_\n\n_6 * 12 = 72_\n\n_6 * 13 = 78_\n\n_6 * 14 = 84_\n\n_6 * 15 = 90_\n\n_6 * 16 = 96_\n\n_6 * 17 = 102_\n\n_6 * 18 = 108_\n\n_6 * 19 = 114_\n\n_6 * 20 = 120_\n\nDisplaying a table for any number, with entries for any range\n\nThe full code:\n\n**_MultiplicationTable.java_**\n\n```java\n\n\tpackage com.in28minutes.firstjavaproject;\n\t\n\tpublic class MultiplicationTable {\n\t\tpublic static void print() {\n\t\t\tfor(int i=1; i\u003c=10;i++) {\n\t\t\t\tSystem.out.printf(\"%d * %d = %d\", 5, i, 5*i).println();\n\t\t\t}\n\t\t}\t\n\t\n\t\tpublic static void print(int number) {\n\t\t\tfor(int i=1; i\u003c=10;i++) {\n\t\t\t\tSystem.out.printf(\"%d * %d = %d\", number, i, number*i).println();\n\t\t\t}\n\t\t}\n\n\t\tpublic static void print(int number, int from, int to) {\n\t\t\tfor(int i=from; i\u003c=to;i++) {\n\t\t\t\tSystem.out.printf(\"%d * %d = %d\", number, i, number*i).println();\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n\n**_MultiplicationRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.firstjavaproject;\n\n\tpublic class MultiplicationRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMultiplicationTable table = new MultiplicationTable();\n\t\t\ttable.print();\n\t\t\ttable.print(8);\n\t\t\ttable.print(6, 11, 20);\n\t\t}\n\t}\n\n```\n\n#### Issue: Code Duplication In Print-Multiplication-Table\n\nThere is an issue with the code for ```class MultiplicationTable```. In the final print format, what if we are asked to replace the multiplication symbol '```*```' with an '```X```', so that school kids like it better? Since there are three calls to ```System.out.printf()```, one in each ```print()``` version, we make three changes.\n\n##### Snippet-3: Code Duplication\n\n**_MultiplicationTable.java_**\n\n```java\n\n\tpackage com.in28minutes.firstjavaproject;\n\n\tpublic class MultiplicationTable {\n\t\tpublic static void print() {\n\t\t\tfor(int i=1; i\u003c=10;i++) {\n\t\t\t\tSystem.out.printf(\"%d X %d = %d\", 5, i, 5*i).println();\n\t\t\t}\n\t\t}\n\n\t\tpublic static void print(int number) {\n\t\t\tfor(int i=1; i\u003c=10;i++) {\n\t\t\t\tSystem.out.printf(\"%d * %d = %d\", number, i, number*i).println();\n\t\t\t}\n\t\t}\n\n\t\tpublic static void print(int number, int from, int to) {\n\t\t\tfor(int i=from; i\u003c=to;i++) {\n\t\t\t\tSystem.out.printf(\"%d X %d = %d\", number, i, number*i).println();\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_5 X 1 = 5_\n\n_5 X 2 = 10_\n\n_5 X 3 = 15_\n\n_5 X 4 = 20_\n\n_5 X 5 = 25_\n\n_5 X 6 = 30_\n\n_5 X 7 = 35_\n\n_5 X 8 = 40_\n\n_5 X 9 = 45_\n\n_5 X 10 = 50_\n\n_8 * 1 = 8_\n\n_8 * 2 = 16_\n\n_8 * 3 = 24_\n\n_8 * 4 = 32_\n\n_8 * 5 = 40_\n\n_8 * 6 = 48_\n\n_8 * 7 = 56_\n\n_8 * 8 = 64_\n\n_8 * 9 = 72_\n\n_8 * 10 = 80_\n\n_6 X 11 = 66_\n\n_6 X 12 = 72_\n\n_6 X 13 = 78_\n\n_6 X 14 = 84_\n\n_6 X 15 = 90_\n\n_6 X 16 = 96_\n\n_6 X 17 = 102_\n\n_6 X 18 = 108_\n\n_6 X 19 = 114_\n\n_6 X 20 = 120_\n\n##### Snippet-3 Explained\n\n* Humans make mistakes. The programmer missed out on changing the format symbol in the code for ```void print(int, int)```, but we don't recommend punishment. He could be overworked, or could only be the maintainer of code someone else wrote years ago! The point is not to blame human flaws (there are many), but to show how code duplication causes errors. This issue arises frequently with overloaded methods, point blank. \n* Instead of trying to change human nature, can we change our software? Let's have a closer look at ```print()```:\n\t* The method ```void print()``` prints the multiplication table for ```5``` only, in the default range ```1``` to ```10```.\n\t* The method ```void print(int)``` outputs the table for any number, but only in the fixed range from ```1``` to ```10```.\n\t* The method ```void print(int,int,int)``` displays the table for any number, in any range of entries.\n\t\n#### A Solution: Code Reuse\n\nThere is something huge we observe in the previous example. All overloaded versions of ```print()``` have nearly the same code!\n\n* ```print(int)``` has wider usage potential than ```print()```. The latter is a special case, as it prints only the for  ```5```.  We can achieve what ```print()``` does, by passing a **fixed** parameter value of ```5``` to ```print(int)```. It's simple: invoke ```print(int)``` within ```print()```, by passing ```5``` to it.\n* The point to note is, that **a more specialized function can be implemented-in-terms-of a more general function**. \n\nLet's now reorganize this part of the code.\n\n##### Snippet-4: Code Reuse\n\n**_MultiplicationTable.java_**\n\n```java\n\n\tpublic static void print() {\n\t\tprint(5);\n\t}\n\n\tpublic static void print(int number) {\n\t\tfor(int i=1; i\u003c=10;i++) {\n\t\t\tSystem.out.printf(\"%d * %d = %d\", number, i, number*i).println();\n\t\t}\n\t}\n\n```\n\n**_MultiplicationRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.firstjavaproject;\n\n\tpublic class MultiplicationRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMultiplicationTable table = new MultiplicationTable();\n\t\t\ttable.print();\n\t\t\ttable.print(8);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_5 * 1 = 5_\n\n_5 * 2 = 10_\n\n_5 * 3 = 15_\n\n_5 * 4 = 20_\n\n_5 * 5 = 25_\n\n_5 * 6 = 30_\n\n_5 * 7 = 35_\n\n_5 * 8 = 40_\n\n_5 * 9 = 45_\n\n_5 * 10 = 50_\n\n_8 * 1 = 8_\n\n_8 * 2 = 16_\n\n_8 * 3 = 24_\n\n_8 * 4 = 32_\n\n_8 * 5 = 40_\n\n_8 * 6 = 48_\n\n_8 * 7 = 56_\n\n_8 * 8 = 64_\n\n_8 * 9 = 72_\n\n_8 * 10 = 80_\n\n##### Snippet-4 Explained\n\nWhen we call a method inside another, the method call statement is replaced by its body (with actual arguments replacing the formal ones). In the new definition of ```int print()``` above, the code executed during the call will be:\n\n```java\n\n\tfor(int i=1; i\u003c=10;i++) {\n\t\tSystem.out.printf(\"%d * %d = %d\", 5, i, 5*i).println();\n\t}\n\n```\n\n#### Extending Code Reuse\n\n* The method ```int print(int,int,int)``` is a more general version of ```int print(int)```. We can achieve what the latter computes, by passing **fixed** range of indexes, namely  ```1``` and ```10```, as arguments to the former. have look into he code that follows.\n\n##### Snippet-5 : Extending code reuse\n\n**_MultiplicationTable.java_**\n\n```java\n\n\tpublic static void print(int number) {\n\t\tprint(number, 1, 10);\t\t\n\t}\t\n\n\tpublic static void print(int number, int from, int to) {\n\t\tfor(int i=from; i\u003c=to;i++) {\n\t\t\tSystem.out.printf(\"%d X %d = %d\", number, i, number*i).println();\n\t\t}\n\t}\n\n```\n\n**_MultiplicationRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.firstjavaproject;\n\n\tpublic class MultiplicationRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMultiplicationTable table = new MultiplicationTable();\n\t\t\ttable.print(8);\n\t\t\ttable.print(6, 11, 20);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_8 * 1 = 8_\n\n_8 * 2 = 16_\n\n_8 * 3 = 24_\n\n_8 * 4 = 32_\n\n_8 * 5 = 40_\n\n_8 * 6 = 48_\n\n_8 * 7 = 56_\n\n_8 * 8 = 64_\n\n_8 * 9 = 72_\n\n_8 * 10 = 80_\n\n_6 * 11 = 66_\n\n_6 * 12 = 72_\n\n_6 * 13 = 78_\n\n_6 * 14 = 84_\n\n_6 * 15 = 90_\n\n_6 * 16 = 96_\n\n_6 * 17 = 102_\n\n_6 * 18 = 108_\n\n_6 * 19 = 114_\n\n_6 * 20 = 120_\n\n##### Snippet-5 Explained\n\n* This example merely extended what we did in the previous example. We will will take this extension one level further now! Yes, you guessed right. We will implement ```print()``` in terms of ```print(int,int,int)```.\n\n##### Snippet-6 : Extending code reuse (contd.)\n\n**_MultiplicationTable.java_**\n\n```java\n\n\tpublic static void print() {\n\t\tprint(5, 1, 10);\n\t}\n\n\tpublic static void print(int number, int from, int to) {\n\t\tfor(int i=from; i\u003c=to;i++) {\n\t\t\tSystem.out.printf(\"%d X %d = %d\", number, i, number*i).println();\n\t\t}\n\t}\n\n```\n\n\n**_MultiplicationRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.firstjavaproject;\n\n\tpublic class MultiplicationRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMultiplicationTable table = new MultiplicationTable();\n\t\t\ttable.print();\n\t\t\ttable.print(6, 11, 20);\n\t\t}\n\t}\n\n```\n\n\n**_Console Output_**\n\n_5 * 1 = 5_\n\n_5 * 2 = 10_\n\n_5 * 3 = 15_\n\n_5 * 4 = 20_\n\n_5 * 5 = 25_\n\n_5 * 6 = 30_\n\n_5 * 7 = 35_\n\n_5 * 8 = 40_\n\n_5 * 9 = 45_\n\n_5 * 10 = 50_\n\n_6 * 11 = 66_\n\n_6 * 12 = 72_\n\n_6 * 13 = 78_\n\n_6 * 14 = 84_\n\n_6 * 15 = 90_\n\n_6 * 16 = 96_\n\n_6 * 17 = 102_\n\n_6 * 18 = 108_\n\n_6 * 19 = 114_\n\n_6 * 20 = 120_\n\n##### Snippet-6 Explained\n\n*  By extending the same logic of code reuse, the method ```int print(int,int,int)``` can be used to implement the logic of ```int print()```. Just pass in a number parameter ```5```, as well as the fixed range parameters ```1``` and ```10```, in a call to the former. ```int print()``` is thus **implemented-in-terms-of** ```int print(int,int,int)```.\n\n* Our new version of ```class MultiplicationTable``` looks like this:\n\n##### Snippet-7: Extending Code Reuse (Contd.)\n\n**_MultiplicationTable.java_**\n\n```java\n\n\tpackage com.in28minutes.firstjavaproject;\n\n\tpublic class MultiplicationTable {\n\t\tpublic static void print() {\n\t\t\tprint(5, 1, 10);\n\t\t}\n\n\t\tpublic static void print(int number) {\n\t\t\tprint(number, 1, 10);\n\t\t}\n\n\t\tpublic static void print(int number, int from, int to) {\n\t\t\tfor(int i=from; i\u003c=to;i++) {\n\t\t\t\tSystem.out.printf(\"%d X %d = %d\", number, i, number*i).println();\n\t\t\t}\t\n\t\t}\n\t}\n\n```\n\n* The logic of the ```class MutliplicationRunner``` does not change at all:\n\n**_MultiplicationRunner.java:_**\n\n```java\n\n\tpackage com.in28minutes.firstjavaproject;\n\t\n\tpublic class MultiplicationRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMultiplicationTable table = new MultiplicationTable();\n\t\t\ttable.print();\n\t\t\ttable.print(8);\n\t\t\ttable.print(6, 11, 20);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_5 * 1 = 5_\n\n_5 * 2 = 10_\n\n_5 * 3 = 15_\n\n_5 * 4 = 20_\n\n_5 * 5 = 25_\n\n_5 * 6 = 30_\n\n_5 * 7 = 35_\n\n_5 * 8 = 40_\n\n_5 * 9 = 45_\n\n_5 * 10 = 50_\n\n_8 * 1 = 8_\n\n_8 * 2 = 16_\n\n_8 * 3 = 24_\n\n_8 * 4 = 32_\n\n_8 * 5 = 40_\n\n_8 * 6 = 48_\n\n_8 * 7 = 56_\n\n_8 * 8 = 64_\n\n_8 * 9 = 72_\n\n_8 * 10 = 80_\n\n_6 * 11 = 66_\n\n_6 * 12 = 72_\n\n_6 * 13 = 78_\n\n_6 * 14 = 84_\n\n_6 * 15 = 90_\n\n_6 * 16 = 96_\n\n_6 * 17 = 102_\n\n_6 * 18 = 108_\n\n_6 * 19 = 114_\n\n_6 * 20 = 120_\n\n##### Snippet-7 Explained\n\nNeat, isn't it! To make our program school kid friendly, we just need to change one character in the code, take a peek below.\n\n##### Snippet-8 : Extending Code Reuse (Contd.)\n\n**_MultiplicationTable.java:_**\n\n```java\n\n\tpackage com.in28minutes.firstjavaproject;\n\n\tpublic class MultiplicationTable {\n\t\tpublic static void print() {\n\t\t\tprint(5, 1, 10);\t\t\n\t\t}\n\n\t\tpublic static void print(int number) {\n\t\t\tprint(number, 1, 10);\n\t\t}\n\n\t\tpublic static void print(int number, int from, int to) {\n\t\t\tfor(int i=from; i\u003c=to;i++) {\n\t\t\t\tSystem.out.printf(\"%d X %d = %d\", number, i, number*i).println();\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_5 X 1 = 5_\n\n_5 X 2 = 10_\n\n_5 X 3 = 15_\n\n_5 X 4 = 20_\n\n_5 X 5 = 25_\n\n_5 X 6 = 30_\n\n_5 X 7 = 35_\n\n_5 X 8 = 40_\n\n_5 X 9 = 45_\n\n_5 X 10 = 50_\n\n_8 X 1 = 8_\n\n_8 X 2 = 16_\n\n_8 X 3 = 24_\n\n_8 X 4 = 32_\n\n_8 X 5 = 40_\n\n_8 X 6 = 48_\n\n_8 X 7 = 56_\n\n_8 X 8 = 64_\n\n_8 X 9 = 72_\n\n_8 X 10 = 80_\n\n_6 X 11 = 66_\n\n_6 X 12 = 72_\n\n_6 X 13 = 78_\n\n_6 X 14 = 84_\n\n_6 X 15 = 90_\n\n_6 X 16 = 96_\n\n_6 X 17 = 102_\n\n_6 X 18 = 108_\n\n_6 X 19 = 114_\n\n_6 X 20 = 120_\n\n##### Snippet-8 Explained\n\nSoftware Development is an iterative process. The best code that we want to write does not happen at one go. It starts off at a certain level, and can always be improved. More importantly, such improvements needs to be remembered, to be applied again at different points in the same program, and across programs. This process is called **Code Refactoring**. Thought we'd keep you posted.\n\n#### Summary\n\nIn this step, we:\n\n* Explored how to reorganize the code for *PMT-Challenge* into a ```class```\n* Understood that overloading works the same way for ```class``` methods\n* Observed that code reuse is possible across overloaded versions of a ```class``` method\n\n## Object Oriented Progamming (OOP)\n\nHow do you design great Object Oriented Programs?\n\nLet's find out\n\nRecommended Videos:\n- Object Oriented Progamming - Part 1 - https://www.youtube.com/watch?v=NOD802rMMCw\n- Object Oriented Progamming - Part 2 - https://www.youtube.com/watch?v=i6EztA-F8UI\n\n### Step 01: Object Oriented Progamming (OOP) - Basic Terminology\n\nLet's consider a few examples before we get to Object Oriented Progamming.\n\nHumans think in a step by step process.\n\nLet's say I've to take a flight from London to New York. This is how I would think:\n\n- Take a cab to London Airport\n- Check in\n- Pass Security\n- Board the flight\n- Wish the Hostess\n- Take Off\n- Cruise\n- Land\n- Get off the plane\n- Take a cab to ..\n\nProcedural programming is just a reflection of this thought process. A procedural program for above process would look something like this:\n\n```java\ntakeACabToLondonAirport();\ncheckIn();\npassSecurity();\nboardPlane();\nwishHostess();\ntakeOff();\ncruiseMode();\nland();\ngetOffPlane();\n//...\n```\n\nObject Oriented Programming (OOP) brings in a new thought process around this. \n\nHow about thinking in terms of the different Actors? How about storing data related to each actor right beside itself? How about giving them some responsiblity and let them do their own actions?\n\nHere's how our program would look like when we think in terms of different actors and give them data and responsibilities\n\n```java\n\n    Person\n    \tname\n    \tboardFlight(Plane flight), wishHostess (Hostess hostess), getOffFlight(Plane flight)\n\n    AirPlane\n    \taltitude, pilot, speed, flightMode\n\t\ttakeOff(), cruiseMode(), land()\n\n    Hostess\n    \twelcome()\n```\n\nDo not worry about the implementation details. Focus on the difference in approaches.\n\nWe have **encapsulated** data and methods into these entities, which are now called **objects**. We have defined object boundaries, and what it can (and cannot) do. \n\nAn object has\n* **State** : Its data\n* **Behavior** : Its operations\n\nThe ```position``` of an ```Airplane``` can change over time. The operations that can be performed on an ```Airplane``` include ```takeOff()```, ```land()``` and ```cruiseMode()```. Each of these actions can change its ```position```. Therefore, an object's behavior can affects its own state.\n\nIt's now time to introduce you to some core **OOP** terms, which will make our future discussions easier.\n\n#### OOP Terminology \n\nLet's visit and enhance  the ```Planet``` example we had written a few sections ago. This time, let's also explore the conceptual angle.\n\n**_Planet_**\n\n```java\n\n\tclass Planet\n\t\tname, location, distanceFromSun // data / state / fields\n\t\trotate(), revolve() // actions / behavior / methods\n\n\tearth : new Planet\n\tvenus : new Planet\n\n```\n\nLet's look at some **OOP** terminology.\n\nA **class** is a template. An **object** is an instance of a class. In above example, `Planet` is a class. `earth` and `venus` are objects.\n* ```name```, ```location``` and ```distanceFromSun``` compose object state.\n* ```rotate()``` and ```revolve()``` define object's behavior.\n\n**Fields** are the elements that make up the object state. Object behavior is implemented through **Methods**.\n\nEach Planet has its own state:\n* ```name```: \"Earth\", \"Venus\"\n* ```location``` : Each has its own orbit\n* ```distanceFromSun``` : They are at unique, different distances from the sun\n\nEach has its own unique behavior:\n* ```rotate()``` : They rotate at different rates (and in fact, different directions!)\n* ```revolve()``` : They revolve round the sun in different orbits, at different speeds\n\n#### Summary\n\nIn this step, we:\n\n* Understood how OOP is different from Prodedural Programming\n* Learned about a few basic OOP terms\n\n### Step 02: Programming Exercise PE-01\n\n#### Exercises\n\nIn each of the following systems, identify the basic entities involved, and organize them using object oriented terminology:\n\n1. Online Shopping System\n2. Person\n\n#### Solution-1: Online Shopping System\n\t\n```java\n\n\tCustomer\n\t\tname, address\n\t\tlogin(), logout(), selectProduct(Product)\n\n```\n\n```java\n\n\tShoppingCart\n\t\titems\n\t\taddItem(), removeItem()\n\n```\n\n```java\n\n\tProduct\n\t\tname, price, quantityAvailable\n\t\torder(), changePrice()\n\n```\n\n#### Solution-2: Person\n\n```java\n\n\tPerson\n\t\tname, address, hobbies, work\n\t\twalk(), run(), sleep(), eat(), drink()\n\n```\n\n### Step 03: Creating ```MotorBike``` ```class``` \n\nIn this series of examples, we want to model your pet mode of transport, a motorbike. We want to create motorbike objects and play around with them.\n\nWe will start with two java files: \n* **_MotorBike.java_**, which contains the ```MotorBike``` ```class``` definition. This ```class``` will encapsulate our motorbike state and behavior \n* **_MotorBikeRunner.java_**, with ```class MotorBikeRunner``` holding a ```main``` method, our program's entry point\n\n##### Snippet-1: MotorBike Class\n\n**_MotorBike.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\t\tpublic class MotorBike {\n\t\t//behavior\n\t\tvoid start() {\n\t\t\tSystem.out.println(\"Bike started!\");\n\t\t}\n}\n\n```\n\n**_MotorBikeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBikeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMotorBike ducati = new MotorBike();\n\t\t\tMotorBike honda = new MotorBike();\n\t\t\tducati.start();\n\t\t\thonda.start();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Bike started!_\n\n_Bike started!_\n\n##### Snippet-1 Explained\n\nWe started off creating a simple `MotorBike` class with a `start` method. We created a couple of instances and invoked the `start` method on them.\n\nWe created two classes because we believe in `Seperation of Concerns`: \n- `MotorBike` class is responsible for all its data and behavior.\n- `MotorBikeRunner` class is responsible for running MotorBike examples.\n\n#### Summary\n\nIn this step, we:\n\n* Defined a ```MotorBike``` ```class``` allowing us to further explore *OOP* concepts in the next steps\n\n### Step 04:  Programming Exercise OO-PE-02\n\n#### Exercises\n\n1. Write a small Java program to create a ```Book``` ```class```, and then create instances to represent the following book titles:\n\t* \"The Art Of Computer Programming\"\n\t* \"Effective Java\"\n\t* \"Clean Code\"\n\n#### Solution\n\n**_Book.java_**\n\n```java\n\n\tpublic class Book {\n\t\tprivate String title;\n\n\t\tpublic void setTitle(String bookTitle) {\n\t\t\ttitle = bookTitle;\n\t\t}\n\n\t\tpublic String getTitle() {\n\t\t\treturn title;\n\t\t}\n\t}\n\n```\n\n**_BookRunner.java_**\n\n```java\n\n\tpublic class BookRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tBook taocp = new Book();\n\t\t\ttaocp.setTitle(\"The Art Of Computer Programming\");\n\t\t\tBook ej = new Book();\n\t\t\tej.setTitle(\"Effective Java\");\n\t\t\tBook cc = new Book();\n\t\t\tcc.setTitle(\"Clean Code\");\n\t\t\tSystem.out.println(taocp.getTitle());\n\t\t\tSystem.out.println(ej.getTitle());\n\t\t\tSystem.out.println(cc.getTitle());\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_The Art Of Computer Programming_\n\n_Effective Java_\n\t\n_Clean Code_\n\n### Step 05: ```MotorBike``` -  Representing State\n\nAn object encapsulates both *state* and *behavior*. \n\n*State* defines \"the condition of the object at a given time\". *State* is represented by **member variables**. \n\nIn the ```MotorBike``` example, if we need a ```speed``` attribute for each ```MotorBike```, here is how we would include it.\n\n##### Snippet-1 : MotorBike with state variable speed\n\n**_MotorBike.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBike {\n\t\tint speed;\n\t\tvoid start() {\n\t\t\tSystem.out.println(\"Bike started!\");\n\t\t}\n\t}\n\t\n\n```\n\n**_MotorBikeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBikeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMotorBike ducati = new MotorBike();\n\t\t\tMotorBike honda = new MotorBike();\n\t\t\tducati.start();\n\t\t\thonda.start();\n\n\t\t\tducati.speed = 100;\n\t\t\thonda.speed = 80;\n\t\t\tducati.speed = 20;\n\t\t\thonda.speed = 0;\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Bike started!_\n\n_Bike started!_\n\n##### Snippet-4 Explained\n\n```int speed;``` within ```MotorBike```, defines a member variable. \n\nIt can be accessed within objects such as ```ducati``` and ```honda```, by qualifying it with the object name (```ducati``` or ```honda```).\n\n```\nducati.speed = 100;\nhonda.speed = 80;\n\n```\n\n```ducati``` has its own value for ```speed```, and so does ```honda```. These values are independent of each other. Changing one does not affect the other.\n\n#### Classroom Exercise CE-OO-01\n\n1. Update the ```Book``` ```class``` created previously to include a member variable named ```noOfCopies```, and demonstrate how it can be set and updated independently for each of the three titles specified earlier.\n\n#### Solution\n\nTODO\n\n### Step 07: ```MotorBike``` - get() and set() methods\n\nIn the previous step. we were merrily modifying the ```speed``` attribute within the ```ducati``` and ```honda``` objects directly, from within the ```main()``` program. \n\n```java\n\tpublic class MotorBikeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\t//... Other code\n\t\t\tducati.speed = 100;\n\t\t\thonda.speed = 0;\n\t\t}\n\t}\n```\n\nThis did work fine, but it breaks the fundamental principle of encapsulation in **OOP**. \n\n*\"A method of one object, should not be allowed to directly access the state of another object. To do so, such an object should only be allowed to invoke methods on the target object*\".\n\nIn other words, a member variable should not be directly accessible from methods declared outside its ```class```.\n\n##### Snippet-3 : MotorBike class with private attributes\n\n**_MotorBike.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\t\n\tpublic class MotorBike {\n\t\tprivate int speed;\n\t\t\n\t\tvoid start() {\n\t\t\tSystem.out.println(\"Bike started!\");\n\t\t}\n\n\t\tvoid setSpeed(int speed) {\n\t\t\tthis.speed = speed;\n\t\t}\n\t}\n\n```\n\n**_MotorBikeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBikeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMotorBike ducati = new MotorBike();\n\t\t\tMotorBike honda = new MotorBike();\n\t\t\tducati.start();\n\t\t\thonda.start();\n\t\t\n\t\t\tducati.setSpeed(100);\n\t\t\thonda.setSpeed(80);\n\t\n\t\t\tducati.setSpeed(20);\n\t\t\thonda.setSpeed(0);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Bike started!_\n\n_Bike started!_\n\n##### Snippet-3 Explained\n\nBy declaring ```speed``` as ```private```, we provide ```MotorBike``` with something called **access control**. Java keywords such as ```public``` and ```private``` are called **access modifiers**. They control what external objects can access within a given object.\n\nLet's look at ```this.speed = speed;``` in the body of method ```setSpeed()```:\n*  An member variable always belongs to a specific instance of that ```class```.\n*  A method argument behaves just like a local variable inside that method.\n*  To differentiate between the two,  ```this``` is used. The expression ```this.speed``` refers to the member variable ```speed``` of a ```Motorbike``` object. ```setSpeed()``` would be invoked on that very object.  \n\nCode written earlier within ```MotorBikeRunner```, such as ```ducati.speed = 100;``` would now result in errors! The correct way to access and modify ```speed``` is to invoke appropriate methods such as  ```setSpeed()```, on ```MotorBike``` objects.\n\n#### Classroom Exercise CE-OO-02\n\n1. Update the ```class``` ```Book``` to make sure it no longer breaks Encapsulation principles.\n\n#### Solution\n\nTODO\n\n#### Summary\n\nIn this step, we:\n* Learned about the need for access control to implement encapsulation\n* Observed that Java provides access modifiers (such as ```public``` and ```private```) for such control \n* Understood the need for ```get()``` and ```set()``` methods to access object data\n\n- - - \n### Step 08: Accessing Object State\n\nEncapsulation is needed to protect an object's state from direct access by other objects. We were able to protect the state of ```MotorBike``` objects by declaring ```speed``` to be ```private```. We have created a sort of rigid situation here, since the ```private``` declaration of ```speed``` forbids even a *get* access. How do we address this issue? Again, the answer is to provide a method for reading the current ```speed```.\n\n##### Snippet-4 : ```getSpeed()``` of ```MotorBike```\n\n**_MotorBike.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBike {\n\t\t//Same as before\n\n\t\tint getSpeed() {\n\t\t\treturn this.speed;\n\t\t}\n\t}\n\n```\n\n**_MotorBikeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBikeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMotorBike ducati = new MotorBike();\n\t\t\tMotorBike honda = new MotorBike();\n\t\t\tducati.start();\n\t\t\thonda.start();\n\n\t\t\tducati.setSpeed(100);\n\t\t\thonda.setSpeed(80);\n\t\t\tSystem.out.printf(\"Current Ducati Speed is : %d\", ducati.getSpeed()).println();\n\t\t\tSystem.out.printf(\"Current Honda Speed is : %d\", honda.getSpeed()).println();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Bike started!_\n\n_Bike started!_\n\n_Current Ducati Speed is : 100_\n\n_Current Honda Speed is : 80_\n\n##### Snippet-4 Explained\n\nDefining a method such as ```getSpeed()``` allows us to access the current```speed``` of a ```MotorBike``` object.\n\n```\n\t\tint getSpeed() {\n\t\t\treturn this.speed;\n\t\t}\n```\n\n\n\u003e Eclipse has a very handy feature. When the state elements (member variables) of a class have been defined, it can generate default get() and set() methods for each of them. You would want to use this regularly, to save on time and typing effort. `Right click on class \u003e Generate Source \u003e Generate Getters and Setters`\n\n#### Summary\n\nIn this step, we:\n\n* Understood how access control forces us to provide ```get()``` methods as well\n* Explored a few Eclispe tips to generate ```get()``` and ```set()``` versions for each ```class``` attribute  \n\n### Step 10: Default Object State\n\nWhat happens if a data element inside an object is not initialized with a value?\n\n##### Snippet-5 : Default Initialization of Object State\n\n**_MotorBike.java_**\n\n```java\n//Same as before\n```\n\n**_MotorBikeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBikeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMotorBike honda = new MotorBike();\t\t\t\n\t\t\tSystem.out.printf(\"Current Honda Speed is : %d\", honda.getSpeed()).println();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n**_Current Honda Speed is : 0_**\n\n##### Snippet-6 Explained\n\nWhen we instantiate an object, all its state elements are always initialized, to the default values of their types. Inside ```MotorBike```, ```speed``` is declared to be an ```int```, and so is initialized to ```0```. This happens even before any method of ```MotorBike``` is called, including ```start()```.\n\nYou can see that `honda.getSpeed()` printed `0` even though we did not explictly initialize it.\n\nDefault \n\n#### Summary\n\nIn this step, we:\n* Learnt that default values are assigned to object member variables.\n\n### Step 10: Encapsulation: Its Advantages\n\nAt the heart of encapsulation, is the need to protect object's state. From whom? Other objects. \n\nLet's look at an example to understand Encapsulation better.\n\n##### Snippet-7 : Advantage of Encapsulation\n\n**_MotorBike.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBike {\n\t\tprivate int speed;\n\n\t\tpublic void start() {\n\t\t\tSystem.out.println(\"Bike started!\");\n\t\t}\n\n\t\tpublic void setSpeed(int speed) {\n\t\t\tthis.speed = speed;\n\t\t}\n\n\t\tpublic int getSpeed() {\n\t\t\treturn this.speed;\n\t\t}\n\t}\n\n```\n\n**_MotorBikeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBikeRunner {\n\n\t\tpublic static void main(String[] args) {\n\t\t\tMotorBike ducati = new MotorBike();\n\t\t\tducati.start();\n\t\t\tducati.setSpeed(-100);\n\t\t\tSystem.out.printf(\"Current Ducati Speed is : %d\", ducati.getSpeed()).println();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Bike started!_\n\n**_Current Ducati Speed is : -100_**\n\n##### Snippet-01 Explained\n\nFor a motorbike, ```-100``` might be an invalid speed. Currently, we do not have any validation. Having a method ```setSpeed``` allows us to add validation. \n\nLet's see how to do that.\n\n##### Snippet-02 : Speed Validity Check\n\n**_MotorBike.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBike {\n\n\t\t//Other code as is\n\n\t\tpublic void setSpeed(int speed) {\n\t\t\tif(speed \u003e 0)\n\t\t\t\tthis.speed = speed;\n\t\t}\n\n\t}\n\n```\n\n**_MotorBikeRunner.java_**\n\n```java\n//Same as before\n```\n\nThe output of this snippet is:\n\n_Bike started!_\n\n**_Current Ducati Speed is : 0_**\n\n##### Snippet-8 Explained\n\n```setSpeed()``` checks `if(speed \u003e 0)` and does not update speed for negative values. \n\n\u003e This is not perfect solution because the caller of the `setSpeed` method assumes that he was successful. Ideally, we should throw an Exception indicating validation error. We will talk about Exceptions later.\n\n#### Summary\n\nIn this step, we:\n\n* Explored the first advantage of encapsulation - A provision for adding data validation\n* Highlighted how such validation can be done, using the ```Motorbike``` example\n\n### Step 11: Encapsulation - Advantages (Code Reuse)\n\nWe've understood quite a few things about encapsulation under *OOP*.\n\nSuppose at different points of time, we want to increase the speeds of both Honda and Ducati bikes by a fixed amount, say ```100 mph```. The logic would be simple, right? Fetch the current ```speed``` of each bike, increment that fetched value by ```100```, and then set the new value back into that bike's ```speed```. The following example puts the above logic into action.\n\n##### Snippet-1 : Bulky Speed Increment code \n\n**_MotorBike.java_**\n\n```java\n// No Change\n```\n\n**_MotorBikeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBikeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMotorBike ducati = new MotorBike();\n\t\t\tMotorBike honda = new MotorBike();\n\t\t\tducati.start();\t\t\n\t\t\thonda.start();\n\t\t\tducati.setSpeed(100);\n\t\t\t\n\t\t\tSystem.out.printf(\"Earlier Ducati Speed is : %d\", ducati.getSpeed()).println();\n\t\t\tSystem.out.printf(\"Earlier Honda Speed is : %d\", honda.getSpeed()).println();\n\t\t\n\t\t\tint ducatiSpeed = ducati.getSpeed();\n\t\t\tducatiSpeed = ducatiSpeed + 100;\n\t\t\tducati.setSpeed(ducatiSpeed);\n\t\t\t\n\t\t\tint hondaSpeed = honda.getSpeed();\n\t\t\thondaSpeed = hondaSpeed + 100;\n\t\t\thonda.setSpeed(hondaSpeed);\n\t\t\t\n\t\t\tSystem.out.printf(\"Later Ducati Speed is : %d\", ducati.getSpeed()).println();\n\t\t\tSystem.out.printf(\"Later Honda Speed is : %d\", honda.getSpeed()).println();\n\t\t}\n\t}\n\n```\n\nThe output of this snippet is:\n\n_Bike started!_\n\n_Bike started!_\n\n_Earlier Ducati Speed is : 100_\n\n_Earlier Honda Speed is : 0_\n\n**_Later Ducati Speed is : 200_**\n\n**_Later Honda Speed is : 100_**\n\n##### Snippet-1 Explained\n\nNotice the repeated code within ```MotorBikeRunner```? The code for updating the ```speed``` of ```ducati```, is almost the same as that for ```honda```. Remember at the start of this book, we said something like this:\n\n*\"The goal of any computer program is to make a task easier, less cumbersome and more elegant for the programmer.\"*\n\n*OOP* achieves all thus through encapsulation! The idea is to *encapsulate* repeated logic within a method, and pass object-specific information to it as arguments. The next example shows you one way of doing it.\n\n##### Snippet-2 : Speed Increase through Code Encapsulation\n\n**_MotorBike.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBike {\n\t\t//Other code same as before\n\t\tpublic void increaseSpeed(int howMuch) {\n\t\t\tthis.speed = this.speed + howMuch;\n\t\t}\n\t}\n\n```\n\n**_MotorBikeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBikeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\t\n\t\t\tMotorBike duati = new MotorBike();\n\t\t\tMotorBike honda = new MotorBike();\n\t\t\tducati.start();\n\t\t\thonda.start();\n\n\t\t\tducati.setSpeed(100);\n\n\t\t\tSystem.out.printf(\"Earlier Ducati Speed is : %d\", ducati.getSpeed()).println();\n\t\t\tSystem.out.printf(\"Earlier Honda Speed is : %d\", honda.getSpeed()).println();\n\n\t\t\tducati.increaseSpeed(100);\n\t\t\thonda.increaseSpeed(100);\n\n\t\t\tSystem.out.printf(\"Later Ducati Speed is : %d\", ducati.getSpeed()).println();\n\t\t\tSystem.out.printf(\"Later Honda Speed is : %d\", honda.getSpeed()).println();\n\t\t}\n\t}\n\n```\n\nThe output of this snippet is:\n\n_Bike started!_\n\n_Bike started!_\n\n_Earlier Ducati Speed is : 100_\n\n_Earlier Honda Speed is : 0_\n\n**_Later Ducati Speed is : 200_**\n\n**_Later Honda Speed is : 100_**\n\n##### Snippet-2 Explained\n\nThe method ```increaseSpeed()``` has been added to ```MotorBike```. It can be invoked on the ```ducati``` and ```honda``` objects.\n\nLet's now add a feature to ```MotorBike```, by which ```speed``` can be decreased.\n\n##### Snippet-3 : Speed Increase And Decrease through Code Encapsulation\n\n**_MotorBike.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBike {\n\t\t// Other methods same as before\n\t\tpublic void decreaseSpeed(int howMuch) {\n\t\t\tthis.speed = this.speed - howMuch;\n\t\t}\n\t}\n\n```\n\n**_MotorBikeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBikeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMotorBike ducati = new MotorBike();\n\t\t\tMotorBike honda = new MotorBike();\n\t\t\tducati.start();\n\t\t\thonda.start();\n\t\n\t\t\tducati.setSpeed(100);\n\t\t\tSystem.out.printf(\"Earlier Ducati Speed is : %d\", ducati.getSpeed()).println();\n\t\t\tSystem.out.printf(\"Earlier Honda Speed is : %d\", honda.getSpeed()).println();\n\n\t\t\tducati.increaseSpeed(100);\n\t\t\thonda.increaseSpeed(100);\n\t\t\tducati.decreaseSpeed(50);\n\t\t\thonda.decreaseSpeed(50);\n\n\t\t\tSystem.out.printf(\"Later Ducati Speed is : %d\", ducati.getSpeed()).println();\n\t\t\tSystem.out.printf(\"Later Honda Speed is : %d\", honda.getSpeed()).println();\n\t\t\t\n\t\t\tducati.decreaseSpeed(200);\n\t\t\thonda.decreaseSpeed(200);\n\n\t\t\tSystem.out.printf(\"Final Ducati Speed is : %d\", ducati.getSpeed()).println();\n\t\t\tSystem.out.printf(\"Final Honda Speed is : %d\", honda.getSpeed()).println();\n\t\t}\n\t}\n\n```\n\nThe output of this snippet is:\n\n_Bike started!_\n\n_Bike started!_\n\n_Earlier Ducati Speed is : 100_\n\n_Earlier Honda Speed is : 0_\n\n**_Later Ducati Speed is : 150_**\n\n**_Later Honda Speed is : 50_**\n\n**_Final Ducati Speed is : -50_**\n\n**_Final Honda Speed is : -150_**\n\n##### Snippet-3 Explained\n\nThe method ```decreaseSpeed()``` has been added to ```MotorBike```. It can be invoked on the ```ducati``` and ```honda``` objects inside the ```main()``` method of ```MotorBikeRunner```.\n\nOn of the things you can observe again is ***Negative Speed Values***. Our validation needs to be improved.\n\n##### Snippet-4 : Validation across methods, repeated!\n\n**_MotorBike.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBike {\n\n\t\t//Same as before\n\n\t\tpublic void increaseSpeed(int howMuch) {\n\t\t\tif(this.speed + howMuch \u003e 0)\n\t\t\t   this.speed = this.speed + howMuch;\n\t\t}\n\n\t\tpublic void decreaseSpeed(int howMuch) {\n\t\t\tif(this.speed - howMuch \u003e 0)\n\t\t\t   this.speed = this.speed - howMuch;\n\t\t}\n\t}\n\n```\n\n**_MotorBikeRunner.java_**\n\n```java\n\t//Same as before\n```\n\nThe output of this snippet is:\n\n_Bike started!_\n\n_Bike started!_\n\n_Earlier Ducati Speed is : 100_\n\n_Earlier Honda Speed is : 0_\n\n_Later Ducati Speed is : 150_\n\n_Later Honda Speed is : 50_\n\n**_Final Ducati Speed is : 150_**\n\n**_Final Honda Speed is : 50_**\n\n##### Snippet-4 Explained\n\nWe have achieved data validation, because attempts to decrease the ```speed``` of ```ducati``` and ```honda``` below ```0``` are now ignored. \n\nBut this has come at a cost,  which is *code bloat*.\n\nHow do we reduce duplication?\n\n##### Snippet-5: Validation by code reuse\n\n**_MotorBike.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBike {\n\t\t//Other methods same as before\n\n\n\t\tpublic void setSpeed(int speed) {\n\t\t\tif(speed \u003e 0)\n\t\t\t\tthis.speed = speed;\n\t\t}\n\n\t\tpublic void increaseSpeed(int howMuch) {\n\t\t\tsetSpeed(this.speed + howMuch);\n\t\t}\n\n\t\tpublic void decreaseSpeed(int howMuch) {\n\t\t\tsetSpeed(this.speed - howMuch);\n\t\t}\n\t}\n\n```\n\n**_MotorBikeRunner.java_**\n\n```java\n\t//Same as before\n\n```\n\nThe output of this snippet is:\n\n_Bike started!_\n\n_Bike started!_\n\n_Earlier Ducati Speed is : 100_\n\n_Earlier Honda Speed is : 0_\n\n_Later Ducati Speed is : 150_\n\n_Later Honda Speed is : 50_\n\n**_Final Ducati Speed is : 150_**\n\n**_Final Honda Speed is : 50_**\n\n##### Snippet-5 Explained\n\nThe idea behind this solution is, that an *update* is the same as a ```set()``` operation. Since ```setSpeed()``` already has a validation check, it can be called inside both ```increaseSpeed()``` and ```decreaseSpeed()``` with appropriate parameters. \n\nIn this way, the validation logic would be reused across update methods.\n\n\u003e Be always careful. Duplication of logic makes your code difficult to maintain.\n\n#### Summary\n\nIn this step, we:\n\n* Started exploring the next advantage of encapsulation - code reuse\n* Mapped this understanding to the ```MotorBike``` example, building on data validation  \n\n### Step 12: Programming Exercise PE-OO-03\n\n#### Exercises\n\n1. Use an encapsulation technique to write methods for the ```Book``` ```class```, that\n\t* Increase the number of books\n\t* Decrease the number of books\n\n#### Solution\n\n**_BookRunner.java_**\n\n```java\n\n\tpublic class BookRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tBook taocp = new Book();\n\t\t\ttaocp.setTitle(\"The Art Of Computer Programming\");\n\t\t\tBook ej = new Book();\n\t\t\tej.setTitle(\"Effective Java\");\n\t\t\tBook cc = new Book();\n\t\t\tcc.setTitle(\"Clean Code\");\n\t\t\t\n\t\t\tSystem.out.println(taocp.getTitle());\n\t\t\tSystem.out.println(ej.getTitle());\n\t\t\tSystem.out.println(cc.getTitle());\n\n\t\t\ttaocp.increaseCopies(10);\n\t\t\tej.increaseCopies(15);\n\t\t\tcc.increaseCopies(20);\n\t\t\ttaocp.decreaseCopies(5);\n\t\t\tej.decreaseCopies(10);\n\t\t\tcc.decreaseCopies(15);\n\n\t\t\tSystem.out.println(taocp.getNumberOfCopies());\n\t\t\tSystem.out.println(ej.getNumberOfCopies());\n\t\t\tSystem.out.println(cc.getNumberOfCopies());\n\t\t}\n\t}\n\n```\n\n**_Book.java_**\n\n```java\n\n\tpublic class Book {\n\t\tprivate String title;\n\t\tprivate int numberOfCopies;\n\n\t\tpublic void setTitle(String bookTitle) {\n\t\t\ttitle = bookTitle;\n\t\t}\n\n\t\tpublic String getTitle() {\n\t\t\treturn title;\n\t\t}\n\n\t\tpublic void setNumberOfCopies(int numberOfCopies) {\t\n\t\t\tif(numberOfCopies \u003e 0) {\n\t\t\t\tthis.numberOfCopies = numberOfCopies;\n\t\t\t}\n\t\t}\n\n\t\tpublic int getNumberOfCopies() {\n\t\t\treturn numberOfCopies;\n\t\t}\n\n\t\tpublic void increaseCopies(int howMuch) {\n\t\t\tsetNumberOfCopies(numberOfCopies + howMuch);\n\t\t}\n\n\t\tpublic void decreaseCopies(int howMuch) {\n\t\t\tsetNumberOfCopies(numberOfCopies - howMuch);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_The Art Of Computer Programming_\n\n_Effective Java_\n\t\n_Clean Code_\n\n_5_\n\n_5_\n\n_5_\n\n### Step 13: Introducing Constructors   \n\nWhen we create Ducati and Honda motorbikes, we may want to configure them with some start speeds. \n\nSuppose our whim is that a Ducati bike starts with 100 mph, and a Honda with 200 mph. \n\n\n##### Snippet-1: MotorBike Constructor\n\n**_MotorBike.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBike {\n\t\tprivate int speed;\n\n\t\t\n\t\tMotorBike(int speed) {\n\t\t\tif(speed \u003e 0)\n\t\t\t\tthis.speed = speed;\n\t\t}\n\n\t\t//Same as before\n\n\t}\n\n```\n\n**_MotorBikeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBikeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMotorBike ducati = new MotorBike(100);\n\t\t\tMotorBike honda = new MotorBike(200);\n\t\t\tducati.start();\n\t\t\thonda.start();\n\t\t\tSystem.out.printf(\"Earlier Ducati Speed is : %d\", ducati.getSpeed()).println();\n\t\t\tSystem.out.printf(\"Earlier Honda Speed is : %d\", honda.getSpeed()).println();\n\t\t}\n\t}\n\n```\n\nThe output of this snippet is:\n\n_Bike started!_\n\n_Bike started!_\n\n_Earlier Ducati Speed is : 100_\n\n_Earlier Honda Speed is : 200_\n\n##### Snippet-1 Explained\n\nWe defined a single-argument constructor for ```MotorBike```, whosw definition looks like this:\n\n```public MotorBike(int speed){ /* Constructor Code Goes Here  */ }```\n\nThe constructor is a method, whose name is the same as the ```class``` name. All Java rules for a method apply to constructors as well. Constructor cannot be directly called. \n\nA constructor is always invoked when a ```class``` object is created, using the ```new``` keyword. A constructor for a ```class``` could accept zero, one or more than one arguments. Let's next write some full-blooded code for a ```MotorBike``` constructor.\n\n\n#### Summary\n\nIn this step, we were introduced to the concept of a ```class``` constructor\n\n### Programming Exercise PE-OO-04, And More On Constructors\n\n#### Exercises\n\n1. Rewrite the ```Book``` ```class``` solution by using a constructor, which accepts an integer argument specifying the initial number of copies to be published:\n\t* \"The Art Of Computer Programming\" : 100 copies\n\t* \"Effective Java\" : 75 copies\n\t* \"Clean Code\" : 60 copies\n\n#### Solution To PE-OO-04\n\n**_BookRunner.java_**\n\n```java\n\n\tpublic class BookRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tBook taocp = new Book(100);\n\t\t\ttaocp.setTitle(\"The Art Of Computer Programming\");\n\t\t\t\n\t\t\tBook ej = new Book(75);\n\t\t\tej.setTitle(\"Effective Java\");\n\t\t\t\n\t\t\tBook cc = new Book(60);\n\t\t\tcc.setTitle(\"Clean Code\");\n\n\t\t\tSystem.out.println(taocp.getTitle());\n\t\t\tSystem.out.println(taocp.getNumberOfCopies());\n\n\t\t\tSystem.out.println(ej.getTitle());`\n\t\t\tSystem.out.println(ej.getNumberOfCopies());\n\n\t\t\tSystem.out.println(cc.getTitle());\n\t\t\tSystem.out.println(cc.getNumberOfCopies());\n\t\t}\n\t}\n\n```\n\n**_Book.java_**\n\n```java\n\n\tpublic class Book {\n\t\tprivate String title;\n\t\tprivate int numberOfCopies;\n\t\t\n\t\tpublic Book(int numberOfCopies) {\n\t\t\tthis.numberOfCopies = numberOfCopies;\n\t\t}\n\n\t\tpublic void setTitle(String bookTitle) {\n\t\t\ttitle = bookTitle;\n\t\t}\n\n\t\tpublic String getTitle() {\n\t\t\treturn title;\n\t\t}\n\n\t\tpublic int getNumberOfCopies() {\n\t\t\treturn numberOfCopies;\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_The Art Of Computer Programming_\n\n_100_\n\n_Effective Java_\n\n_75_\n\t\n_Clean Code_\n\n_60_\n\n#### More on Constructors\n\nWe enjoyed defining the ```MotorBike``` ```class``` and checking out the behavior of its instances, ```ducati``` and ```honda```. \n\nWhen we started off , we created instances of `MotorBike` classes using:\n\n```MotorBike ducati = new MotorBike();```\n\nDid you notice something familiar? Doesn't the expression ```new MotorBike()``` look like a constructor call? \n\nAs it turns out, it is a constructor call on ```MotorBike```! \n\nWhen we define a ```class``` in Java (even a seemingly empty one), some behind-the-scene magic happens. Consider one such ```class``` ```Cart```:\n\n```java\n\n\tclass Cart {\n\n\t};\n\n```\n\nThis ```class``` has neither state, nor behavior. When we try to create instances of this \"empty\" ```class```:\n\n```java\n\n\tclass CartRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tCart cart = new Cart();\n\t\t}\n\t}\n\n```\n\nThe code seems to compile, execute and get initialized quite smoothly! What happens is, that the compiler silently generates a **default constructor** for ```Cart```. \n\nA default constructor is one that accepts no arguments. It is as if the ```Cart``` ```class``` were defined this way:\n\n```java\n\n\tclass Cart {\n\t\tpublic Cart() {\n\t\t}\n\t};\n\n```\n\nA constructor may also have overloaded definitions. \n\nLet's now try to create ```MotorBike``` instances with default initialization, just as we did with ```Cart```.\n\n##### Snippet-2 : Default Motorbike Construction?\n\n**_MotorBike.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBike {\n\n\t\tprivate int speed;\n\n\t\tMotorBike(int speed) {\n\t\t\tif(speed \u003e 0)\n\t\t\t\tthis.speed = speed;\n\t\t}\n\t}\n\n```\n\n**_MotorBikeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBikeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMotorBike ducati = new MotorBike(100);\n\t\t\tMotorBike honda = new MotorBike(200);\n\t\t\tMotorBike yamaha = new MotorBike();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n**_Compiler Error_**\n\n##### Snippet-2 Explained\n\nThe compiler flags an error with **_MotorBikeRunner.java_**! `MotorBike yamaha = new MotorBike();` is failing compilation. Why?\n\nNo default constructor is generated here! If you provide any constructor definition in a class, the compiler will not add a default constructor. **Do them all yourself, if you don’t like what I do for you!** is what it yells back.\n\nIf you need the default constructor, you can explicitly add it.\n\n##### Snippet-3 : Programmer-defined default constructor\n\n**_MotorBike.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBike {\n\t\t//state\n\t\tprivate int speed;\n\n\t\t//behavior\n\t\tMotorBike() {\n\t\t\tthis(5);\n\t\t}\n\n\t\tMotorBike(int speed) {\n\t\t\tif(speed \u003e 0)\n\t\t\t\tthis.speed = speed;\n\t\t}\n\n\t}\n\n```\n\n**_MotorBikeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBikeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMotorBike ducati = new MotorBike(100);\n\t\t\tMotorBike honda = new MotorBike(200);\n\t\t\tMotorBike yamaha = new MotorBike();\n\t\t\tSystem.out.printf(\"Earlier Yamaha Speed is : %d\", yamaha.getSpeed()).println();\n\t\t}\n\t}\n\n```\n\nThe output of this snippet is:\n\n**_Earlier Yamaha Speed is : 5_**\n\n##### Snippet-3 Explained\n\nWe defined a zero-argument constructor ```MotorBike()```, to enable default object initialization. But what are we doing in its body with the statement ```this(5);```? \n\nWe have called the constructor ```MotorBike(int)```, qualified with the ```this``` keyword, within ```Motorbike()```. \n\n## Primitive Data Types\n\nEarlier, we looked at basic Java types (including ```int```, ```double``` and ```boolean```), and got a little familiar with them.\n\nWe used literal values, declared variables and formed expressions using them. \n\nJava **primitive types** include:\n* Integer Types\n\t* ```byte```\n\t* ```short```\n\t* ```int```\n\t* ```long```\n* Floating-Point Types\n\t* ```float```\n\t* ```double```\n* Character Type\n\t* ```char```\n* Logical Type\n\t* ```boolean```\n\nIn this section, let's play with each of these types to understand them further.\n\n### Step 01: The Integer Types\n\nIntegers are not much of a mystery, are they? They've been part of us since our school days, and we normally prefer them over other numbers (they scare us less!). \n\nJava supports them with ease, and we have coded quite a few examples using them, already. \n\nJava also has a **wrapper class** corresponding to each of them, which make their primitive versions more versatile. The wrapper classes we are talking about are:\n\n* ```Byte```: for ```byte```\n* ```Short```: matching ```short```\n* ```Integer``` corresponding to ```int```\n* ```Long```: about ```long```\n\nLet's see how we can work with them.\n\n##### Snippet-01 : Integer Sizes\n\nLook at all the information these tiny classes hold for you! As they say, **_\"fore-warned is fore-armed\"_**. Depending on the data (range and size) your program handles, you decide which types to use, to store them.\n\n```java\n\n\tjshell\u003e Byte.SIZE\n\t$1 ==\u003e 8\n\tjshell\u003e Byte.BYTES\n\t$2 ==\u003e 1\n\tjshell\u003e Byte.MAX_VALUE\n\t$3 ==\u003e 127\n\tjshell\u003e Byte.MIN_VALUE\n\t$4 ==\u003e -128\n\tjshell\u003e Short.BYTES\n\t$5 ==\u003e 2\n\tjshell\u003e Integer.BYTES\n\t$6 ==\u003e 4\n\tjshell\u003e Long.BYTES\n\t$7 ==\u003e 8\n\tjshell\u003e Short.MAX_VALUE\n\t$8 ==\u003e 32767\n\tjshell\u003e Integer.MAX_VALUE\n\t$8 ==\u003e 2147483647\n\tjshell\u003e int i = 100000;\n\ti ==\u003e 100000\n\tjshell\u003e long l = 50000000000;\n\t| Error:\n\t| integer number too large: 50000000000\n\t| long l = 50000000000;\n\t|_________^\n\tjshell\u003e long l = 50000000000l;\n\tl ==\u003e 50000000000\n\tjshell\u003e\n\n```\n\n#### Integer Type Conversions\n\nProblems will (and should) arise if we attempt to store large data into smaller bins. The compiler warns the programmer about such issues by flagging errors. However, if the programmer is aware of the risks and intends to go ahead, **explicit casts** are her tools to push the code through.\n\nOperations in the other direction (storing a smaller data value in a larger bin), is a piece of cake for the compiler. Such a conversion is called an **implicit cast**.\n\n##### Snippet-02 : Integer Type Conversions \n\nAttempting to store a ```long``` value into an ```int``` variable will give us a compiler error. However, you can use an explicit cast, such as ```i = (int) l;```.\n\n```java\n\n\tjshell\u003e int i = 100000;\n\ti ==\u003e 100000\n\tjshell\u003e long l = 50000000000l;\n\tl ==\u003e 50000000000\n\tjshell\u003e i = l;\n\t| Error :\n\t| incompatible types: possible lossy conversion from long to int\n\t| i = l;\n\t|_____^\n\tjshell\u003e i = (int) l;\n\ti ==\u003e -1539607552\n\tjshell\u003e l = i;\n\tl ==\u003e -1539607552\n\tjshell\u003e\n\t\n```\n\n**_The compiler is not responsible for the type-safety of this statement. The onus is on me, the programmer._**\n\nRemember our earlier statement on possible incorrect program behavior? As you can see, a different value got stored in ```i```.\n\n#### Summary\n\nIn this step, we:\n\n* Explored the wrapper classes present for the primitive integer types\n* Understood the different capacities and data ranges of these types\n* Examined how to use explicit and implicit casts\n\n### Step 02: Integer Representations, And Other Puzzles\n\nIn a decimal system, the allowed digits are ```0``` through ```9```. When a value of ```10``` is encountered, the number of digits increases by 1, and its representation is \"```10```\".\n\nThose familiar with number systems would know that decimal is not the only system that computers understand. \n\nOther number systems that the Java language supports are **Octal** (Base-8) and **Hexadecimal** (Base-16). \n\nIn an Octal system, the allowed digits are ```0``` through ```7```, and a value ```8``` is represented by \"```010```\". The leading ```0``` is added only to distinguish the octal format from the decimal one. \n\nIn a Hexadecimal system, the allowed digits are ```0``` through ```9```, followed by ```a``` through ```f``` (or ```A``` through ```F```). A value of ```16``` is represented by \"```0x10```\". Here, a leading ```0x``` is added to help the compiler recognize Hexa decimal representation.\n\nLet's see how Java supports these three number systems.\n\n##### Snippet-01 : Storing Octal and Hexadecimal in Integer types\n\nThere are no number-system specific integer types in Java! The same ```int``` type is used to store decimal, octal and hexadecimal values. \n\nIf we adhere to to number system conventions about valid digits and understand the compiler hints, we get no surprises.\n\n```java\n\n\tjshell\u003e int eight = 010;\n\teight ==\u003e 8\n\tjshell\u003e int sixteen = 0x10;\n\tsixteen ==\u003e 16\n\tjshell\u003e int fifteen = 0xf;\n\tfifteen ==\u003e 15\n\tjshell\u003e int eight = 08;//8 is invalid octal digit\n\t| Error:\n\t| integer number too large : 08\n\t| int eight = 08;\n\t|___________^\n\tjshell\u003e int big = 0xbbaacc;\n\tbig ==\u003e 12298956\n\tjshell\u003e\n\n```\n\n##### Snippet-02 : More Integer Type-casting\n\nThere are two kinds of assignments:\n* Literal-to-variable assignment: With ```short s = 123456;```, the data is clearly out of range (this is known at compile-time). The compiler flags an error.\n* Variable-to-variable assignment:  Consider ```sh = in;```. The value stored in ```int in``` at that stage was ```4567```, which is well within the range of the ```short``` type. The compiler chooses not to take chances and flags an error. This can again be preempted with a explicit cast `sh = (short) in`.\n\n\n```java\n\n\tjshell\u003e byte b = 128;\n\t| Error:\n\t| incompatible types: possible lossy conversion from int to byte\n\t| byte b = 128;\n\t|_________^--^\n\tjshell\u003e short s = 123456;\n\t| Error:\n\t| incompatible types: possible lossy conversion from int to short\n\t| short s = 123456;\n\t|__________^-------^\n\tjshell\u003e short sh = 3456;\n\tsh ==\u003e 3456\n\tjshell\u003e int in = 4567;\n\tin ==\u003e 3456\n\tjshell\u003e sh = in;\n\t| Error:\n\t| incompatible types: possible lossy conversion from int to short\n\t| sh = in;\n\t|______^\n\tjshell\u003e sh = (short) in;\n\tsh ==\u003e 4567\n\tjshell\u003e int num = sh;\n\tnum ==\u003e 4567\n\tjshell\u003e\n\n```\n\n#### Built-In Operators For Integer Types\n\nWe already had a glimpse of arithmetic operators for the integer types:\n* ```+```\n* ```-```\n* ```*```\n* ```/```\n* ```%```\n* ```++``` (both prefix and post-fix increment)\n* ```--``` (both prefix and post-fix increment)\n\nThe increment and decrement operators are an interesting case, as they are actually short-hands for multiple statements. When we use their prefix and post-fix versions, we need to look out for side-effects.\n\n##### Snippet-03 : Increment \u0026 Decrement Operators\n\nWith post-fix increment, such as in ```int j = i++;```, the increment takes place *after* the assignment is done. ```j``` gets the value before increment.\n```java\n\n\tjshell\u003e int i = 10;\n\ti ==\u003e 10\n\tjshell\u003e int j = i++;\n\tj ==\u003e 10\n\tjshell\u003e i\n\ti ==\u003e 11\n```\n\nWhen prefix increment is involved, as with ```int n = ++m;```, the increment is carried out *before* the assignment. ```n``` gets the value after increment.\n\n```java\n\tjshell\u003e int m = 10;\n\tm ==\u003e 10\n\tjshell\u003e int n = ++m;\n\tn ==\u003e 11\n\tjshell\u003e m\n\tm ==\u003e 11\n```\n\nWith post-fix decrement, as with ```int l = k--;```, the decrement occurs *after* the assignment is done. As far as prefix decrement is concerned, such as in ```int q = --p;```, the decrement is performed *before* the assignment.\n\n```java\n\tjshell\u003e int k = 10;\n\tk ==\u003e 10\n\tjshell\u003e int l = k--;\n\tl ==\u003e 10\n\tjshell\u003e k\n\tk ==\u003e 9\n\tjshell\u003e int p = 10;\n\tp ==\u003e 10\n\tjshell\u003e int q = --p;\n\tq ==\u003e 9\n\tjshell\u003e p\n\tp ==\u003e 9\n\tjshell\u003e\n\n```\n\n#### Summary:\n\nIn this step, we:\n\n* Looked at the number-systems supported in Java for integers\n* Examined how prefix and post-fix versions work for increment and decrement operators\n\n- - -\t\n### Step 03: Classroom Exercise CE-01 (With Solutions)\n\n#### Exercise Set\n\n1. Create a Java ```class``` ```BiNumber``` that stores a pair of integers, and has the following functionality:\n\n\t* Can be created by passing its initial two numbers to store\n\t* Must Support Addition and Multiplication operations on the stored integers\n\t* An operation to double the values of both numbers\n\t* Operations to access each number individually\n\t\nIn short, we must be able to write code like this in the ```main``` method of  our runner class:\n\n```java\n\n\tBiNumber numbers = new BiNumber(2, 3);\n\tSystem.out.println(numbers.add());\n\tSystem.out.println(numbers.multiply());\n\tnumbers.double();\n\tSystem.out.println(numbers.getNumber1());\n\tSystem.out.println(numbers.getNumber2());\n\n```\n\n#### Solution to CE-01\n\n**_BiNumber.java_**\n\n```java\n\n\tpackage com.in28minutes.primitive.datatypes;\n\t\n\tpublic class BiNumber {\n\t\tprivate int number1;\n\t\tprivate int number2;\n\n\t\tpublic BiNumber(int number1, int number2) {\n\t\t\tthis.number1 = number1;\n\t\t\tthis.number2 = number2;\n\t\t}\n\n\t\tpublic int add() {\n\t\t\treturn number1 + number2;\n\t\t}\n\n\t\tpublic int multiply() {\n\t\t\treturn number1 * number2;\n\t\t}\n\n\t\tpublic void doubleValue() {\n\t\t\tnumber1 *= 2;\n\t\t\tnumber2 *= 2;\n\t\t}\n\n\t\tpublic int getNumber1() {`\n\t\t\treturn number1;\n\t\t}\n\n\t\tpublic int getNumber2() {\n\t\t\treturn number2;\n\t\t}\n\n\t\tpublic void setNumber1(int number1) {\n\t\t\tthis.number1 = number1;\n\t\t}\n\n\t\tpublic void setNumber2(int number2) {\n\t\t\tthis.number2 = number2;\n\t\t}\n\t}\n\n```\n\n**_BiNumberRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.primitive.datatypes;\n\n\tpublic class BiNumberRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tBiNumber numbers = new BiNumber(2, 3);\n\t\t\tSystem.out.println(numbers.add());\n\t\t\tSystem.out.println(numbers.multiply());\n\t\t\tnumbers.doubleValue();\n\t\t\tSystem.out.println(numbers.getNumber1());\n\t\t\tSystem.out.println(numbers.getNumber2());\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_5_\n\n_6_\n\n_4_\n\n_6_\n\n### Step 05: Floating-Point Types\n\nYou would recall there are two types in Java to support floating-point numbers:\n* ```double```: The default type for floating-point literals, with a capacity of 8 bytes\n* ```float```: A narrower, less precise representation for floating-point data. It has a capacity of 4 bytes.\n\nLet's quickly refresh what we know, with a few code snippets.\n\n##### Snippet-01 : double and float\n\nDefault floating point type in Java is `double`. A ```float``` literal must be accompanied with a trailing ```f``` or ```F```.\n\n\n```java\n\n\tjshell\u003e float f = 34.5;\n\t| Error:\n\t| incomaptible types: possible lossy conversion from double to float\n\t| float f = 34.5;\n\t|_________^---^\n\tjshell\u003e float f = 34.5f;\n\tf ==\u003e 34.5\n\tjshell\u003e float fl = 34.5F;\n\tfl ==\u003e 34.5\n\tjshell\u003e double d = 34.5678;\n\td ==\u003e 34.5678\n\tjshell\u003e float flo = d;\n\t| Error:\n\t| incomaptible types: possible lossy conversion from double to float\n\t| float flo = d;\n\t|__________^\n\tjshell\u003e float flo = (float) d;\n\tflo ==\u003e 34.567\n\tjshell\u003e\n\n```\n\n##### Snippet-02 : Operators for type double\n\nYou can use operators `++`, `--` and `%` on double. \n\n```java\n\njshell\u003e double dbl = 34.5678;\ndbl ==\u003e 34.5678\n\njshell\u003e dbl++\n$3 ==\u003e 34.5678\n\njshell\u003e dbl\ndbl ==\u003e 35.5678\n\njshell\u003e dbl--\ndbl ==\u003e 35.5678\njshell\u003e dbl % 5\ndbl ==\u003e 4.567799999999998\n```\n\nYou would need an explicit cast to convert a float to an integer value `int i = (int)f`.\n\n```java\n\tjshell\u003e float f = 34.5678f;\n\tf ==\u003e 34.5678\n\tjshell\u003e int i = f;\n\t| Error:\n\t| incomaptible types: possible lossy conversion from float to int\n\t| int i = f;\n\t|_______^\n\tjshell\u003e int i = (int)f;\n\ti ==\u003e 34\n\tjshell\u003e float fl = i;\n\tfl ==\u003e 34.0\n\tjshell\u003e\n\n```\n#### Summary\n\nIn this step, we:\n\n* Saw how we create literals and variables of the floating-point types\n* Understood the differences between ```double``` and ```float```\n\n### Step 06: Introducing BigDecimal\n\nCompact though they are, ```double``` and ```float``` are not very precise representations of floating-point numbers. \n\nIn fact, they are not used in computations that require high degrees for accuracy, such as scientific experiments and financial applications. The next example shows you why.\n\n\n```java\n\n\tjshell\u003e 34.56789876 + 34.2234\n\t$1 ==\u003e 68.79129875999999\n```\n\nThe literal expression ```34.56789876 + 34.2234``` should evaluate to ```68.79129876```. Above addition is not really accurate.\n\nThis is due to a flaw in floating-point representations, used in the ```double``` and ```float``` types.\n\nThe ```BigDecimal``` class was introduced in Java to tide over these problems.\n\nAccuracy of ```BigDecimal``` representation is retained only when ```String``` literals are used to build it.\n\n\n\n```java\n\n\tjshell\u003e BigDecimal number1 = new BigDecimal(\"34.56789876\");\n\tnumber1 ==\u003e 34.56789876\n\tjshell\u003e BigDecimal number2 = new BigDecimal(\"34.2234\");\n\tnumber2 ==\u003e 34.2234_\n```\n\nA ```BigDecimal``` type can be used to create only **immutable** objects. The values in an *immutable* object cannot be changed after creation. \n\nYou can see that the value of number1 is not changed on executing `number1.add(number2)`. To get the result of the sum, we create a new variable `sum`.\n\n```java\n\tjshell\u003e number1.add(number2);\n\t$2 ==\u003e 68.79129876\n\tjshell\u003e number1\n\tnumber1 ==\u003e 34.56789876\n\tjshell\u003e BigDecimal sum = number1.add(number2);\n\tsum ==\u003e 68.79129876\n```\n\n#### Summary\n\nIn this step, we:\n\n* Learned that ```double``` and ```float``` are not very precise data types\n* Were introduced to the ```BigDecimal``` built-in data type\n* Understood that ```BigDecimal``` is immutable\n* Saw that accuracy is best achieved when you construct ```BigDecimal``` data using string literals \n\n### Step 06: BigDecimal Operations\n\nLet's look at a few other operations defined in the ```BigDecimal``` class.\n\n##### Snippet-01: Arithmetic Operations\n\nAll BigDecimal operations support only BigDecimal operands.\n\n```java\n\n\tjshell\u003e BigDecimal number1 = new BigDecimal(\"11.5\");\n\tnumber1 ==\u003e 34.56789876\n\tjshell\u003e BigDecimal number2 = new BigDecimal(\"23.45678\");\n\tnumber2 ==\u003e 23.45678\n\tjshell\u003e number1.add(number2);\n\t$1 ==\u003e 34.95678\n```\n\n```BigDecimal``` does not jell well with primitive types.\n\n```java\n\tjshell\u003e int i = 5;\n\ti ==\u003e 5\n\tjshell\u003e number1.add(i);\n\t| Error:\n\t| incompatible types: int cannot be converted to java.math.BigDecimal\n\t| number1.add(i);\n\t|_____________^\n```\n\nWe can add, multiple, divide or subtract `BigDecimal` values.\n\n```java\n\tjshell\u003e number1.add(new BigDecimal(i));\n\t$2 ==\u003e 16.5\n\tjshell\u003e number1.multiply(new BigDecimal(i));\n\t$3 ==\u003e 67.5\n\tjshell\u003e number1.divide(new BigDecimal(100));\n\t$4 ==\u003e 0.115\n\tjshell\u003e\n\n```\n\n#### Summary\n\nIn this step, we:\n\n* Explored the ```BigDecimal``` methods for doing some basic arithmetic\n* Found that ```BigDecimal``` has constructors accepting most basic Java numeric types\n\n### Step 07: Classroom Exercise CE-02\n\n#### Exercise-Set\n\nWrite a Program that does a Simple Interest computation for a Principal amount. Recall that the formula for such a calculation is:\n\n`Total amount (TA) = Principal Amount (PA) + ( PA * Simple Interest (SI) Rate * Duration In Years (N))`\n\nIn essence, write a ```SimpleInterestCalculator``` ```class``` that can be used in the following manner:\n\n```java\n\n\tSimpleInterestCalculator calculator = new SimpleInterestCalculator(\"4500.00\", \"7.5\");\n\tBigDecimal totalValue = calculator.calculateTotalValue(5); //5 year duration\n\tSystem.out.println(totalValue);\n\n```\n\n#### Solution To CE-02\n\n**_SimpleInterestCalculatorRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.primitive.datatypes;\n\timport java.math.BigDecimal;\n\n\tpublic class SimpleInterestCalculatorRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tSimpleInterestCalculator calculator = new SimpleInterestCalculator(\"4500.00\", 7.5\");\n\t\t\tBigDecimal totalValue = calculator.calculateTotalValue(5); //5 year duration\n\t\t\tSystem.out.println(totalValue);\n\t\t}\n\t}\n\n```\n\n**_SimpleInterestCalculator.java_**\n\n```java\n\n\tpackage com.in28minutes.primitive.datatypes;\n\timport java.math.BigDecimal;\n\n\tpublic class SimpleInterestCalculatorRunner {\n\t\tBigDecimal principal;\n\t\tBigDecimal interest;\n\n\t\tpublic SimpleInterestCalculator(String principal, String interest) {\n\t\t\tthis.principal = new BigDecimal(principal);\n\t\t\tthis.interest = new BigDecimal(interest).divide(new BigDecimal(100));\n\t\t}\n\n\t\tpublic BigDecimal calculateTotalValue(int noOfYears)\n\t\t\t//Total Value = Principal  + Principal * Interest* Years\n\t\t\tBigDecimal totalValue = prinipal.add(principal.multiply(interest).multiply(new BigDecimal(noOfYears)));\n\t\t\treturn totalValue;`\n\t\t}\t\n}\n\n```\n\n**_Console Output:_**\n\n_6187.50000_\n\n#### Tip: The ```import``` Statement\n\nThe Java ```import``` statement is Required in each source file that uses a ```class``` from another ```package```. Hence, both **_SimpleInterestCalculator.java_** (```class``` definition) and **_SimpleInterestCalculatorRunner.java_** (runner ```class``` definition) need to import ```class``` ```java.math.BigDecimal```.\n\n```package java.lang.*``` is imported by default. \n\nThe ```.*``` suffix indicates that all classes in the ```package``` ```java.lang``` are being imported.\n\n#### Summary\n\nIn this step, we:\n\n* Used ```BigDecimal``` values in a stand-alone Java program\n* Learnt how to make use of built-in Java packages, through the ```import``` statement \n\n### Step 08: ```boolean```, Relational and Logical Operators\n\nThe Java ```boolean\t``` data type is one that holds only one of two values: ```true``` or ```false```. Both labels are case-sensitive. We have seen examples of built-in comparison operators, such as ```==```, ```!=``` and ```\u003e```, that evaluate expressions to  give us ```boolean``` results. Let us do a quick recap of some of these.\n\n##### Snippet-01 : Relational Operators : Recap\n\nRelational Operators are used mainly for comparison. They accept operands of non-```boolean``` primitive data types, and return a ```boolean``` value.\n\n```java\n\n\tjshell\u003e int i = 7;\n\ti ==\u003e 7\n\tjshell\u003e i \u003e 7;\n\t$1 ==\u003e false\n\tjshell\u003e i \u003e= 7;\n\t$2 ==\u003e true\n\tjshell\u003e i \u003c 7;\n\t$3 ==\u003e false\n\tjshell\u003e i \u003c= 7;\n\t$4 ==\u003e true\n\tjshell\u003e i == 7;\n\t$5 ==\u003e true\n\tjshell\u003e i == 8;\n\t$6 ==\u003e false\n\tjshell\u003e\n\t\n```\n\n#### Logical Operators\n\nJava also has logical operators that are used in expressions. Logical operators expect ```boolean``` operands. Expressions involving these are used for forming ```boolean``` conditions in code, including within  ```if```, ```for``` and ```while``` statements.  The prominent logical operators are:\n\n* ```\u0026\u0026``` : logical **AND**\n* ```||``` : **OR**\n* ```!``` : **NOT**\n\nLet's learn how we use them in our code.\n\n##### Snippet-02 : Logical Operators\n\nWe would want to find if `i` is between `15` and `25`.  An expression `i \u003e= 15 \u0026\u0026 i \u003c= 25` can be used. Details below.\n\n```java\n\n\tjshell\u003e int i = 17;\n\ti ==\u003e 17\n\tjshell\u003e i \u003e= 15\n\t$1 ==\u003e true\n\tjshell\u003e i \u003c= 25\n\t$2 ==\u003e true\n\tjshell\u003e i \u003e= 15 \u0026\u0026 i \u003c= 25\n\t$3 ==\u003e true\n\tjshell\u003e i == 30;\n\ti ==\u003e 30\n\tjshell\u003e i \u003e= 15 \u0026\u0026 i \u003c= 25\n\t$4 ==\u003e false\n\tjshell\u003e i == 5;\n\ti ==\u003e 30\n\tjshell\u003e i \u003e= 15 \u0026\u0026 i \u003c= 25\n\t$5 ==\u003e false\n```\n\nAn expression with```\u0026\u0026``` evaluates to ```true``` only if **both** its ```boolean``` operands evaluate to ```true```.\n\n```java\n\tjshell\u003e true \u0026\u0026 true\n\t$6 ==\u003e true\n\tjshell\u003e true \u0026\u0026 false\n\t$7 ==\u003e false\n\tjshell\u003e false \u0026\u0026 true\n\t$8 ==\u003e false\n\tjshell\u003e false \u0026\u0026 false\n\t$9 ==\u003e false\n\tjshell\u003e\n\n```\n\n##### Snippet-02 Explained\n\nThe next example helps us visualize truth tables for the prominent logical operators.\n\n```java\n\n\tjshell\u003e true || true\n\t$1 ==\u003e true\n\tjshell\u003e true || false\n\t$2 ==\u003e true\n\tjshell\u003e false || true\n\t$3 ==\u003e true\n\tjshell\u003e false || false\n\t$4 ==\u003e false\n\tjshell\u003e true ^ true\n\t$5 ==\u003e false\n\tjshell\u003e true ^ false\n\t$6 ==\u003e true\n\tjshell\u003e false ^ true\n\t$7 ==\u003e true\n\tjshell\u003e false ^ false\n\t$8 ==\u003e false\n\tjshell\u003e !true\n\t$9 ==\u003e false\n\tjshell\u003e !false\n\t$10 ==\u003e true\n\tjshell\u003e int x = 6;\n\tx ==\u003e 6\n\tjshell\u003e !(x \u003e 7)\n\t$11 ==\u003e true\n\tjshell\u003e\n\n```\n\n#### Summary\n\nIn this step, we:\n\n* We're introduced to the ```boolean``` primitive type\n* Understood where logical operators are used in Java programs\n* Explored the truth-tables of commonly used logical operators\n\n### Step 09: Short-Circuit Evaluation (With Puzzles)\n\nConsider code below. The expression ```j \u003e 15 \u0026\u0026 i++ \u003e 5``` evaluates to ```false``` as expected. `j\u003e15` is `false` as `j` has a value of `15`. \n\n\n```java\n\n\tjshell\u003e int j = 15;\n\tj ==\u003e 15\n\tjshell\u003e int i = 10;\n\ti ==\u003e 10\n\tjshell\u003e j \u003e 15 \u0026\u0026 i++ \u003e 5\n\t$1 ==\u003e false\n\tjshell\u003e j\n\tj ==\u003e 15\n\tjshell\u003e i\n\ti ==\u003e 10\n```\n\nYou can also observe that the value of i remains unchanged `10`.  \n\nWhy? Because ```i++ \u003e 5``` was not even evaluated.\nWhy? `\u0026\u0026` is lazy. It saw that `j \u003e 15` is false. Irrespective of the result of second expression, the result of this `\u0026\u0026` would be false. So, it does NOT evaluate the second expression.\n\n***A more detailed explanation***\n\nThe expression ```j \u003e 15 \u0026\u0026 i++ \u003e 5``` was scanned from left to right. As the first operand to ```\u0026\u0026``` evaluated to ```false```, the compiler got lazy. `\u0026\u0026` avoids evaluating expressions that don't affect the final result. The optimization has a name: **Short-Circuit Evaluation**, also called **lazy evaluation**.\n\n\nThe logical operator ```\u0026``` is another version of the logical **AND** operation, that does away with lazy evaluation. \n\nBoth operands to ```\u0026``` are always evaluated. \n\n```java\n\n\tjshell\u003e j \u003e 15 \u0026 i++ \u003e 5\n\t$1 ==\u003e false\n\tjshell\u003e j\n\tj ==\u003e 15\n\tjshell\u003e i\n\ti ==\u003e 11\n\tjshell\u003e\n\n```\n\nSimilarly, the logical **OR** operator also has two versions: \n* The ```||``` operator we saw earlier. This exhibits lazy evaluation.\n* The ```|``` operator, without lazy evaluation.\n\nIt is bad programming practice for our code to depend on the compiler's lazy evaluation. It makes code less readable, and can hide difficult-to-fix software bugs. It obviously adds to the code maintenance burden, so don't do it unless you like being in your peers' bad books.        \n\n#### Summary\n\nIn this step, we:\n\n* Examined conditions involving logical operators, that had lazy evaluation\n* Observed that the lazy evaluation depends on the operator's truth-table\n* Saw versions of the operators without lazy evaluation\n* Learned that code depending on lazy-evaluation, is less readable \n\n### Step 10: Character Types\n \nEarlier, we explored how we could store basic keyboard characters(called **ascii-code** characters), such as:\n* Upper-Case and lower-case letters (A-Z, a-z)\n* Numeric characters (0-9)\n* Punctuation and other special characters (such as ',', '$', '{', etc.)\n\nTurns out Java supports a much larger family of character encoding sets, called **Unicode**. All Unicode characters can be input to, understood and processed by, as well as output from your code. \n\n##### Snippet-01 : Unicode characters\n\nNot all Unicode characters can be input from your keyboard. But Java allows you to  handle their values from your code, if you deal correctly with their format.\n\n```java \n \n\tjshell\u003e char ch = '\"';\n\tch ==\u003e '\"'\n\tjshell\u003e char c = '\\u0022';\n\tc ==\u003e '\"'\n```\n\nInteger values can be stored in ```char``` variables. If the value is within a meaningful range, it also corresponds to the **ascii** value of a keyboard character. \n\n```java\n\tjshell\u003e char cn = 65;\n\tcn ==\u003e 'A'\n```\n\nInteger arithmetic can be performed on `char` data.\n\n```java\n\tjshell\u003e cn++\n\t$1 ==\u003e 'A'\n\tjshell\u003e cn\n\t$2 ==\u003e 'B'\n\tjshell\u003e ++cn\n\t$3 ==\u003e 'C'\n\tjshell\u003e cn + 5\n\t$4 ==\u003e 72\n\tjshell\u003e cn\n\tcn ==\u003e 'C'\n\tjshell\u003e (int)cn\n\tcn ==\u003e 67\n\tjshell\u003e\n\n```\n\n\n#### Summary\n\nIn this step, we:\n\n* Were introduced the the ```char``` data type\n* Learned that Unicode takes the character set beyond your keyboard\n* An ascii character is ```char``` value, encoded by an integer value\n\n### Step 11: Programming Exercise PE-02\n\n#### Exercise Set\n\n1. Write a Java class ```MyChar``` that is a special type of ```char```. An object of type ```MyChar``` is created round an input ```char``` data element, and has operations that do the following:\n\t* Check if the input character is a:\n\t\t* Numeric Digit\n\t\t* Letter of the Alphabet\n\t\t* Vowel (Either upper-case or lower-case)\n\t\t* Consonant (Either upper-case or lower-case) NOTE: A letter is a consonant if not a vowel\n\t* Print all the letters of the Alphabet in\n\t\t* Upper-Case\n\t\t* Lower-Case\n\nIn Essence, a runner ```class``` for ```MyChar``` would have its ```main``` method run code similar to:\n\n```java\n\n\tMyChar myChar = new MyChar('c');\n\tSystem.out.println(myChar.isDigit());\n\tSystem.out.println(myChar.isAlphabet());\n\tSystem.out.println(myChar.isVowel());\n\tSystem.out.println(myChar.isConsonant());\n\tmyChar.printLowerCaseAlphabets();\n\tmyChar.printUpperCaseAlphabets();\n\n```\n\n### Step 12: Solution To PE-02, Part 1 - ```isVowel()```\n\n**_MyCharRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.primitive.datatypes;\n\n\tpublic class MyCharRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMyChar myChar = new MyChar('c');\n\t\t\tSystem.out.println(myChar.isVowel());\n\t\t}\n\t}\n\n```\n\n**_MyChar.java_**\n\n```java\n\n\tpackage com.in28minutes.primitive.datatypes;\n\t\n\tpublic class MyChar {\n\t\tprivate char ch;\n\t\t\n\t\tpublic MyChar(char ch) {\n\t\t\tthis.ch = ch;\n\t\t}\n\n\t\tpublic boolean isVowel() {\n\t\t\tif(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {\n\t\t\t\treturn true;\n\t\t\t} \n\t\t\tif(ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U') {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\n```\n\n**_Console Output_** :\n\n_false_\n\n### Step 13: Solution To PE-02, Part 2 - ```isDigit()```\n\n**_MyCharRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.primitive.datatypes;\n\n\tpublic class MyCharRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMyChar myChar = new MyChar('c');\n\t\t\tSystem.out.println(myChar.isDigit());\n\t\t\tSystem.out.println(myChar.isVowel());\n\t\t}\n\t}\n\n```\n\n**_MyChar.java_**\n\n```java\n\n\tpackage com.in28minutes.primitive.datatypes;\n\n\tpublic class MyChar {\n\t\tprivate char ch;\n\n\t\tpublic MyChar(char ch) {\n\t\t\tthis.ch = ch;\n\t\t}\n\n\t\tpublic boolean isVowel() {\n\t\t\tif(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {\n\t\t\t\treturn true;\n\t\t\t} \n\n\t\t\tif(ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U') {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic boolean isDigit() {\n\t\t\tif(ch \u003e= 48 \u0026\u0026 ch \u003c= 57) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n}\n\n```\n\n**_Console Output_** :\n\n_false_\n\n_false_\n\n### Step 14: Solution To PE-02, Part 3 - Other Methods\n\n**_MyCharRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.primitive.datatypes;\n\t\n\tpublic class MyCharRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMyChar myChar = new MyChar('c');\n\t\t\tSystem.out.println(myChar.isDigit());\n\t\t\tSystem.out.println(myChar.isAlphabet());\n\t\t\tSystem.out.println(myChar.isVowel());\n\t\t\tSystem.out.println(myChar.isConsonant());\n\t\t\tmyChar.printLowerCaseAlphabets();\n\t\t\tmyChar.printUpperCaseAlphabets();\n\t\t}\n\t}\n\n```\n\n**_MyChar.java_**\n\n```java\n\n\tpackage com.in28minutes.primitive.datatypes;\n\n\tpublic class MyChar {\n\t\tprivate char ch;\n\t\t\n\t\tpublic MyChar(char ch) {\n\t\t\tthis.ch = ch;\n\t\t}\n\n\t\tpublic boolean isVowel() {\n\t\t\tif(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {\n\t\t\t\treturn true;\n\t\t\t} \n\t\t\tif(ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U') {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic boolean isConsonant() {\n\t\t\tif(isAlphabet() \u0026\u0026 !(isVowel())) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic boolean isDigit() {\n\t\t\tif(ch \u003e= 48 \u0026\u0026 ch \u003c= 57) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic boolean isAlphabet() {\n\t\t\tif(ch \u003e= 97 \u0026\u0026 ch \u003c= 122) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tif(ch \u003e= 65 \u0026\u0026 ch \u003c= 90) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic void printLowerCaseAlphabets() {\n\t\t\tfor(char ch='a'; ch \u003c= 'z'; ch++) {\n\t\t\t\tSystem.out.println(ch);\n\t\t\t}\n\t\t}\n\n\t\tpublic void printUpperCaseAlphabets() {\n\t\t\tfor(char ch='A'; ch \u003c= 'Z'; ch++) {\n\t\t\t\tSystem.out.println(ch);\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Console Output_** :\n\n_false_\n\n_true_\n\n_false_\n\n_true_\n\na\n\nb\n\nc\n\nd\n\ne\n\nf\n\ng\n\nh\n\ni\n\nj\n\nk\n\nl\n\nm\n\nn\n\no\n\np\n\nq\n\nr\n\ns\n\nt\n\nu\n\nv\n\nw\n\nx\n\ny\n\nz\n\nA\n\nB\n\nC\n\nD\n\nE\n\nF\n\nG\n\nH\n\nI\n\nJ\n\nK\n\nL\n\nM\n\nN\n\nO\n\nP\n\nQ\n\nR\n\nS\n\nT\n\nU\n\nV\n\nW\n\nX\n\nY\n\nZ\n\n### Step 15: The Primitive Types - A Review\n\nIn this section, we built on our knowledge of the primitive Java types. \n\n* We first got familiar with built-in wrappers for the integer types, that store useful type information. \n* Going from the integer to the floating-point types, we examined type compatibility, and how the compiler warns you about common pitfalls. We used explicit casts to force type conversions, and learned that implicit type conversions are quite common.\n* We moved on to the ```BigDecimal``` class, a floating-point type with greater precision and accuracy. \n* Next in line was ```boolean```, where we built on what we know of logical expressions. We focused on the logical operators, more so on short-circuit evaluation of their expressions. \n* We saw how dependency on side-effects, and on lazy evaluation, is not a good programming practice.\n* Finally, we got to the ```char``` type, and were pleasantly surprised to know, that the keyboard is not the limit.\n\n## Introducing Conditionals - if, switch and more\n\nDecision making is a part of our daily lives. Computers do tasks for humans, so even programs need to make decisions. They do this by checking logical conditions, which evaluate to ```boolean``` values. \n\nIn the following steps, we will explore the following **conditional** statements:\n\n* ```if```\n* ```if```-```else```\n* ```if```-```else if```-```else```\n* ```switch```  \n\nWhat better way to master these basics, than using them to solve a programming challenge? \n\nHere we go!\n\n#### Programming Challenge : Design A Menu (The *Menu-Challenge*)\n\n* Ask the User for input:\n\t* Enter two numbers\n\t* Choose the arithmetic to do on those:\n\t\t* Add\n\t\t* Subtract\n\t\t* Multiply\n\t\t* Divide\n* Perform the Operation\n* Publish the Result\n\n***An example scenario could be:***\n\nEnter First Number\n\n2\n\nEnter Second Number\n\n4\n\n1 - Add\n\n2 - Subtract\n\n3 - Multiply\n\n4 - Divide\n\nEnter your choice of operation\n\n3\n\nThe Result Is : 8\n\n#### Summary\n\nIn this step, we:\n\n* Discussed how input affects the control-flow of a program\n* Listed out the conditionals available with Java\n* Selected a programming challenge to help us learn about conditions\n\n### Step 01: The ```if``` and ```if```-```else``` Conditionals\n\nAn ```if``` statement is the most basic way to manage control-flow in a program. A ```boolean``` condition is tested, and if found to be ```true```, some code is executed. Otherwise, that code is not run. \n\n* \"**_Do Something when ```condition``` is ```true```_**\"\n\nConceptually, the ```if``` statement looks like this:\n\n```java\n\n\tif(condition) {\n\t\t\u003cif-body\u003e\n\t}\n\n```\n\nAn ```if```-```else``` statement improves over the plain ```if```. We can now choose between executing two pieces of code, depending on what ```condition``` evaluates to.\n\n* \"**_Do Something when ```condition``` is ```true```, something else when ```condition``` is ```false```_**\"\n\nAn ```if```-```else``` statement boils down to the following:\n\n```java\n\n\tif(condition) {\n\t\t\u003cif-body\u003e\n\t} else {\n\t\t\u003celse-body\u003e\n\t}\n\n```\n\nIf ```condition``` is found to be ```true```, the statement block ```\u003cif-body\u003e``` is executed, otherwise ```\u003celse-body\u003e``` is run.\n\nLet's now look at a examples that make use of these conditionals.\n\n##### Snippet-01 : ```if``` behavior\n\nIn this example:\n*  we have used compound comparison operators such as ```\u003c=``` and ```\u003e=```, which also evaluate to ```boolean``` values. \n*  Also used, are logical operators such as ```\u0026\u0026``` and ```||```, which both accept and return values of type ```boolean```.\n\n\n\n```java\n\n\tjshell\u003e int i = 3;\n\ti ==\u003e 3\n\tjshell\u003e if(i==3) {\n\t   ..\u003e\u003e System.out.println(\"True\");\n\t   ..\u003e\u003e }\n\tTrue\n\tjshell\u003e if(i\u003c2) {\n\t   ..\u003e\u003e System.out.println(\"True\");\n\t   ..\u003e\u003e }\n\t\n\tjshell\u003e if(i\u003c=3 || i \u003e= 35) {\n\t   ..\u003e\u003e System.out.println(\"True\");\n\t   ..\u003e\u003e }\n\tTrue\n\tjshell\u003e if(i\u003c=3 \u0026\u0026 i \u003e= 35) {\n\t   ..\u003e\u003e System.out.println(\"True\");\n\t   ..\u003e\u003e }\n```\n\n```if```-```else``` allows us to specify code to execute when a condition is `false`.\n\n```java\n\tjshell\u003e if(i==3) {\n\t   ..\u003e\u003e System.out.println(\"True\");\n\t   ..\u003e\u003e } else {\n\t   ..\u003e\u003e System.out.println(\"i is not 3\");\n\t   ..\u003e\u003e }\n\tTrue\n\tjshell\u003e i = 5;\n\ti ==\u003e 5\n\tjshell\u003e if(i==3) {\n\t   ..\u003e\u003e System.out.println(\"True\");\n\t   ..\u003e\u003e } else {\n\t   ..\u003e\u003e System.out.println(\"i is not 3\");\n\t   ..\u003e\u003e }\n\ti is not 3\n\tjshell\u003e\n\n```\n\n\n##### Snippet-02 : chained ```if```-```else``` - v1\n\n**_IfStatementRunner.java_**\n\n```java\n\n\tcom.in28minutes.ifstatement.examples;\n\n\tpublic class IfStatementRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\t//int i=25;\n\t\t\tint i=26;\n\t\t\tif(i == 25) {\n\t\t\t\tSystem.out.println(\"i = 25\");\n\t\t\t} else {\t\t\n\t\t\t\tSystem.out.println(\"i != 25\");\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_i != 25_\n\n##### Snippet-03 : chained if-else v2\n\nWe would want to test a number for 3 conditions - `value is 24`, `value is 25` or `value is not 24 and 25`. Let's consider the code from the example below.\n\n**_IfStatementRunner.java_**\n\n```java\n\n\tcom.in28minutes.ifstatement.examples;\n\n\tpublic class IfStatementRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\t// if i is 25, print i = 25\n\t\t\t//if i is 24, print i = 24\n\t\t\t//otherwise, print i != 25 and i != 24\n\t\t\t\n\t\t\tint i=25;\n\t\t\tif(i == 25) {\n\t\t\t\tSystem.out.println(\"i = 25\");\n\t\t\t}\n\t\t\tif(i == 24) {\n\t\t\t\tSystem.out.println(\"i = 24\"); \n\t\t\t} else {\t\t\t\n\t\t\t\tSystem.out.println(\"i != 25 and i != 24\");\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_i = 25_\n\n_i != 25 and i != 24_\n\n##### Snippet-03 Explained\n\nWhat just happened here? The value of ```i``` is set to ```25``` within the program, so like in the previous example, only **_i = 25_** should have been printed. \n\nWhy the extra print?\n\nWe started off trying to check fro 3 possibilities:\n\t* ```i``` being equal to ```25```\n\t* ```i``` being equal to ```24```\n\t* Neither of the above\n\nWe get wrong output, because ```i == 25``` in first ```if``` is independent from ```i == 24``` in the ```if```-```else``` that follows it. \n\nOur decision making is not continuous. We need a tighter conditional to deal with more than two alternatives. We will explore this topic in the next step.\n\n#### Summary\n\nIn this step, we:\n\n* Learned about the ```if``` and ```if```-```else``` conditionals\n* Tried out a few examples to see how they are used\n\n### Step 02: The ```if```-```else if```-```else``` Conditional\n\nThe ```if```-```else if```-```else``` statement solves the issue we faced, while trying to test more than two conditions.\n\nLet's see an example.\n\n##### Snippet-01 : Matching The ```if``` Clause\n\n**_IfStatementRunner.java_**\n\n```java\n\n\tcom.in28minutes.ifstatement.examples;\n\n\tpublic class IfStatementRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\t// if i is 25, print i = 25\n\t\t\t//if i is 24, print i = 24\n\t\t\t//otherwise, print i != 25 and i != 24\n\n\t\t\tint i=25;\n\t\t\tif(i == 25) {\n\t\t\t\tSystem.out.println(\"i = 25\");\n\t\t\t} else if(i == 24) {\n\t\t\t\tSystem.out.println(\"i = 24\"); \n\t\t\t} else {\n\t\t\t\tSystem.out.println(\"i != 25 and i != 24\");\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_i = 25_\n\nLet's now try giving ```i``` a different value, say ```24```.\n\n##### Snippet-02: Matching The ```else if``` Clause \n\n**_IfStatementRunner.java_**\n\n```java\n\n\tcom.in28minutes.ifstatement.examples;\n\n\tpublic class IfStatementRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\t// if i is 25, print i = 25\t\t\n\t\t\t//if i is 24, print i = 24\n\t\t\t//otherwise, print i != 25 and i != 24\n\t\t\n\t\t\t//int i=25;\n\t\t\tint i=24;\n\t\t\tif(i == 25) {\n\t\t\t\tSystem.out.println(\"i = 25\");\n\t\t\t} else if(i == 24) {\n\t\t\t\tSystem.out.println(\"i = 24\"); \n\t\t\t} else {\n\t\t\t\tSystem.out.println(\"i != 25 and i != 24\");\t\t\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n**_i = 24_**\n\n##### Snippet-02 Explained\n\n* With ```i``` holding ```24```, a different condition (the one coresponding to ```i == 24```) evaluates to ```true```.\n\nLet's now try to get a match with the ```else``` clause, the only one unexplored so far. \n\n##### Snippet-03: Matching The ```else``` Clause\n\n**_IfStatementRunner.java_**\n\n```java\n\n\tcom.in28minutes.ifstatement.examples;\n\n\tpublic class IfStatementRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\t// if i is 25, print i = 25\n\t\t\t//if i is 24, print i = 24\n\t\t\t//otherwise, print i != 25 and i != 24\n\t\t\t\n\t\t\t//int i=24;\n\t\t\tint i=26;\n\t\t\tif(i == 25) {\n\t\t\t\tSystem.out.println(\"i = 25\");\n\t\t\t} else if(i == 24) {\n\t\t\t\tSystem.out.println(\"i = 24\"); \n\t\t\t} else {\n\t\t\t\tSystem.out.println(\"i != 25 and i != 24\");\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n**_i != 25 and i != 24_**\n\n##### Snippet-03 Explained\n\nWhen ```i``` is given a value of ```26```, the first two conditions are false. Hence, the code in the `else` gets executed. \n\n_**one, and only one** clause among those present in an  ```if```-```else if```-```else``` statement ever evaluates to ```true```. Also, the code block corresponding to the matched clause will get executed. This is ensured even if conditions are *duplicated*, or *overlap*. In that scenario, only the first such condition, downward from the ```if``` in sequence, will evaluate to ```true```. The remaining possible matches are not even checked._\n\n#### Summary\n\nIn this step, we:\n\n* Learned about the ```if```-```else if```-```else``` conditional\n* Found out how to test when each different clause gets executed\n* Understood the guarantees made by Java regarding the conditional's code execution\n\n### Step 03:  Puzzles on ```if```\n\nTry and guess the outputs of the following puzzles.\n\n#### Programming Puzzle PP-01\n\n```java\n\n\tpublic class puzzleRunner {\n\n\t\tpublic static void main(String[] args) {\n\t\t\tpuzzleOne();\n\t\t}\n\n\t\tpublic static void puzzleOne() {\n\t\t\tint k = 15;\n\t\t\tif(k \u003e 20) {\n\t\t\t\tSystem.out.println(1);\n\t\t\t} else if(k \u003e 10) {\n\t\t\t\tSystem.out.println(2);\n\t\t\t} else if(k \u003c 20) {\n\t\t\t\tSystem.out.println(3);\n\t\t\t} else {\n\t\t\t\tSystem.out.println(4);\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**Answer:**\n\n**_2_**\n\n#### Programming Puzzle PP-02\n\n```java\n\n\tpublic class puzzleRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tpuzzleTwo();\n\t\t}\n\n\t\tpublic static void puzzleTwo() {\n\t\t\tint l = 15;\n\t\t\tif(l \u003c 20)\n\t\t\tSystem.out.println(\"l \u003c 20\");\n\t\t\tif(l \u003e 20)\n\t\t\tSystem.out.println(\"l \u003e 20\");\n\t\t\telse\n\t\t\tSystem.out.println(\"Who Am I?\");\n\t\t}\n\t}\n\n```\n\n**Answer:**\n\n**_l \u003c 20_**\n\n**_Who Am I?_**\n\n#### Programming Puzzle PP-03\n\n```java\n\n\tpublic class puzzleRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tpuzzleThree();\n\t\t}\n\t\t\n\t\tpublic static void puzzleThree() {\n\t\t\tint m = 15;\n\t\t\tif(m \u003e 20)\n\t\t\tif(m \u003c 20)\n\t\t\tSystem.out.println(\"m \u003e  20\");\telse\n\t\t\tSystem.out.println(\"Who Am I?\");\n\t\t}\n\t}\n\n```\n\n**Answer:**\n \n\n\u003e Nothing is printed. Because the code is structured this way.\n\n```java\nif(m \u003e 20) {\n\tif(m \u003c 20)\n\t\tSystem.out.println(\"m \u003e  20\");\t\n\telse\n\t\tSystem.out.println(\"Who Am I?\");\n}\n```\n\n#### Programming Puzzle PP-04\n\n```java\n\n\tjshell\u003e int i = 0;\n\ti ==\u003e 3\n\tjshell\u003e if(i) {\n\t   ..\u003e\u003e System.out.println(\"i\");\n\t   ..\u003e\u003e }\n\t| Error:\n\t| incompatible types: int cannot be converted to boolean\n\t| if(i)\n\t|____^\n\tjshell\u003e if(i=1) {\n\t   ..\u003e\u003e System.out.println(\"i\");\n\t   ..\u003e\u003e }\n\t| Error:\n\t| incompatible types: int cannot be converted to boolean\n\t| if(i=1)\n\t|____^-^\n\tjshell\u003e if(i==1) {\n\t   ..\u003e\u003e System.out.println(\"i\");\n\t   ..\u003e\u003e }\n\tjshell\u003e\n\n```\n\n**Answer:**\n\n_**Compiler Error**_\n\n#### Programming Puzzle PP-05\n\n```java\n\n\tpublic class puzzleRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tpuzzleFive();\n\t\t}\n\n\t\tpublic static void puzzleFive() {\n\t\t\tint number = 5;\n\t\t\tif(number \u003c 0)\n\t\t\tnumber = number + 10;\n\t\t\tnumber++;\n\t\t\tSystem.out.println(number);\n\t\t}\n\t}\n\n```\n\n**Answer : **\n\n**_6_**\n\n\u003e In the absence of explicit blocks, Only the statement next to the if statement is considered to be part of the if statement block.\n\n### Step 04: Reading User Input\n- - - \n\nLook at the statement of *Menu-Challenge* once again:\n\n#### *Menu-Challenge*\n\n* Ask the User for input:\n\t* Enter two numbers\n\t* Choose an Arithmetic Operation to perform on them:\n\t\t* Add\n\t\t* Subtract\n\t\t* Multiply\n\t\t* Divide\n* Perform the Operation\n* Publish the Result\n\nWe have a good idea about how the ```if```-```else if```-```else``` conditional works.What we don't know, however, is how a such a conditional would behave when fed with random input. To test those scenarios out, the next step would be to learn how to take console input, from within our code.\n\nWe will do just that, in our next example.\n\n##### Snippet-01: Reading console input\n\nJava provides a built-in ```class``` named  ```Scanner```, to scan user input from the console. Roping in this utility would require you, the programmer, to do the following:\n* ```import``` the ```java.util.Scanner``` ```class``` within your code (here, we were writing code in the Eclipse IDE)\n* Create a ```scanner``` object which is of type ```Scanner```. This involves invoking the ```Scanner``` constructor through the ```new``` operator. You also need to pass  ```System.in``` as a constructor parameter, which ties ```scanner``` to the console input.\n* To read integer input from the console, call the method ```scanner.nextInt()```. The keyboard's \u003cEnter\u003e key needs to be pressed to complete user input. That number is passed on to your code, where it can be passed around.\n\n**_MenuScanner.java_**\n\n```java\n\n\tpackage com.in28minutes.ifstatement.examples;\n\timport java.util.Scanner;\n\n\tpublic class MenuRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tScanner scanner = new Scanner(System.in);\n\t\t\tSystem.out.print(\"Enter Number1: \");\n\t\t\tint number1 = Scanner.nextInt();\t\t\n\t\t\tSystem.out.println(\"The number you entered is: \" + number1);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Enter Number1: 35_\n\n_The number you entered is: 35_\n\n\n#### Summary\n\nIn this step, we:\n\n* Revisited our *Menu-Challenge* problem statement, and found we needed to read user input\n* Explored the basic usage of the ```Scanner``` utility to fulfill this need\n\n### Step 05: *Menu-Challenge* : Reading More Input\n\nThe *Menu-Challenge* does not stop at a single user input. It requires a total of three numbers to be typed in at the console. So how do we continue asking for input, and read them when they are given?\n\n##### Snippet-01 : Implementing *Menu-Challenge*\n\n**_MenuScanner.java_**\n\n```java\n\n\tpackage com.in28minutes.ifstatement.examples;\n\timport java.util.Scanner;\n\n\tpublic class MenuRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tScanner scanner = new Scanner(System.in);\n\t\t\tSystem.out.print(\"Enter Number1: \");\n\t\t\tint number1 = Scanner.nextInt();\n\t\t\tSystem.out.print(\"Enter Number2: \");\n\t\t\tint number2 = Scanner.nextInt();\n\n\t\t\tSystem.out.println(\"Select The Operation Choice\");\n\t\t\tSystem.out.println(\"1 - Add\");\n\t\t\tSystem.out.println(\"2 - Subtract\");\n\t\t\tSystem.out.println(\"3 - Multiply\");\n\t\t\tSystem.out.println(\"4 - Divide\");\n\t\t\tSystem.out.print(\"Enter Choice: \");\n\t\t\tint choice = Scanner.nextInt();\n\n\t\t\tSystem.out.print(\"Your Inputs Are:\");\n\t\t\tSystem.out.println(\"Number1: \" + number1);\n\t\t\tSystem.out.println(\"Number2: \" + number2);\n\t\t\tSystem.out.println(\"Choice: \" + choice);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Enter Number1: 25_\n\n_Enter Number2: 50_\n\n_Operation Choices Available_\n\n_1 - Add_\n\n_2 - Subtract_\n\n_3 - Multiply_\n\n_4 - Divide_\n\n_Enter Choice: 4_\n\n_Your Inputs Are_\n\n_Number1: 25_\n\n_Number2: 50_\n\n_Choice: 4_\n\n##### Snippet-01 Explained\n\nRepeatedly calling ```scanner.nextInt()``` will keep reading in any number the user may input. Also, the user needs to press the keyboard \u003cEnter\u003e key to send each input.\n\nWe were not only able to read in all three values we need, but also wrote them out on the console. The user can now see that we got his data! \n\n#### Summary\n\nIn this step, we:\n\n* Figured out how to read more than one input from the console\n* Demonstrated how values read in, can be preserved and used within the program\n\n### Step 06: *Menu-Challenge* - Reading Input, Computing Result, Displaying Output\n\nWe don't think that after the previous step, anything can stop you from completing the *Menu-Challenge*. Here is one such way, from head-to-toe. \n\n##### Snippet-01 : All computations\n\nOur solution above does a very simple thing. It combines the mechanisms we learned for reading input and testing conditions, to solve *Menu-Challenge*. \n\nThe ```if```-```else```-```else if``` statement has a total of ```5``` clauses: \n* To check for ```4``` favorable conditions (The ```choice``` values for the ```4``` supported operations). One ```if``` and three ```else```-```if``` clauses do the stuff for us.\n* the last default condition, which corresponds to a ```choice``` value not supported, is handled by an ```else``` clause.\n\n**_MenuScanner.java_**\n\n```java\n\npackage com.in28minutes.ifstatement.examples;\nimport java.util.Scanner;\n\npublic class MenuRunner {\n\tpublic static void main(String[] args) {\n\t\tScanner scanner = new Scanner(System.in);\n\t\tSystem.out.print(\"Enter Number1: \");\n\t\tint number1 = Scanner.nextInt();\n\t\tSystem.out.print(\"Enter Number2: \");\n\t\tint number2 = Scanner.nextInt();\n\n\t\tSystem.out.println(\"Select The Operation Choice\");\n\t\tSystem.out.println(\"1 - Add\");\n\t\tSystem.out.println(\"2 - Subtract\");\n\t\tSystem.out.println(\"3 - Multiply\");\n\t\tSystem.out.println(\"4 - Divide\");\n\t\tSystem.out.print(\"Enter Choice: \");\n\t\tint choice = Scanner.nextInt();\n\n\t\tSystem.out.print(\"Your Inputs Are:\");\n\t\tSystem.out.println(\"Number1: \" + number1);\n\t\tSystem.out.println(\"Number2: \" + number2);\t\t\t\n\t\tSystem.out.println(\"Choice: \" + choice);\n\n\t\tif(choice == 1) {\n\t\t\tSystem.out.println(\"Result = \" + (number1 + number2));\n\t\t} else if(choice == 2) {\n\t\t\tSystem.out.println(\"Result = \" + (number1 - number2));\n\t\t} else if(choice == 3) {\n\t\t\tSystem.out.println(\"Result = \" + (number1 * number2));\n\t\t} else if(choice == 4) {\n\t\t\tSystem.out.println(\"Result = \" + (number1 / number2));\n\t\t} else {\n\t\t\tSystem.out.println(\"Invalid Operation\");\n\t\t}\n\t}\n}\n\n```\n\n**_Console Output_**\n\n_Enter Number1: 23_\n\n_Enter Number2: 10_\n\n_Operation Choices Available_\n\n_1 - Add_\n\n_2 - Subtract_\n\n_3 - Multiply_\n\n_4 - Divide_\n\n_Enter Choice: 2_\n\n_Your Inputs Are_\n\n_Number1: 23_\n\n_Number2: 10_\n\n_Choice: 2_ \n\n_Result = 13_\n\n**_Console Output_**\n\n_Enter Number1: 25_\n\n_Enter Number2: 35_\n\n_Operation Choices Available_\n\n_1 - Add_\n\n_2 - Subtract_\n\n_3 - Multiply_\n\n_4 - Divide_\n\n_Enter Choice: 5_\n\n_Your Inputs Are_\n\n_Number1: 23_\n\n_Number2: 10_\n\n_Choice: 5_ \n\n_Invalid Operation_\n\n\n#### Summary\n\nIn this step, we:\n\n* Combined our knowledge of conditionals, with our recent learning on taking multiple console inputs\n* Ultimately solved the *Menu-Challenge* problem\n\n### Step 07: Introducing ```switch```\n\nIf you remember, our initial list of conditionals to manage control-flow, also had a ```switch``` statement. A ```switch``` also tests multiple conditions, and just like an ```else``` clause, it can handle the default possibility. Conceptually, a ```switch``` statement looks like the following:\n\n```java\n\n\tswitch(condition) {\t\n\t\tcase 1:\n\t\t\t//\u003cstatements\u003e\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\t//\u003cstatements\u003e\n\t\t\tbreak;\n\t\t//...\n\t\tdefault:\n\t\t\t//\u003cstatements\u003e\n\t\t\tbreak;\n\t\t}\n\t}\n\n```\n\n```default``` clause is executed when none of the cases match. \n\n ```break;``` statement is used to break out of the switch after a successful match.\n\nLet's look at a few examples on how to use ```switch```.   \n\n##### Snippet-01: The ```switch``` statement\n\nUsing a ```switch``` leads to code that is quite readable, doesn't it? Compare it with the chained ```if```-```else if```-```else``` statements we used in the previous step.\n\nLeaving out the ```break``` statement from every ```case``` clause is a very common error. It leads to a situation called **switch-fall-through**. Here, even if there is a match with a particular ```case``` clause, all clauses following this one are executed in sequence, until a ```break``` is encountered somewhere!\n\n```java\n\n\tjshell\u003e int i = 5;\n\ti ==\u003e 5\n\tjshell\u003e switch(i) {\n\t   ..\u003e\u003e case 1 : System.out.println(\"1\");\n\t   ..\u003e\u003e case 5 : System.out.println(\"5\");\n\t   ..\u003e\u003e default : System.out.println(\"default\");\n\t   ..\u003e\u003e }\n\t5\n\tdefault\n\tjshell\u003e i = 1;\n\ti ==\u003e 1\n\tjshell\u003e switch(i) {\n\t   ..\u003e\u003e case 1 : System.out.println(\"1\");\n\t   ..\u003e\u003e case 5 : System.out.println(\"5\");\n\t   ..\u003e\u003e default : System.out.println(\"default\");\n\t   ..\u003e\u003e }\n\t1\n\t5\n\tdefault\n```\n\nAdding `break`s ensures that only the matching case is executed. \n\n```java\n\tjshell\u003e switch(i) {\n\t   ..\u003e\u003e case 1 : System.out.println(\"1\"); break;\n\t   ..\u003e\u003e case 5 : System.out.println(\"5\"); break;\n\t   ..\u003e\u003e default : System.out.println(\"default\"); break;\n\t   ..\u003e\u003e }\n\t1\n\tjshell\u003e\n\t\n```\n\n##### Snippet-02: refactoring MenuScanner\n\nLet's now refactor the `MenuScanner` example to use `switch` statement.\n\n**_MenuScanner.java_**\n\n```java\n\npackage com.in28minutes.ifstatement.examples;\nimport java.util.Scanner;\n\npublic class MenuRunner {\n\tpublic static void main(String[] args) {\n\t\tScanner scanner = new Scanner(System.in);\n\t\tSystem.out.print(\"Enter Number1: \");\t\t\n\t\tint number1 = Scanner.nextInt();\n\t\tSystem.out.print(\"Enter Number2: \");\n\t\tint number2 = Scanner.nextInt();\n\n\t\tSystem.out.println(\"Select The Operation Choice\");\n\t\tSystem.out.println(\"1 - Add\");\n\t\tSystem.out.println(\"2 - Subtract\");\n\t\tSystem.out.println(\"3 - Multiply\");\n\t\tSystem.out.println(\"4 - Divide\");\n\t\tSystem.out.print(\"Enter Choice: \");\n\t\tint choice = Scanner.nextInt();\n\n\t\tSystem.out.print(\"Your Inputs Are:\");\n\t\tSystem.out.println(\"Number1: \" + number1);\n\t\tSystem.out.println(\"Number2: \" + number2);\n\t\tSystem.out.println(\"Choice: \" + choice);\n\n\t\t//performOperationUsingChainedIfElse(number1, number2, choice);`\n\t\tperformOperationUsingSwitch(number1, number2, choice);\n\t}\n\n\tpublic static void performOperationUsingSwitch(int number1, int number2, int choice) {\n\t\tswitch(choice) {\n\t\t\tcase 1 : System.out.println(\"Result = \" + (number1 + number2)); break;\n\t\t\tcase 2 : System.out.println(\"Result = \" + (number1 - number2)); break;\n\t\t\tcase 3 : System.out.println(\"Result = \" + (number1 * number2)); break;\n\t\t\tcase 4 : System.out.println(\"Result = \" + (number1 / number2)); break;\n\t\t\tdefault : System.out.println(\"Invalid Operation\"); break;\n\t\t}\n\t}\n\n\tpublic static void performOperationUsingChainedIfElse(int number1, int number2, int choice) {\n\t\tif(choice == 1) {\n\t\t\tSystem.out.println(\"Result = \" + (number1 + number2));\n\t\t} else if(choice == 2) {\n\t\t\tSystem.out.println(\"Result = \" + (number1 - number2));\n\t\t} else if(choice == 3) {\n\t\t\tSystem.out.println(\"Result = \" + (number1 * number2));\n\t\t} else if(choice == 4) {\n\t\t\tSystem.out.println(\"Result = \" + (number1 / number2));\n\t\t} else {\t\t\n\t\t\tSystem.out.println(\"Invalid Operation\");\n\t\t}\n\t}\n}\n\n```\n\n**_Console Output_**\n\n_Enter Number1: 23_\n\n_Enter Number2: 10_\n\n_Operation Choices Available_\n\n_1 - Add_\n\n_2 - Subtract_\n\n_3 - Multiply_\n\n_4 - Divide_\n\n_Enter Choice: 2_\n\n_Your Inputs Are_\n\n_Number1: 23_\n\n_Number2: 10_\n\n_Choice: 2_ \n\n_Result = 13_\n\n**_Console Output_**\n\n_Enter Number1: 25_\n\n_Enter Number2: 35_\n\n_Operation Choices Available_\n\n_1 - Add_\n\n_2 - Subtract_\n\n_3 - Multiply_\n\n_4 - Divide_\n\n_Enter Choice: 5_\n\n_Your Inputs Are_\n\n_Number1: 23_\n\n_Number2: 10_\n\n_Choice: 5_ \n\n_Invalid Operation_\n\n#### Summary\n\nIn this step, we:\n\n* Explored the ```switch``` conditional\n* Saw how it could implement the same control-flow as the ```if``` family of conditionals\n* Learned the importance of coding it correctly, to enjoy Java control-flow guarantees\n\n### Puzzles On ```switch```\n\nLet's now have some fun with the various conditionals. These puzzles will not only ensure you're still wide awake, they will also give you ample food for thought. \n\n##### Programming Puzzle PP-01\n\n```java\n\n\tpublic class SwitchPuzzleRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tpuzzleOne();\n\t\t}\n\n\t\tpublic static void puzzleOne() {\n\t\t\tint number = 2;\n\t\t\tswitch(number) {\n\t\t\t\tcase 1:\n\t\t\t\t\tSystem.out.println(1);\t\t\t\n\t\t\t\tcase 2:\n\t\t\t\t\tSystem.out.println(2);\n\t\t\t\tcase 3:\n\t\t\t\t\tSystem.out.println(3);\n\t\t\t\tdefault:\n\t\t\t\t\tSystem.out.println(\"default\");\n\t\t\t}\n\t\t}\t\n\t}\n\n```\n\n**_Answer:_**\n\n_2_\n\n_3_\n\n_default_\n\n#### Programming Puzzle PP-02\n\n```java\n\n\tpublic class SwitchPuzzleRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tpuzzleTwo();\n\t\t}\n\n\t\tpublic static void puzzleTwo() {\n\t\t\tint number = 2;\n\t\t\tswitch(number) {\n\t\t\t\tcase 1:\n\t\t\t\t\tSystem.out.println(1);\n\t\t\t\tcase 2:\n\t\t\t\tcase 3:\n\t\t\t\t\tSystem.out.println(\"Number is 2 or 3\");\n\t\t\t\t\tbreak;\t\t\t\n\t\t\t\tdefault:\n\t\t\t\t\tSystem.out.println(\"default\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Answer:_**\n\n_Number is 2 or 3_\n\n##### Programming Puzzle PP-03\n\n```java\n\n\tpublic class SwitchPuzzleRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tpuzzleThree();\n\t\t}\n\n\t\tpublic static void puzzleThree() {\n\t\t\tint number = 10;\n\t\t\tswitch(number) {\n\t\t\t\tcase 1:\n\t\t\t\t\tSystem.out.println(1);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tSystem.out.println(2);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3:\n\t\t\t\t\tSystem.out.println(3);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tSystem.out.println(\"default\");\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Answer:_**\n\n_default_\n\n#### Programming Puzzle PP-04\n\n```java\n\n\tpublic class SwitchPuzzleRunner {\n\t\tpublic static void main(String[] args) {\n\t\tpuzzleFour();\n\t}\n\n\t\tpublic static void puzzleFour() {\n\t\t\tint number = 10;\n\t\t\tswitch(number) {\n\t\t\t\tSystem.out.println(\"default\");\n\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\t\tSystem.out.println(1);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\t\tSystem.out.println(2);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3:\n\t\t\t\t\tSystem.out.println(3);\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\t\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Answer:_**\n\n_default_\n\n#### Programming Puzzle PP-05\n\n```java\n\n\tpublic class SwitchPuzzleRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tpuzzleFive();\n\t\t}\n\n\t\tpublic static void puzzleFive() {\n\t\t\tlong l = 15;\n\t\t\tswitch(l) {\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Answer:_**\n\n**_Compiler Error_**\n\n#### Programming Puzzle PP-06\n\n```java\n\n\tpublic class SwitchPuzzleRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tpuzzleSix();\n\t\t}\n\n\t\tpublic static void puzzleSix() {\n\t\t\tint number = 10;\n\t\t\tint i = number * 2;\n\t\t\tswitch(number) {\n\t\t\t\tcase number\u003e5 : System.out.println(\"number\u003e5\");\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Answer:_**\n\n**_Compiler Error_**\n\n### Step 09: Comparing The ```if``` Family, And ```switch```\n\nLet's compare and contrast these two approaches, to gain some experience on how to choose a conditional.\n\nFirst comes an example using the ```if```-```else if```-```else``` statement.  \n\n##### Snippet-01 : Formatted Output Using ```if```\n\n**_OperatorChoiceRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.ifstatement.examples;\n\n\tpublic class OperatorChoiceRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tOperatorChoice opChoice = new OperatorChoice(5, 2, 1);\n\t\t\topChoice.operate();\n\t\t}\n\t}\n\n```\n\n**_OperatorChoice.java_**\n\n```java\n\n\tpackage com.in28minutes.ifstatement.examples;\n\n\tpublic class OperatorChoice {\n\t\tprivate int number1;\n\t\tprivate int number2;\n\t\tprivate int choice;\n\t\t\n\t\tpublic OperatorChoice(int number1, int number2, int choice) {\n\t\t\tthis.number1 = number1;\t\t\n\t\t\tthis.number2= number2;\n\t\t\tthis.choice = choice;\n\t\t}\n\n\t\tpublic void operate() {\n\t\t\tSystem.out.printf(\"number1 : %d\", number1).println();\n\t\t\tSystem.out.printf(\"number2 : %d\", number2).println();\n\t\t\tSystem.out.printf(\"choice : %d\", choice).println();\n\t\t\t\n\t\t\tif(choice == 1) {\n\t\t\t\tSystem.out.printf(\"result : %d\", number1 + number2).println();\n\t\t\t} else if(choice == 2) {\n\t\t\t\tSystem.out.printf(\"result : %d\", number1 - number2).println();\n\t\t\t} else if(choice == 3) {\n\t\t\t\tSystem.out.printf(\"result : %d\", number1 * number2).println();\n\t\t\t} else if(choice == 4) {\n\t\t\t\tSystem.out.printf(\"result : %d\", number1 / number2).println();\n\t\t\t} else {\n\t\t\t\tSystem.out.println(\"Invalid Operation\");\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n\n**_Console Output_**\n\n_number1 : 5_\n\n_number2 : 2_\n\n_choice : 1_\n\n_result : 7_\n\nNext in line, is an example involving a ```switch```.\n\n##### Snippet-02 : Formatted Output Using ```switch```\n\n**_OperatorChoiceRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.ifstatement.examples;\n\n\tpublic class OperatorChoiceRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tOperatorChoice opChoice = new OperatorChoice(5, 2, 1);\n\t\t\topChoice.operateUsingSwitch();\n\t\t}\n\t}\n\n```\n\n**_OperatorChoice.java_**\n\n```java\n\n\tpackage com.in28minutes.ifstatement.examples;\n\n\tpublic class OperatorChoice {\n\t\tprivate int number1;\n\t\tprivate int number2;\n\t\tprivate int choice;\n\n\t\tpublic OperatorChoice(int number1, int number2, int choice) {\n\t\t\tthis.number1 = number1;\n\t\t\tthis.number2= number2;\n\t\t\tthis.choice = choice;\n\t\t}\n\n\t\tpublic void operateUsingSwitch() {\n\t\t\tSystem.out.printf(\"number1 : %d\", number1).println();\n\t\t\tSystem.out.printf(\"number2 : %d\", number2).println();\n\t\t\tSystem.out.printf(\"choice : %d\", choice).println();\n\n\t\t\tswitch(choice) {\n\t\t\t\tcase 1: System.out.printf(\"result : %d\", number1 + number2).println(); \n\t\t\t\t\tbreak;\n\t\t\t\tcase 2: System.out.printf(\"result : %d\", number1 - number2).println(); \n\t\t\t\t\tbreak;\n\t\t\t\tcase 3: System.out.printf(\"result : %d\", number1 * number2).println(); \n\t\t\t\t\tbreak;\t\t\t\t\n\t\t\t\tcase 4: System.out.printf(\"result : %d\", number1 / number2).println(); \n\t\t\t\t\tbreak;\n\t\t\t\tdefault: System.out.printf(\"result : %d\", number1 + number2).println(); \n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_number1 : 5_\n\n_number2 : 2_\n\n_choice : 1_\n\n_result : 7_\n\n#### Summary\n\nIn this step, we:\n\n* Observed that the same conditional code could be written using an ```if```-family conditional, or the ```switch```.\n* Learned that an ```if``` family conditional is difficult to get wrong, as the rules for it are very strict. It can be used to evaluate only ```boolean``` conditions. But it is verbose, and often less readable.\n* Came to know that a ```switch``` conditional can be used to check for only integer values. It is very compact, and very readable. However, the relative order of ```case``` clauses and ```default``` are not fixed, and the usage of ```break``` is optional. This can lead to subtle errors in your program. \n\n### Step 10: Programming Exercise PE-03\n\n1. Write a Java ```class``` which has the following operations within it:\n\t* Given a number between 0 (Sunday) and 6 (Saturday), return if the day is a Weekday\n\t* Given a number between 1 (January) and 12 (December), return the corresponding English name for that month\n\t* Given a number between 1 (January) and 12 (December), return the corresponding English name for that day of the week\n\n#### Solution to PE-03\n\n**_CalendarSwitchRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.ifstatement.examples;\n\n\tpublic class CalendarSwitchRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tSystem.out.println(determineNameOfDay(1));\n\t\t\tSystem.out.println(isWeekDay(1));\n\t\t\tSystem.out.println(determineMonthOfYear(1));\n\t\t}\n\n\t\tpublic String determineNameOfDay(int dayNumber) {\n\t\t\tswitch(dayNumber) {\n\t\t\t\tcase 0 : return \"Sunday\";\n\t\t\t\t\tbreak;\t\t\t\t\n\t\t\t\tcase 1 : return \"Monday\";\n\t\t\t\t\tbreak;\t\t\t\t\t\n\t\t\t\tcase 2 : return \"Tuesday\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3 : return \"Wednesday\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase 4 : return \"Thursday\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase 5 : return \"Friday\";\n\t\t\t\t\tbreak;\n\t\t\t\tcase 6 : return \"Saturday\";\n\t\t\t\t\tbreak;\n\t\t\t\tdefault : return \"Invalid Day\";\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tpublic String determinenameofMonth(int monthNumber) {\n\t\t\tswitch(monthNumber) {\n\t\t\t\tcase 1 : return \"January\";\n\t\t\t\tcase 2 : return \"February\";\n\t\t\t\tcase 3 : return \"March\";\n\t\t\t\tcase 4 : return \"April\";\n\t\t\t\tcase 5 : return \"May\";\n\t\t\t\tcase 6 : return \"June\";\n\t\t\t\tcase 7 : return \"July\";\n\t\t\t\tcase 8 : return \"August\";\n\t\t\t\tcase 9 : return \"September\";\n\t\t\t\tcase 10 : return \"October\";\n\t\t\t\tcase 11 : return \"November\";\n\t\t\t\tcase 12 : return \"December\";\n\t\t\t\tdefault : return \"Invalid Month\";\n\t\t\t}\n\t\t}\n\n\t\tpublic boolean isWeekDay(int dayNumber) {\n\t\t\tswitch(dayNumber) {\n\t\t\t\tcase 1 : \n\t\t\t\tcase 2 : \n\t\t\t\tcase 3 : \t\n\t\t\t\tcase 4 : \n\t\t\t\tcase 5 : return true;\n\t\t\t\tcase 0 :\n\t\t\t\tcase 6 : \n\t\t\t\tdefault : return false;\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n### Step 12: Introducing ```?:```, The Ternary Operator\n- - - \n\nThe ternary operator ```?:``` is a logical operator, that works on three operands. Its functioning is similar to an ```if```-```else``` statement (Checking for just ```2``` conditions). Exactly one  of the two expressions is guaranteed to match.\n\nConceptually, its syntax is this:\n\n*```result = (condition ? expression-if-condition-true : expression:if-condition-false);```* \n\n##### Snippet-01 : ternary operator \n\n`?:` is easy to use. A few examples below:\n\n```java\n\n\tjshell\u003e boolean isEven;\n\tisEven ==\u003e false\n\tjshell\u003e int i = 6;\n\tjshell\u003e isEven = ( i%2==0 ? true : false);\n\tisEven ==\u003e true\n\tjshell\u003e i = 7;\n\ti ==\u003e 7\n\tjshell\u003e isEven = ( i%2==0 ? true : false);\n\tisEven ==\u003e false\n```\n\nYou can return non boolean values.\n```java\n\tjshell\u003e String ifEven = ( i%2==0 ? \"YES\" : \"NO\");\n\tifEven ==\u003e \"NO\"\n\tjshell\u003e i = 6;\n\ti ==\u003e 6\n\tjshell\u003e ifEven = ( i%2==0 ? \"YES\" : \"NO\");\n\tifEven ==\u003e \"YES\"\n```\n\nBoth the expressions should return value of same type.\n\n```java\n\tjshell\u003e ifEven = ( i%2==0 ? \"YES\" : 4 );\n\t| Error:\n\t| incompatible types: bad type in conditional expression\n\t| int cannot be converted to java.lang.String\n\t| ifEven = ( i%2==0 ? \"YES\" : 4 );\n\t|_____________________________^\n\tjshell\u003e ifEven = ( i%2==0 ? \"YES\" : true );\n\t| Error:\n\t| incompatible types: bad type in conditional expression\n\t| boolean cannot be converted to java.lang.String\n\t| ifEven = ( i%2==0 ? \"YES\" : true );\n\t|_____________________________^\n\tjshell\u003e\n\n```\n\n\n#### Summary\n\nIn this step, we:\n\n* Discovered a more compact Java conditional, the ```?:``` operator\n* Saw that in most cases it behaves like an ```if```-```else``` construct\n\n## Loops\n\nTODO \n\n### Revisiting Java loop constructs: ```for``` and ```while```\n\nIf you may recall, the structure of a ```for``` loop is:\n\n```for(initialization; condition; update) {```\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;```//\u003cStatements Body\u003e```\n\n```}``` \n\nThe ```\u003cStatements Body\u003e``` inside the loop is executed so long as the ```condition``` is ```true```. Let's look at a few puzzles to explore how we can utilize them.\n##### Snippet 1 : First for loop puzzle\n\n**jshell\u003e**```for(int i=0; i \u003c= 10; i++) {```\n\n__**...\u003e\u003e**```System.out.print(i + \" \");```\n\n__**...\u003e\u003e**```}```\n\n_0 1 2 3 4 5 6 7 8 9 10_\n\n**jshell\u003e**```for(int i=0; i \u003c= 10; i = i+2) {```\n\n__**...\u003e\u003e**```System.out.print(i + \" \");```\n\n__**...\u003e\u003e**```}```\n\n_0 2 4 6 8 10_\n\n**jshell\u003e**```for(int i=1; i \u003c= 10; i = i+2) {```\n\n__**...\u003e\u003e**```System.out.print(i + \" \");```\n\n__**...\u003e\u003e**```}```\n\n_1 3 5 7 9_\n\n\n**jshell\u003e**```for(int i=11; i \u003c= 10; i = i+2) {```\n\n__**...\u003e\u003e**```System.out.print(i + \" \");```\n\n__**...\u003e\u003e**```}```\n\n\n**jshell\u003e**```for(int i=11; i \u003c= 20;) {```\n\n__**...\u003e\u003e**```System.out.print(i + \" \");```\n\n__**...\u003e\u003e**```i++;```\n\n__**...\u003e\u003e**```}```\n\n_11 12 13 14 15 16 17 18 19 20_\n\n**jshell\u003e**```int i = 20;```\n\n_i ==\u003e 20_\n\n**jshell\u003e**```for(i \u003c= 30; i++) {```\n\n__**...\u003e\u003e**```System.out.print(i + \" \");```\n\n__**...\u003e\u003e**```}```\n\n_21 22 23 24 25 26 27 28 29 30_\n\n**jshell\u003e**\n\n##### Snippet-1 Explained\n\nAll the three control components of a ```for``` loop are dispensable\n\n* ```initialziation```\n* ```condition```\n* ```update```\n- - -\n\n## Reference Types\n\n### Step 01: Introducing Reference Types\n\nWhat happens in the background when we create objects?\n\n```java\n\n\tjshell\u003e class Planet {\n\t..\u003e\u003e}\n\t| created class Planet\n\tjshell\u003e Planet jupiter = new Planet();\n\tjupiter ==\u003e Planet@31a5c39e\n```\n\nWhere is the object `jupiter` stored?\n\nAll Java objects are created on the `Heap` or `Heap Memory`. \n\nWhen we create an new instance of `Planet', it is created on the Heap.\n\n\n```java\n\tjshell\u003e new Planet()\n\t$18 ==\u003e Planet@3f49dace\n```\n\n`new Planet()` creates an object on the Heap. In above example `Planet@3f49dace`, the object is stored on the Heap at address `3f49dace`.\n\n\n```java\n\tjshell\u003e Planet jupiter = new Planet();\n\tjupiter ==\u003e Planet@31a5c39e\n```\n\n`Planet jupiter = new Planet()` does two things.\n- Creates an object on the Heap `new Planet()`. In above example, object is created at Heap location `31a5c39e`\n- Stores the reference of the object on the Heap in a variable `jupiter`. In above example, `31a5c39e` is the value stored in variable `jupiter`. That's the memory location where the new object was created.\n\nLet's consider another example.\n\n```java\n\tjshell\u003e class Animal {\n\t   ..\u003e\u003e int id;\n\t   ..\u003e\u003e public Animal(int id) {\n\t   ..\u003e\u003e this.id = id;\n\t   ..\u003e\u003e }\n\t   ..\u003e\u003e }\n\t| created class Animal\n\tjshell\u003e Animal dog = new Animal(12);\n\tdog ==\u003e Animal@27c20538\n\tjshell\u003e Animal cat = new Animal(15);\n\tcat ==\u003e Animal@6e06451e\n\tjshell\u003e\n\n```\n\nTwo new `Animal` objects are created on the `Heap`. Their memory locations (`references`) are stored in the reference variables - `dog` and `cat`.\n\nIn Java, all classes are also called Reference Types. Except for primitive variable instances, all the instances or objects are stored on the Heap. The references to the objects are stored in the reference variables like `jupiter`, `dog` and `cat`.\n\n#### Summary\n\nIn this step, we:\n\n* Looked at what references are\n* Had a look at what the contents of a reference variable look like\n\n### Step 02: References: Usage And Puzzles\n\nLet's spend some time playing with reference variables.\n\nReferences that are not initialized by the programmer, are initialized by the Java compiler to ```null```. ```null``` is a special value that stands for an **empty location**. In other words, the ```Animal``` ```nothing``` refers to nothing!\n\n```java\n\n\tjshell\u003e class Animal {\n\t   ..\u003e\u003e int id;\n\t   ..\u003e\u003e public Animal(int id) {\n\t   ..\u003e\u003e this.id = id;\n\t   ..\u003e\u003e }\n\t   ..\u003e\u003e };\n\t| created class Animal\n\tjshell\u003e Animal nothing;\n\tnothing ==\u003e null\n\n```\n\nAssigning the reference ```cat``` to ```nothing``` does what one would expect: it assigns the address of the object created with ```new Animal(15)``` (stored in ```cat```), to the variable ```nothing```.\n\n```java\n\tjshell\u003e Animal dog = new Animal(12);\n\tdog ==\u003e Animal@27c20538\n\tjshell\u003e Animal cat = new Animal(15);\n\tcat ==\u003e Animal@6e06451e_\n\n\tjshell\u003e nothing = cat;\n\tnothing ==\u003e 6e06451e\n```\n\n`nothing` and `cat` are pointing to the same location on the 'Heap'. When we do `nothing.id = 10` we are changing the `id` of the object pointed to by both `nothing` and `cat`.\n\n```java\n\tjshell\u003e nothing.id = 10;\n\t$1 =\u003e 10\n\tjshell\u003e cat.id\n\t$2 =\u003e 10\n```\n\nLet's change `nothing` to point to the same object referenced by `dog`.\n\n```java\n\tjshell\u003e nothing = dog;\n\tdog ==\u003e 27c20538\n\tjshell\u003e nothing.id;\n\t$3 =\u003e 12\n\tjshell\u003e\n\n```\n\nYou can `nothing.id` prints the value of the object referenced by `dog` because they are pointing to the same object.\n\nHere are couple of important things to note:\n\n* `nothing = dog` - Assignment between references does not copy the entire referenced object. It only copies the reference. After an assignment, both reference variables point to the same object. \n* `nothing.id = 10` - References can be used to modify the objects they reference.\n\n#### Comparing Reference Variables\n\nLet's look at an example.\n\nWith primitive variables, assignment copies values.\n\n```java\n\n\tjshell\u003e int i =5;\n\ti ==\u003e 5\n\tjshell\u003e int j;\n\tj ==\u003e 0\n\tjshell\u003e j = i;\n\tj ==\u003e 5\n\tjshell\u003e j = 6;\n\tj ==\u003e 6\n\tjshell\u003e i;\n\ti ==\u003e 5\n```\n`j = i` copies the value of `i` into `j`. Later, when value of `j` is changed, `i` is not affected.\n\nComparing primitive variables compares their values.\n\n```java\n\tjshell\u003e i == j;\n\t$4 ==\u003e false\n\tjshell\u003e j = 5;\n\tj ==\u003e 5\n\tjshell\u003e i == j;\n\t$5 ==\u003e true\n```\n\n\nLet's create a few reference variables.\n\n```java\n\tjshell\u003e Animal dog = new Animal(12);\n\tdog ==\u003e Animal@4b952a2d\n\tjshell\u003e Animal cat = new Animal(10);\n\tcat ==\u003e Animal@3159c4b8\n\tjshell\u003e Animal ref = cat;\n\tref ==\u003e Animal@3159c4b8\n\tjshell\u003e Animal dog2 = new Animal(12);\n\tdog ==\u003e Animal@29ca901e_\n```\n\nWhen we compare reference variables, we are still comparing values. But the values are references - the address of memory locations where objects are stored. The values stored inside the referenced objects are not used for comparison.\n\nBoth ```cat``` and ```ref``` reference a single ```Animal``` object created using ```new Animal(10)```. `==` returns true\n```java\n\tjshell\u003e cat == dog;\n\t$6 ==\u003e false\n\tjshell\u003e cat == ref;\n\t$7 ==\u003e true\n```\n\nThe comparison ```dog == dog2``` evaluates to ```false``` since the references i.e. memory locations pointed by these variables are different. They have the same values for ```id``` field (```12```). But, that is not important!\n\n```java\n\tjshell\u003e dog == dog2;\n\t$8 ==\u003e false\n\tjshell\u003e\n\n```\n\n\n\n#### Summary\n\nIn this step, we:\n\n* Understood the way reference variables behave during initialization and assignment\n* Saw the relevance of a ```null``` value for references\n* Observed how equality of references, is different from equality of values of primitive types\n\n### Step 03: Introducing ```String```\n\nA sequence of characters, such as ```\"Hello\"```, ```\"qwerty\"``` and ```\"PDF\"``` is very different from other pieces of data. \n\nIn Java, a sequence of characters is typically represented by ```String``` ```class```.\n\n```String``` provides several built-in utility methods. \n\nLet's look at a few examples.\n\n```java\n\n\tjshell\u003e \"Test\".length()\n\t$1 ==\u003e 4\n```\n```\"Test\"``` is a string literal, so the compiler internally creates an object, gives it the type ```String``` and allocates memory for it. Since ```length()``` is a method of ```String```, it can be invoked on this ```\"Test\"``` object.\n\n\n\nIn the example below, ```str``` is a reference to a ```String``` object, containing the value ```\"Test\"```. Creating a ```String``` object is an exception to how we typically create objects in Java. You don't need to make a ```String``` constructor call. Contrast this with how we would create a ```BigDecimal``` object.\n```java\n\tjshell\u003e String str = \"Test\";\n\tstr ==\u003e \"Test\"\n\tjshell\u003e BigDecimal bd = new BigDecimal(\"1.0\");\n\tbd ==\u003e 1.0\n```\n\nString indexes, like those of arrays, start at ```0```. The ```charAt(int)``` method takes an index value as its argument, and returns the character symbol present at that index.\n\n```java\n\tjshell\u003e str.charAt(0)\n\t$2 ==\u003e 'T'\n\tjshell\u003e str.charAt(2)\n\t$3 ==\u003e 's'\n\tjshell\u003e str.charAt(3)\n\t$4 ==\u003e 't'\n```\nThe ```substring()``` method returns a ```String``` reference, and has overloaded versions:\n* The ```substring(int, int)``` method returns the sequence of character symbols starting at the lower index, and ending just before the upper index. \n* The ```substring(int)``` method returns the sequence of character symbols starting from the index to end of string.\n\n```java\n\tjshell\u003e String biggerString = \"This is a lot of text\";\n\tbiggerString ==\u003e \"This is a lot of text\"\n\tjshell\u003e biggerString.substring(5)\n\t$5 ==\u003e \"is a lot of text\"\n\tjshell\u003e biggerString.substring(5, 13)\n\t$6 ==\u003e \"is a lot\"\n\tjshell\u003e biggerString.charAt(13)\n\t$7 ==\u003e ' '\n\tjshell\u003e\n\t\n```\n\n\n#### Summary\n\nIn this step, we:\n\n* Were introduced to the ```String``` class, that represents sequences of characters\n* Explored a few utility methods of the ```String``` class\n\n### Step 04: Programming Exercise PE-01, And ```String``` Utilities\n\n#### Exercise\n\n1. Write a method to print the individual characters of a given text string, separately.\n\n#### Solution To PE-01\n\n```java\n\n\tjshell\u003e String text = \"Equation\";\n\t   ..\u003e\u003e for (int i=0; i \u003c text.length(); i++) {\n\t   ..\u003e\u003e System.out.println(text.charAt(i));\n\t   ..\u003e\u003e }\n\tE\n\tq\n\tu\n\ta\n\tt\n\ti\n\to\n\tn\n\tjshell\u003e\n\t\n```\n\n#### Common ```String``` Utilities\n\nThe ```String``` class is part of the built-in ```java.lang``` package. It provides several methods for common text processing. Let's have a peek at some of them, shall we? \n\n##### Snippet-01: ```String``` Utilities \n\n\nHere are a few of the methods used in the examples below:\n* ```indexOf()``` : Has two overloaded versions. ```indexOf(char)``` returns the position where a character occurs in a string, the first time. ```indexOf(String)``` returns the starting position where a string occurs within our string, the first time.\n* ```lastIndexOf()``` : Similar in function to ```indexOf()```, but replace \"*first time*\" with \"**final time**\" in its description.\n* ```startsWith()``` : Returns ```true``` if our string starts with the given *prefix*, ```false``` otherwise.\n* ```endsWith()``` : Returns ```true``` if our string ends with the given *suffix*, ```false``` otherwise.\n* ```isEmpty()``` : Returns ```true``` if our string is empty, ```false``` otherwise.\n* ```equals()``` : Returns ```true``` if our string is identical to the argument, ```false``` otherwise.\n* ```equalsIgnoreCase()``` : Returns ```true``` if our string is identical to the argument, ignoring the case of its characters. Will return ```false``` otherwise.\n\n```java\n\n\tjshell\u003e String someString = \"This is a lot of text again\";\n\tsomeString ==\u003e \"This is a lot of text again\"\n\tjshell\u003e someString.indexOf(\"lot\")\n\t$1 ==\u003e 10\n\tjshell\u003e someString.charAt(10)\n\t$2 ==\u003e 'l'\n\tjshell\u003e someString.indexOf('i')\n\t$3 ==\u003e 2\n\tjshell\u003e someString.lastIndexOf('i')\n\t$4 ==\u003e 25\n\tjshell\u003e someString.contains(\"text\")\n\t$5 ==\u003e true\n\tjshell\u003e someString.startsWith(\"This\")\n\t$6 ==\u003e true\n\tjshell\u003e someString.startsWith(\"jfsdklfj\")\n\t$7 ==\u003e false\n\tjshell\u003e someString.endsWith(\"in\")\n\t$7 ==\u003e true\n\tjshell\u003e someString.endsWith(\"ain\")\n\t$8 ==\u003e true\n\tjshell\u003e someString.endsWith(\"gain\")\n\t$9 ==\u003e true\n\tjshell\u003e someString.endsWith(\"againasdf\")\n\t$10 ==\u003e false\n\tjshell\u003e someString.isEmpty()\n\t$11 ==\u003e false\n\tjshell\u003e \"\".isEmpty()\n\t$12 ==\u003e true\n\tjshell\u003e \"true\".equals(\"true\")\n\t$13 ==\u003e true\n\tjshell\u003e String str = \"value\";\n\tstr ==\u003e \"value\"\n\tjshell\u003e str.equals(\"value\")\n\t$14 ==\u003e true\n\tjshell\u003e str.equals(\"VALUE\")\n\t$15 ==\u003e false\n\tjshell\u003e str.equalsIgnoreCase(\"VALUE\")\n\t$16 ==\u003e true\n\tjshell\u003e\n\n```\n\n\n#### Summary\n\nIn this step, we:\n\n* Used our ```String``` programming skills on a small challenge.\n* Explored a set of simple, yet useful ```String``` utilities.\n\n### Step 05: ```String``` Immutability\n\nWhat picture forms in your mind on hearing the word \"**immutable**\"? Someone whose voice cannot be muted out? Or is it the other way round? \n\nThe word \"immutable\" is related to the concept of \"mutability\", or the possibility of \"mutating\" something. \n\n\"**mutate**\" means \"**to change**\". \"Immutable\" refers to something that \"**cannot be changed**\". \n\n```String``` objects are immutable. You cannot change their value after they are created.\n\nThe method ```concat()```joins the contents of two ```String``` objects into one. \n\n```java\n\n\tjshell\u003e String str = \"in28Minutes\";\n\tstr ==\u003e \"in28Minutes\"\n\tjshell\u003e str.concat(\" is awesome\")\n\t$1 ==\u003e \"in28Minutes is awesome\"\n```\n\nHowever, the original value referred by `str` remains unchanged. The `concat` method create a new `String` object.\n\n```\n\tjshell\u003e str\n\tstr ==\u003e \"in28Minutes\"\n```\n\nJust like ```concat()```, other ```String``` methods such as ```toUpperCase()```, ```toLowerCase()``` and ```trim()``` return new ```String``` objects.\n\n```java\n\n\tjshell\u003e String anotherString = str.concat(\" is awesome\");\n\tanotherString ==\u003e \"in28Minutes is awesome\"\n\tjshell\u003e str\n\tstr ==\u003e \"in28Minutes\"\n\tjshell\u003e String string2 = anotherString.concat(\".\");\n\tstring2 ==\u003e \"in28Minutes is awesome.\"\n\tjshell\u003e str\n\tstr ==\u003e \"in28Minutes\"\n\tjshell\u003e anotherString\n\tanotherString ==\u003e \"in28Minutes is awesome\"\n\tjshell\u003e String s= \"in28Minutes is awesome.\"\n\ts ==\u003e \"in28Minutes is awesome.\"\n\tjshell\u003e s.toUpperCase()\n\ts ==\u003e \"IN28MINUTES IS AWESOME.\"\n\tjshell\u003e s.toLowerCase()\"\n\ts ==\u003e \"in28minutes is awesome.\"\n\tjshell\u003e String str2= \"  in28Minutes is awesome    \"\n\tstr2 ==\u003e \"  in28Minutes is awesome    \"\n\tjshell\u003e str2.trim()\n\tstr2 ==\u003e \"in28Minutes is awesome\"\n\tjshell\u003e\n\n```\n\n#### Summary\n\nIn this step, we:\n\n* We understood that ```String``` objects are immutable\n* Observed how common ```String``` utilities return a new String. \n\n### Step 06:  More ```String``` Utilities\n\nThe symbol ```+``` denotes addition, and addition only, right? Any school kid will tell you that, or laugh at you if you disagree. \n\nHeck, we even saw how to use it with the primitive numeric types, such as ```int```, ```double``` and others related to it.\n\nJava does not strictly follow your arithmetic text book. \n\n```+``` can also be used as a ```String``` concatenation operator.\n\nHere is how ```+``` works\n* if both operands of ```+``` are numeric,  then arithmetic ```+``` (addition) is performed.\n* If any one of the operators is a ```String```, then string concatenation is performed.\n\n\n```java\n\n\tjshell\u003e 1 + 2\n\t$1 ==\u003e 3\n\tjshell\u003e \"1\" + \"2\"\n\t$2 ==\u003e \"12\"\n\tjshell\u003e \"1\" + 2\n\t$3 ==\u003e \"12\"\n\tjshell\u003e \"1\" + 23\n\t$4 ==\u003e \"123\"\n\tjshell\u003e 1 + 23\n\t$5 ==\u003e 24\n\tjshell\u003e \"1\" + 2 + 3\n\t$6 ==\u003e \"123\"\n\tjshell\u003e 1 + 2 + \"3\"\n\t$7 ==\u003e \"33\"\n```\n\nIn the example below, a different value is printed when parentheses are used around `i + 20`.\n\n```java\n\tjshell\u003e int i = 20;\n\ti ==\u003e 20\n\tjshell\u003e System.out.println(\"Value is \" + i);\n\tValue is 20\n\tjshell\u003e System.out.println(\"Value is \" + i + 20);\n\tValue is 2020\n\tjshell\u003e System.out.println(\"Value is \" + (i + 20));\n\tValue is 40\n```\n\n```join()``` is used to join a set of `String` values.\n\n```java\n\tjshell\u003e String.join(\",\", \"2\", \"3\", \"4\");\n\t$8 ==\u003e \"2,3,4\"\n```\n\n```replace(String, String)```replaces all occurrences of the first sub-string with the second one. It also works with `char` data type.\n\n```java\n\tjshell\u003e \"abcd\".replace('a', 'z');\n\t$9 ==\u003e \"zbcd\"\n\tjshell\u003e \"abcd\".replace(\"ab\", \"xyz\");\n\t$10 ==\u003e \"xyzcd\"\n\tjshell\u003e\n\n```\n\n\n#### Summary\n\nIn this step, we:\n\n* Learned that the ```+``` operator is overloaded for ```String``` concatenation\n* Observed how ```+``` interprets its operands, depending on the context\n* Noticed a few more ```String``` utility methods, such as ```join()``` and ```replace()```\n\n### Step 07: Storing mutable text\n\n```StringBuffer``` and ```StringBuilder``` allow you to modify a string literal in-place. \n\n```java\n\n\tjshell\u003e \"123\" + \"123\" + \"1234\" + \"12345\"\n\t$1 ==\u003e \"123123123412345\"\n\tjshell\u003e StringBuffer sb = new StringBuffer(\"TEst\");\n\tsb ==\u003e \"TEst\"\n\tjshell\u003e sb.append(\" 123\");\n\t$2 ==\u003e \"TEst 123\"\n\tjshell\u003e sb\n\tsb ==\u003e \"TEst 123\"\n\tjshell\u003e sb.setCharAt(1, 'e');\n\tsb ==\u003e \"Test 123\"\n\tjshell\u003e StringBuilder sbldr = new StringBuffer(\"TEst\");\n\tsbldr ==\u003e \"TEst\"\n\tjshell\u003e\n\n```\nHow do you choose which one to use?\n* `StringBuffer` is thread safe. If you are writing a multi threaded program(more on this in a later section), use ```StringBuffer```.\n* Otherwise, use ```StringBuilder```, since it offers better performance in both execution-time and memory usage.\n\n#### Summary\n\nIn this step, we:\n\n* Learned about ```StringBuffer``` and ```StringBuilder```\n\n### Step 08: Introducing Wrapper Classes\n\nEach primitive type in Java has a corresponding built-in **wrapper class**. Wrapper classes are also immutable (As well as ```final```, more on this a little later). \n\nFollowing is a list of built-in Java wrapper classes and their corresponding primitive types:\n* ```byte``` : ```Byte```\n* ```short``` : ```Short```\n* ```int``` : ```Integer```\n* ```long``` : ```Long```\n* ```float``` : ```Float```\n* ```double``` : ```Double```\n* ```char``` : ```Character```\n* ```boolean``` : ```Boolean```\n\nThe main incentives of using such wrappers in your code, are:\n* Accessing type information about the corresponding primitive type\n* Auto-Boxing feature, where a primitive data is automatically promoted to an object  reference type\n* Moving primitive type data around data structures (called *collections*), using their wrapper-style counterparts\n\nLet's look at these incentives in the next step.\n\n#### Summary\n\nIn this step, we:\n\n* Were introduced to the wrapper classes available for the primitive types\n* Learned about the advantages of having them around\n\n### Step 09: Creating Wrapper Objects\n\nNow that we know what wrapper classes are, and which ones correspond to each primitive Java type, let's try them out.\n\nCreating instance of Wrapper Classes using `new` is simple. Examples below.\n\n```java\n\n\tInteger hundred = new Integer(\"100\");\n\tBoolean b1 = new Boolean(\"true\"); //true\n\tBoolean b1 = new Boolean(\"True\"); //true\n\tBoolean b1 = new Boolean(\"false\"); //false\n\tBoolean b1 = new Boolean(\"False\"); //false\n\tBoolean b1 = new Boolean(\"other arbitrary string\"); //false\n\n```\n\nYou can also use ```valueOf()``` method within types such as ```Integer``` and ```Float``` to create a wrapper object. \n\n```java\n\n\tFloat floatWrapper = Float.valueOf(57.0f);\n\tint floatToInt = floatWrapper.intValue(); // 57\n\tInteger seven = Integer.valueOf(\"111\", 2);\n\tInteger.toString(seven, 2);\n\n```\n\n#### Difference between creating wrapper objects using valueOf and new\n\nThe ```Integer.valueOf()``` reuses existing ```Integer``` objects with same value on the heap. If an object with same value is present in the heap, it returns a reference to existing object. Otherwise, it returns a reference of a newly created ```Integer``` object.\n\nWrapper classes are immutable. Hence, above approach is efficient and accurate.\n\n```java\n\n\tjshell\u003e Integer integer1 = new Integer(5);\n\tinteger1 ==\u003e 5\n\tjshell\u003e Integer integer2 = new Integer(5);\n\tinteger2 ==\u003e 5\n\tjshell\u003e Integer integer3 = Integer.valueOf(5);\n\tinteger3 ==\u003e 5\n\tjshell\u003e Integer integer4 = Integer.valueOf(5);\n\tinteger4 ==\u003e 5\n\tjshell\u003e integer1 == integer2\n\t$1 ==\u003e true\n\tjshell\u003e integer3 == integer4\n\t$2 ==\u003e true\n\tjshell\u003e\n\n```\n#### Summary \n\nIn this step, we:\n\n* Discovered that there are two ways to create a wrapper object for primitive data\n* Learned that ```valueOf()``` takes advantage of immutability, to improve efficiency\n\n### Step 10: Auto-Boxing, And Some Wrapper Constants\n\n**Auto-Boxing** is an example of **syntactic sugar** in the Java language. It does not provide new features but makes code more readable. \n\nAuto-boxing reuses the mechanism provided by ```Integer.valueOf()``` for ```Integer```, ```Float``` and others.\n\n\n\n```java\n\n\tjshell\u003e Integer seven = Integer.valueOf(7000);\n\tseven ==\u003e 7000\n\tjshell\u003e Integer sevenToo = 7000;\n\tsevenToo ==\u003e 7000\n\tjshell\u003e Integer sevenAgain = 7000;\n\tsevenAgain ==\u003e 7000\n\tjshell\u003e sevenToo == sevenAgain\n\t$1 ==\u003e true\n```\n\nIn the above example, \t`Integer sevenToo = 7000` uses auto boxing. We are upgrading a `int` literal to a `Integer` value. This is done implicitly by using `Integer.valueOf` method.\n\nThere are constants available on Wrapper classes print the size of their variables and the range of values they can store.\n\n```\n\tjshell\u003e Integer.MAX_VALUE\n\t$2 ==\u003e 2147483647\n\tjshell\u003e Integer.MIN_VALUE\n\t$3 ==\u003e -2147483648\n\tjshell\u003e Integer.SIZE\n\t$4 ==\u003e 32\n\tjshell\u003e Integer.BYTES\n\t$5 ==\u003e 4\n\tjshell\u003e\n\n```\n\n\n#### Summary\n\nIn this step, we:\n\n* Understood the mechanism of auto-boxing, which uses the assignment operator route\n* Understood how auto-boxing internally makes use of ```valueOf()``` method\n\n### Step 11: The Java ```Date``` API\n\nNo  discussion on the built-in Java primitive and reference types is complete without an exploration of the Date API. \n\nBefore Java SE 8, there were a lot of practical issues regarding the interface and implementation of the ```Date``` class.\n\nFrom Java 8, Java provided an API for `Date` classes based on the Joda Date Framework. \n\nThe three most significant classes within this framework are : ```LocalDate```, ```LocalTime``` and ```LocalDateTime```. \n\n##### Snippet-01 : java.time utilities\n\n```java.time.*``` is not imported automatically by Jshell.  Let's import it in. \n\nThe commonly used utilities to access current values of date and time are:\n* ```LocalDate.now()``` : Returns the current date value in readable format\n* ```LocalTime.now()``` : Returns the current time value in a readable format\n* ```LocalDateTime.now()``` : Returns a combination of the current date and time values, in a readable format   \n\n```java\n\n\tjshell\u003e import java.time.LocalDate\n\tjshell\u003e LocalDate now = LocalDate.now()\n\tnow ==\u003e 2018-02-01\n\tjshell\u003e import java.time.*\n\tjshell\u003e LocalDateTime now = LocalDateTime.now()\n\tnow ==\u003e 2018-02-01T15:50:48.423164\n\tjshell\u003e LocalTime now = LocalTime.now()\n\tnow ==\u003e 15:51:09.642001\n\tjshell\u003e\n\n```\n\n#### Summary\n\nIn this step, we:\n\n* Were introduced to the Java Date API, available through the ```java.time``` package\n* Saw how to use the ```LocalDate```, ```LocalTime``` and ```LocalDateTime``` types\n\n### Step 12: Playing With ```java.time.LocalDate```\n\nWe've been looking at calendars right from childhood, haven't we! How about playing around with a digital calendar? \n\n`LocalDate` provides a number of methods to retrieve \n* Date information: Day/Month/Year and related attributes\n* Date meta-information: Classification-related information, such as whether a leap year, etc.\n\n\n```java\n\n\tjshell\u003e import java.time.*\n\tjshell\u003e import java.time.*\n\tjshell\u003e LocalDate today = LocalDate.now()\n\ttoday ==\u003e 2018-02-01\n\tjshell\u003e today.getYear()\n\t$1 ==\u003e 2018\n\tjshell\u003e today.getDayOfWeek()\n\t$2 ==\u003e THURSDAY\n\tjshell\u003e today.getDayOfMonth()\n\t$3 ==\u003e 01\n\tjshell\u003e today.getDayOfYear()\n\t$4 ==\u003e 32\n\tjshell\u003e today.getMonth()\n\t$5 ==\u003e FEBRUARY\n\tjshell\u003e today.getMonthValue()\n\t$6 ==\u003e 2\n\tjshell\u003e today.isLeapYear()\n\t$7 ==\u003e false\n\tjshell\u003e today.lengthOfYear()\n\t$8 ==\u003e 365\n\tjshell\u003e today.lengthOfMonth()\n\t$9 ==\u003e 28\n```\n\n```LocalDate``` is also immutable. You can use different methods provided to add and subtract days, months and years. Each of these return a new instance of ```LocalDate```.\n\n```java\n\tjshell\u003e today.plusDays(100)\n\t$10 ==\u003e 2018-05-12\n\tjshell\u003e today.plusMonths(100)\n\t$11 ==\u003e 2026-06-01\n\tjshell\u003e today.plusYears(100)\n\t$12 ==\u003e 2118-02-01\n\tjshell\u003e today.minusYears(100)\n\t$13 ==\u003e 1918-02-01\n\tjshell\u003e LocalDate yesteryear = today.minusYears(100)\n\tyesterYear ==\u003e 1918-02-01\n\tjshell\u003e today\n\ttoday ==\u003e 2018-02-01\n\tjshell\u003e\n\n```\n\n```LocalDateTime``` extends ```LocalDate``` and provides time component as well. You can access, and perform arithmetic on the hours, minutes, seconds and nanoseconds values.\n\n#### Summary\n\nIn this step, we:\n\n* Saw common utilities that the ```LocalDate``` ```class``` provides\n* Learned that ```LocalDate```, ```LocalTime``` and ```LocalDateTime``` are all immutable\n\n### Step 13: Comparing ```LocalDate``` Objects\n\nYou can take a look at additional utility methods in ```LocalDate``` in examples below:\n\n```java\n\n\tjshell\u003e LocalDate today = LocalDate.now()\n\ttoday ==\u003e 2018-02-01\n\tjshell\u003e LocalDate yesterday = LocalDate.of(2018, 01, 31)\n\tyesterday ==\u003e 2018-01-31\n\tjshell\u003e today.withYear(2016)\n\t$1 ==\u003e 2016-02-01\n\tjshell\u003e today.withDayOfMonth(20)\n\t$2 ==\u003e 2018-02-20\n\tjshell\u003e today.withMonth(3)\n\t$3 ==\u003e 2018-03-01\n\tjshell\u003e today.withDayOfYear(3)\n\t$4 ==\u003e 2018-04-30\n```\n\nYou can also compare dates using the methods shown below:\n\n```java\n\tjshell\u003e today.isBefore(yesterday)\n\t$5 ==\u003e false\n\tjshell\u003e today.isAfter(yesterday)\n\t$6 ==\u003e true\n\tjshell\u003e\n\t\n```\n\nThese methods are also available with ```LocalTime``` and ```LocalDateTime``` classes as well.\n\n## Arrays and ArrayList\n\nWe will use the following exercise to understand heavily used data structures of Java - Arrays and \n`ArrayList`.\n\nWe would like to model a student report card in a Java program, which allows the user to do stuff such as:\n\n```java\n\n\tStudent student - new Student(name, list-of-marks);\n\tint number = student.getNumberOfmarks();\n\tint sum = student.getTotalSumOfMarks();\n\tint maximumMark = student.getMaximumMark();\n\tint minimumMark = student.getMinimumMark();\n\tBigDecimal average = student.getAverageMarks();\n\tstudent.addMark(35);\n\tstudent.removeMarkAtIndex(5);\n\n```\n\nA data structure like array and `ArrayList` allow you to store multiple object of the same kind. These are called **aggregates**. \n\n\n### Step 01: The Need For ```Array```\n\nLet's start with understanding the need for arrays.\n\nConsider the example below. We are creating 3 marks and adding them.\n\n```java\n\n\tjshell\u003e int mark1;\n\tmark1 ==\u003e 0\n\tjshell\u003e mark1 = 100;\n\tmark1 ==\u003e 10\n\tjshell\u003e int mark2 = 75;\n\tmark2 ==\u003e 75\n\tjshell\u003e int mark3 = 60;\n\tmark3 ==\u003e 60\n\tjshell\u003e int sum = mark1 + mark2 + mark3;\n\tsum ==\u003e 235\n\tjshell\u003e int mark4 =7 56;\n\tmark4 ==\u003e 56\n\tjshell\u003e sum = mark1 + mark2 + mark3 + mark4;\n\tsum ==\u003e 291\n\tjshell\u003e\n\n```\n\nIf an additional mark component ```mark4``` is added to the existing list of marks ```mark1```, ```mark2``` and ```mark3```, the code for computing ```sum``` needs to change. \n\nAll these marks are similar. How about creating a group of marks and storing it as part of single variable?\n\nLet's create an array - `marks`\n\n```java\n\n\tjshell\u003e int[] marks = {75, 60, 56};\n\tmarks ==\u003e int[3]{ 75,60,56 }\n```\nIn above example\n* ```marks``` is an ```array```. \n* `marks` stores multiple ```int``` values.\n* `marks` array has 3 values\n\nIn an array, the index runs from 0 to (length of array - 1). In above example, the index runs from 0 to 2. \n\nYou can use an index to find the specific element from the array. It is done by using the indexing operator, '```[]```'. The expression ```marks[0]``` maps to the first array element stored at index ```0``` of the array ```marks```.\n\n\n```java\njshell\u003e marks[0]\n$20 ==\u003e 75\n\njshell\u003e marks[1]\n$21 ==\u003e 60\n\njshell\u003e marks[2]\n$22 ==\u003e 56\n```\n\nHow do we write code to sum all values in marks array?\n\n```java\n\n\tjshell\u003e int sum = 0;\n\tsum ==\u003e 0\n\tjshell\u003e for(int mark:marks) {\n\t   ..\u003e\u003e sum = sum + mark;\n\t   ..\u003e\u003e }\n\tjshell\u003e sum\n\tsum ==\u003e 191\n\tjshell\u003e\n\n```\n\nAbove construct is called Enhanced ```for``` loop.\n\n```mark``` is the loop control variable. Its type needs to match the type of an array elements, which is ```int```.\n\nAbove ```for``` loop can be used irrespective of the number of elements in `marks` array.\n\n### Step 02:  Storing And Accessing Array Values\n\nLet's dig deeper into arrays in this step.\n\nAn array can be used to store zero or more number of elements. \n\n```java\n\n\tjshell\u003e int[] marks = {1, 2, 3 };\n\tmarks ==\u003e int[3]{ 1,2,3 }\n\tjshell\u003e int[] marks = {1, 2, 3, 4, 5};\n\tmarks ==\u003e int[5]{ 1,2,3,4,5 }\n\tjshell\u003e int[] marks = {1};\n\tmarks ==\u003e int[1]{ 1 }\n\tjshell\u003e int[] marks = {};\n\tmarks ==\u003e int[0]{  }\n```\n\n\nAn array can also be created with ```new``` operator. You've to specify the size of the array.\n```java\n\tjshell\u003e int[] marks2 = new int[5];\n\tmarks2 ==\u003e int[5]{ 0,0,0,0,0 }\n```\n\nYou can use array index to assign values. \n\n`marks2[0] = 10` stores `10` as first element in marks array.\n\n\n```java\n\tjshell\u003e marks2[0]\n\t$1 ==\u003e 0\n\tjshell\u003e marks2[0] = 10;\n\t$2 ==\u003e 10\n\tjshell\u003e marks2[0]\n\t$3 ==\u003e 10\n\tjshell\u003e\n\n```\n  \nSnippet below shows more examples.\n\n```java\n\n\tjshell\u003e int[] marks2 = new int[5];\n\tmarks2 ==\u003e int[5]{ 0,0,0,0,0 }\n\tjshell\u003e marks2[0] = 1;\n\t$1 ==\u003e 1\n\tjshell\u003e marks2[1] = 2;\n\t$2 ==\u003e 2\n\tjshell\u003e marks2[2] = 3;\n\t$3 ==\u003e 3\n\tjshell\u003e marks2[3] = 4;\n\t$4 ==\u003e 4\n\tjshell\u003e marks2[4] = 5;\n\t$5 ==\u003e 5\n\tjshell\u003e marks2\n\tmarks2 ==\u003e int[5]{ 1,2,3,4,5 }\n```\n\n`length` can be used to find the number of elements in the array.\n\n```java\n\tjshell\u003e marks2.length\n\t$6 ==\u003e 5\n\tjshell\u003e int marks3 = {};\n\tmarks3 ==\u003e int[0]{  }\n\tjshell\u003e marks3.length\n\t$7 ==\u003e 0\n\t\n```\n#### Classroom Exercise CE-AA-01\n\n1. Write a program that creates an array ```marks``` to store \t```8``` ```int``` values, and code to iterate through ```marks``` using a ```for``` loop, printing out its values.\n\nHint: Use the ```marks.length``` property\n\n#### Solution To CE-AA-01\n\n```java\n\n\tjshell\u003e int[] marks = {1, 2, 3, 4, 5, 6, 7, 8};\n\tmarks ==\u003e int[8]{ 1,2,3,4,5,6,7,8 }\n\tjshell\u003e marks.length\n\t$1 ==\u003e 8\n\tjshell\u003e for(int i=0; i \u003c marks.length; i++) {\n\t   ..\u003e\u003e System.out.println(marks[i]);\n\t   ..\u003e\u003e }\n\t1\n\t2\n\t3\n\t4\n\t5\n\t6\n\t7\n\t8\n\tjshell\u003e\n\n```\n\n### Step 04: Array Initialization, Data Types And Exceptions\n\nBelow snippet shows how arrays with different types are initialized.\n\nSummary - int - 0, double - 0.0, boolean - false, Any object - null\n\n```java\n\n\tjshell\u003e int[] marks = new int[5];\n\tmarks ==\u003e int[5]{ 0,0,0,0,0 }\n\tjshell\u003e double[] values = new double[5];\n\tvalues ==\u003e double[5]{ 0.0,0.0,0.0,0.0,0.0 }\n\tjshell\u003e boolean[] tests = new boolean[5];\n\ttests ==\u003e boolean[5]{ false,false,false,false,false }\n\tjshell\u003e class Person {\n\t   ..\u003e\u003e}\n\t| created class Person\n\tjshell\u003e Person[] persons = new Person[5];\n\tpersons ==\u003e Person[5]{ null,null,null,null,null }\n\tjshell\u003e\n\n```\n\nLet's look at a few variations of array declarations.\n\nImportant things to Remember\n* The declaration part of an array definition must not include the dimension of the array\n* The assignment part of an array definition must include the dimension of the array\n* All the elements of an array must be of the same, homogeneous type\n\n```java\n\n\tjshell\u003e int[5] marks2;\n\t| Error:\n\t| ']' expected\n\t| int[5] marks2;\n\t|____^\n\tjshell\u003e int[] marks2 = new int[];\n\t| Error:\n\t| array dimension missing\n\t| int[] marks2 = new int[];\n\t|____________^========^\n\tjshell\u003e int[] marks2 = new int[5];\n\tmarks2 ==\u003e int[5]{ 0,0,0,0,0 }\n\tjshell\u003e marks2[6]\n\t| java.lang.ArrayIndexOutOfBoundsException thrown : 6\n\t| at (#54:1)\n\tjshell\u003e int[] marks3 = {1, 2, 3, 4.0};\n\t| Error:\n\t| incompatible types: possible lossy conversion from double to int\n\t| int[] marks3 = {1, 2, 3, 4.0};\n\t|__________________________^-^ \n\tjshell\u003e\n\n```\n\nThe name of an array is a reference variable that stores the address of where the array is created on the heap.\n```java\n\n\tjshell\u003e int[] marks4 = {1, 2, 3, 4, 5};\n\tmarks4 ==\u003e int[5]{ 1,2,3,4,5 }\n\tjshell\u003e System.out.println(marks4);\n\tI@6c49835d\n```\n\nThe built-in method ```Arrays.toString``` can be used to print out elements of an array.\n```java\n\tjshell\u003e System.out.println(Arrays.toString(marks));\n\t[1, 2, 3, 4, 5]\n\tjshell\u003e\n\n```\n\n### Step 05: Array Utilities\n- - - \n\nLet's look at a few examples for\n* Iterating through An Array\n* Bulk-modification of array elements\n* Comparing Arrays\n* Sorting Arrays\n\n##### Snippet-01 : Iterating through an array\n\nUsing an enhanced ```for``` loop is easy and intutive.\n\n```java\n\n\tjshell\u003e int[] marks = {100, 99, 95, 96, 100};\n\tmarks ==\u003e int[5]{ 100,99,95,96,100 }\n\tjshell\u003e for(int mark:marks) {\n\t..\u003e\u003e System.out.println(mark);\n\t..\u003e\u003e }\n\t100\n\t99\n\t95\n\t96\n\t100\n\tjshell\u003e for(int i=0; i \u003c marks.length; i++) {\n\t..\u003e\u003e System.out.println(marks[i]);\n\t..\u003e\u003e }\n\t100\n\t99\n\t95\n\t96\n\t100\n\tjshell\u003e\n\n```\n\n##### Snippet-02 : Filling \u0026 Comparing Arrays\n\n```Array.fill``` fills the entire array with a specified value.\n\n```java\n\n\tjshell\u003e int[] marks = new int[5];\n\tmarks ==\u003e int[5]{ 0,0,0,0,0 }\n\tjshell\u003e Arrays.fill(marks, 100);\n\tjshell\u003e marks\n\tmarks ==\u003e int[5]{ 100,100,100,100,100 }\n```\n\n```Array.equals``` compares two given arrays, and returns a ```boolean``` value of```true``` only if\n* Both arrays are of same length and\n* Elements at each corresponding index are equal, for all indexes\n\n\n```java\n\tjshell\u003e int[] array1 = {1, 2, 3};\n\tarray1 ==\u003e int[3]{ 1,2,3 }\n\tjshell\u003e int[] array2 = {1, 2, 3};\n\tarray2 ==\u003e int[3]{ 1,2,3 }\n\n\tjshell\u003e Arrays.equals(array1, array2);\n\t$1 ==\u003e true\n\n\tjshell\u003e int[] array3 = {3, 2, 3};\n\tarray3 ==\u003e int[3]{ 3,2,3 }\n\tjshell\u003e Arrays.equals(array1, array3);\n\t$2 ==\u003e false\n\n\tjshell\u003e int[] array4 = {1, 2};\n\tarray4 ==\u003e int[2]{ 1,2 }\n\tjshell\u003e Arrays.equals(array1, array4);\n\t$3 ==\u003e false\n```\n\n```Array.sort```: Performs an in-position sorting of elements by comparing pairs of them at a time.\n```java\n\tjshell\u003e Arrays.sort(array3);\n\tjshell\u003e array3\n\tarray3 ==\u003e int[3]{ 2,3,3 }\n\tjshell\u003e\n\n```\n\n### Step 06: Classroom Exercise  CE-AA-02\n\n#### Exercise\n\nArmed with the knowledge of Java arrays and their in-built utility methods, let's now solve the challenge we started off with. \n\n```java\n\n\tStudent student - new Student(name, list-of-marks);\n\tint number = student.getNumberOfmarks();\n\tint sum = student.getTotalSumOfMarks();\n\tint maximumMark = student.getMaximumMark();\n\tint minimumMark = student.getMinimumMark();\n\tBigDecimal average = student.getAverageMarks();\n\n```\n\nWe can implement the aggregate ```list-of-marks``` as an array.\n\n#### Solution To CE-AA-02\n\n**_StudentRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.arrays;\n\n\tpublic class StudentRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tint[] marks = {99, 98, 100};\n\t\t\tStudent student = new Student(\"Ranga\", marks);\n\t\n\t\t\tint number = student.getNumberOfmarks();\t\t\n\t\t\tSystem.out.println(\"Number of marks : \" + number);\t\n\t\t\tint sum = student.getTotalSumOfMarks();\n\t\t\tSystem.out.println(\"Sum of marks : \" + sum);\n\t\n\t\t\tint maximumMark = student.getMaximumMark();\n\t\t\tSystem.out.println(\"Maximum of marks : \" + maximumMark);\n\t\t\tint minimumMark = student.getMinimumMark();\n\t\t\tSystem.out.println(\"Minimum of marks : \" + minimumMark);\n\t\n\t\t\tBigDecimal average = student.getAverageMarks();\n\t\t\tSystem.out.println(\"Average of marks : \" + average);\n\t\t\tstudent.addMark(35);\n\t\t\tstudent.removeMarkAtIndex(5);\n\t\t}\n\t}\n\n```\n\n**_Student.java_**\n\n```java\n\n\tpackage com.in28minutes.arrays;\n\timport java.math.BigDecimal;\n\n\tpublic class Student {\n\t\tprivate String name;\n\t\tprivate int[] marks;\n\n\t\tpublic Student(String name, int[] marks) {\n\t\t\tthis.name = name;\n\t\t\tthis.marks = marks;\n\t\t}\n\n\t\tpublic int getNumberOfMarks() {\n\t\t\treturn marks.length;\n\t\t}\n\n\t\tpublic int getTotalSumOfMarks() {\n\t\t\tint sum = 0;\n\t\t\tfor(int mark:marks) {\n\t\t\t\tsum += mark;\n\t\t\t}\n\t\t\treturn sum;\n\t\t}\n\n\t\tpublic BigDecimal getAverageOfMarks() {\n\t\t\tint sum = getTotalSumOfMarks();\n\t\t\tBigDecimal average = new BigDecimal(sum).divide(new BigDecimal(marks.length), 3, RoundingMode.UP);\n\t\t}\n\n\t\tpublic int getMaximumMark() {\n\t\t\tint max = Integer.MIN_VALUE;\n\t\t\tfor(int mark:marks) {\n\t\t\t\tif(mark \u003e max) {\n\t\t\t\t\tmax = mark;\t\t\t\t\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn max;\n\t\t}\n\n\t\tpublic int getMinimumMark() {\t\n\t\t\tint min = Integer.MAX_VALUE;\n\t\t\tfor(int mark:marks) {\n\t\t\t\tif(mark \u003c min) {\n\t\t\t\t\tmin = mark;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn min;\n\t\t}\n\t}\n\n```\n### Step 08:  Variable Arguments - The Basics\n\nWhat if you want to create a method which can accept variable number of arguments?\n\nLet's look at an example. The critical part is the parameter `int... values`.\n\n```java\n\n\tjshell\u003e class Something {\n\t   ..\u003e\u003e public void doSomething(int... values) {\n\t   ..\u003e\u003e System.out.println(Arrays.toString(values));\n\t   ..\u003e\u003e }\n\t   ..\u003e\u003e };\n\t| created class Something\n```\n\nA typical parameter would've been `int values`. This allows us to pass one parameter to the method.\n\nWhat difference does the three dots `...` make in `int... values`?\n\n```java\n\tjshell\u003e Something thing = new Something();\n\tthing ==\u003e Something@2e465f6a\n\tjshell\u003e thing.doSomething(1);\n\t[1]\n\tjshell\u003e thing.doSomething(1, 2);\n\t[1, 2]\n\tjshell\u003e thing.doSomething(1, 2, 3);\n\t[1, 2, 3]\n\tjshell\u003e\n\n```\n\nYou can see that `doSomething` can be called with one, two and three parameters. \n\nLet's look at another example:\n\n```java\n\n\tjshell\u003e void sum(int... values) {\n\t   ..\u003e\u003e   int sum = 0;\n\t   ..\u003e\u003e   for(value: values) {\n\t   ..\u003e\u003e     sum += value;\n\t   ..\u003e\u003e   }\n\t   ..\u003e\u003e   System.out.println(sum);\n\t   ..\u003e\u003e }\n\t| created method sum(int...)\n```\n\nWe created a `sum` method with a variable argument. Let's look at how to use it.\n\n```java\n\tjshell\u003e sum(1, 2)\n\t3\n\tjshell\u003e sum(1, 2, 3)\n\t6\n\tjshell\u003e sum(1, 2, 3, 4)\n\t1\n\tjshell\u003e sum(1, 2, 3, 4, 5, 6)\n\t21\n\tjshell\u003e\n\n```\n\nIn this step, we took our first look at variable arguments. Variable arguments allow us to pass variable number of arguments to a method.\n\n### Step 09: Variable Argument Methods For ```Student``` \n\nLet's add a few methods to the `Student` class to accept variable arguments.\n\n**_Student.java_**\n\n```java\n\n\tpackage com.in28minutes.arrays;\n\timport java.math.BigDecimal;\n\n\tpublic class Student {\n\t\tprivate String name;\n\t\tprivate int[] marks;\n\n\t\tpublic Student(String name, int...  marks) {\n\t\t\tthis.name = name;\n\t\t\tthis.marks = marks;\n\t\t}\n\n\t\tpublic int getNumberOfMarks() {\n\t\t\treturn marks.length;\n\t\t}\n\n\t\tpublic int getTotalSumOfMarks() {\n\t\t\tint sum = 0;\n\t\t\tfor(int mark:marks) {\n\t\t\t\tsum += mark;\n\t\t\t}\n\t\t\treturn sum;\n\t\t}\n\n\t\tpublic BigDecimal getAverageOfMarks() {\n\t\t\tint sum = getTotalSumOfMarks();\n\t\t\tBigDecimal average = new BigDecimal(sum).divide(new BigDecimal(marks.length), 3, RoundingMode.UP);\n\t\t}\n\n\t\tpublic int getMaximumMark() {\n\t\t\tint max = Integer.MIN_VALUE;\n\t\t\tfor(int mark:marks) {\n\t\t\t\tif(mark \u003e max) {\n\t\t\t\t\tmax = mark;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn max;\n\t\t}\n\n\t\tpublic int getMinimumMark() {\n\t\t\tint min = Integer.MAX_VALUE;\n\t\t\tfor(int mark:marks) {\n\t\t\t\tif(mark \u003c min) {\n\t\t\t\t\tmin = mark;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn min;\n\t\t}\n\t}\n\n```\n\n**_StudentRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.arrays;\n\tpublic class StudentRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\t//int[] marks = {99, 98, 100};\n\t\t\tStudent student = new Student(\"Ranga\", 97, 98, 100);\n\n\t\t\tint number = student.getNumberOfmarks();\n\t\t\tSystem.out.println(\"Number of marks : \" + number);\n\t\t\tint sum = student.getTotalSumOfMarks();\n\t\t\tSystem.out.println(\"Sum of marks : \" + sum);\n\n\t\t\tint maximumMark = student.getMaximumMark();\n\t\t\tSystem.out.println(\"Maximum of marks : \" + maximumMark);\n\t\t\tint minimumMark = student.getMinimumMark();\n\t\t\tSystem.out.println(\"Minimum of marks : \" + minimumMark);\n\t\t\tBigDecimal average = student.getAverageMarks();\n\t\t\tSystem.out.println(\"Average of marks : \" + average);\n\n\t\t\tstudent.addMark(35);\n\t\t\tstudent.removeMarkAtIndex(5);\n\t\t}\n\t}\n\n```\n\n#### Quick Tip\n\nThe variable arguments list must always be at the end of the parameter list passed to a method. The following method definition **will not** be accepted by the Java compiler:\n\n```java\n\n\tvoid process(int... values, String name) {\n\n\t}\n\n```\n\n- - - \n### Step 10: Arrays - Some Puzzles And Exercises \n\nLet's look at a few puzzles and exercises with Arrays.\n\nWhen creating arrays of objects, the array ends up holding references to the created objects.\n\n```java\n\n\tjshell\u003e class Person {\n\t   ..\u003e\u003e }\n\t| created class Person\n\tjshell\u003e Person[] persons = new Person[5];\n\tpersons ==\u003e Person[5]{ null,null,null,null,null }\n```\n\nWe can assign new `Person` objects to different elements of the array.\n\n```java\n\tjshell\u003e persons[1] = new Person();\n\t$1 ==\u003e Person@394e1a0f\n\tjshell\u003e persons\n\tpersons ==\u003e Person[5]{ null,Person@394e1a0f,null,null,null }\n\tjshell\u003e persons[0] = new Person();\n\t$2 ==\u003e Person@1e965684\n\tjshell\u003e persons\n\tpersons ==\u003e Person[5]{ Person@1e965684,Person@394e1a0f, null,null,null }\n```\n\nYou can also initialize values when you create an array.\n\n```java\n\tjshell\u003e Person[] persons2 = {new Person(), new Person()};\n\tpersons2 ==\u003e Person[2]{ Person@3b088d51, Person@1786dec2 }\n```\n\nHere's how you can initialize a `String` array.\n\n```java\n\tjshell\u003e String[] textValues = {\"Apple\", \"Ball\", \"Cat\"};\n\ttextValues ==\u003e String[2]{ \"Apple\",\"Ball\",\"Cat\" }\n\tjshell\u003e\n\t\n```\n\n#### Classroom Exercise CE-AA-03 \n\n#### Exercises\n\n1. Create a ```String``` array with the names of days of the week:\n\n```Sunday```, ```Monday```, ```Tuesday```, ```Wednesday```, ```Thursday```, ```Friday```, ```Saturday```\n2. Find the day with the most number of letters in it\n3. Print days of the week backwards\n\n#### Solutions To CE-AA-03\n\n**_WeekRunner.java_**\n\n```java\n\npackage com.in28minutes.arrays;\n\npublic class StringRunner {\n\n\tpublic static void main(String[] args) {\n\n\t\tString[] daysOfWeek = { \"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\" };\n\n\t\tString dayWithMostCharacters = \"\";\n\n\t\tfor (String day : daysOfWeek) {\n\t\t\tif (day.length() \u003e dayWithMostCharacters.length()) {\n\t\t\t\tdayWithMostCharacters = day;\n\t\t\t}\n\t\t}\n\n\t\tSystem.out.println(\"Day with Most number of characters \" + dayWithMostCharacters);\n\n\t\tfor (int i = daysOfWeek.length - 1; i \u003e= 0; i--) {\n\t\t\tSystem.out.println(daysOfWeek[i]);\n\t\t}\n\n\t}\n\n}\n\n```\n\n### Step 11: Problems With Arrays\n\nLet's look at our implementation for our challenge. \n\nWe've implemented most of the features except for ```addMark()``` and ```removeMarkAtIndex()```.\n\n```java\n\n\tStudent student = new Student(name, \u003clist-of-marks\u003e);\n\tint number = student.getNumberOfmarks();\n\tint sum = student.getTotalSumOfMarks();\n\tint maximumMark = student.getMaximumMark();\n\tint minimumMark = student.getMinimumMark();\n\tBigDecimal average = student.getAverageMarks();\n\tstudent.addMark(35);\t\n\tstudent.removeMarkAtIndex(5);\n\n```\n\nWe would want to add and remove from an array. Can we do this?\n\nThe size of an array is fixed at its compile-time definition. Which means that once we define an array such as:\n\n```String[] textValues = {\"Apple\", \"Ball\", \"Cat\"};```\n\nThe size of the `textValues` array is fixed to 3. You an change values inside the array. But the size cannot be changed.\n\nHow to add an element to an array?\n\nOne of the options is\n* Create a fresh array with a few extra element slots to accommodate the additional elements to be inserted\n* Copy the existing array elements to the beginning of this new array\n* Add the additional elements at the rear end of this array\n\nIf elements need to be removed from an array:\n* Create a fresh array with correspondingly lesser element slots\n* Copy the existing array elements, excluding the ones to be removed, to the beginning of this new array\n\n```java\njshell\u003e int[] marks = {12, 34, 45};\nmarks ==\u003e int[3] { 12, 34, 45 }\n\njshell\u003e int[] newMarks = new int[marks.length+1];\nnewMarks ==\u003e int[4] { 0, 0, 0, 0 }\n\njshell\u003e System.arraycopy(marks, 0, newMarks, 0, marks.length);\n\njshell\u003e newMarks\nnewMarks ==\u003e int[4] { 12, 34, 45, 0 }\n\njshell\u003e newMarks[3] = 100\n$27 ==\u003e 100\n\njshell\u003e newMarks\nnewMarks ==\u003e int[4] { 12, 34, 45, 100 }\n\n```\n\nAs you can see, this can be very inefficient. How do we solve it?\n\n### Step 12: Introducing ```ArrayList```\n\n`ArrayList` is more dynamic than an array. It provides operations to add and remove elements.\n\nLet's start with creating an `ArrayList` and add a few values.\n\n```java\n\n\tjshell\u003e ArrayList arrayList = new ArrayList();\n\tarrayList ==\u003e []\n\tjshell\u003e arrayList.add(\"Apple\");\n\t| Warning:\n\t| unchecked call to add(E) as a member of the raw type java.util.ArrayList\n\t| arrayList.add(\"Apple\");\n\t|_^---------------------^\n\t$1 ==\u003e true\n\tjshell\u003e arrayList.add(\"Ball\");\n\t| Warning:\n\t| unchecked call to add(E) as a member of the raw type java.util.ArrayList\n\t| arrayList.add(\"Ball\");\n\t|_^---------------------^\n\t$2 ==\u003e true\n\tjshell\u003e arrayList.add(\"Cat\");\n\t| Warning:\n\t| unchecked call to add(E) as a member of the raw type java.util.ArrayList\n\t| arrayList.add(\"Cat\");\n\t|_^---------------------^\n\t$3 ==\u003e true\n\tjshell\u003e arrayList\n\tarrayList ==\u003e [\"Apple\", \"Ball\", \"Cat\"]\n```\nYou can remove values using `remove` method.\n\n```java\n\n\tjshell\u003e arrayList.remove(\"Cat\");\n\t$4 ==\u003e true\n\tjshell\u003e arrayList\n\tarrayList ==\u003e [\"Apple\", \"Ball\"]\n```\n\nThe ```ArrayList``` instance ```arrayList``` can be used to store objects of pretty much any type, even primitive types. Also, non-homogeneous types! \n\n\u003e The warning message displayed is a hint to the programmer to discourage this.\n\n```java\n\tjshell\u003e arrayList.add(1);\n\t| Warning:\n\t| unchecked call to add(E) as a member of the raw type java.util.ArrayList\n\t| arrayList.add(1);\n\t|_^---------------------^\n\t$3 ==\u003e true\n\tjshell\u003e arrayList\n\tarrayList ==\u003e [\"Apple\", \"Ball\", 1]\n\tjshell\u003e\n\n```\n\nLet's say we want to store only `String` values in an `ArrayList`. How do we do it?\n\nWe can specify the type of elements that an `ArrayList` can contain.\n\n```java\n\n\tjshell\u003e ArrayList\u003cString\u003e items = new ArrayList\u003cString\u003e();\n\titems ==\u003e []\n```\n\nIn above snippet, we are creating an `ArrayList` that can hold `String` values.\n\nYou can add `String` value but not numbers.\n\n```java\t\n\tjshell\u003e items.add(\"Apple\");\n\t$1 ==\u003e true\n\tjshell\u003e items\n\titems ==\u003e [\"Apple\"]\n\tjshell\u003e items.add(1);\n\t| Error\n\t| no suitable method found for add(int)\n\t|...\n\tjshell\u003e items.add(\"Ball\");\n\t$2 ==\u003e true\n\tjshell\u003e items.add(\"Cat\");\n\t$3 ==\u003e true\n\tjshell\u003e items\n\titems ==\u003e [\"Apple\", \"Ball\", \"Cat\"]\n```\n\nRest of operations are similar to a normal `ArrayList`.\n```java\n\tjshell\u003e items.remove(\"Cat\");\n\t$4 ==\u003e true\n\tjshell\u003e items\n\titems ==\u003e [\"Apple\", \"Ball\"]\n\tjshell\u003e items.remove(0);\n\t$5 ==\u003e \"Apple\"\n\tjshell\u003e items\n\titems ==\u003e [\"Ball\"]\n\tjshell\u003e\n\n```\n\n### Step 13: Refactoring ```Student``` To Use ```ArrayList```\n\nLet's now get to the ```Student``` challenge once again. Let's use an `ArrayList` this time.\n\n```java\n\n\tStudent student = new Student(name, \u003clist-of-marks\u003e);\n\tint number = student.getNumberOfmarks();\n\tint sum = student.getTotalSumOfMarks();\n\tint maximumMark = student.getMaximumMark();\n\tint minimumMark = student.getMinimumMark();\t\n\tBigDecimal average = student.getAverageMarks();\n\n```\n\n##### Snippet-01 : Refactoring ```Student```\n\n**_StudentRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.arrays;\n\n\tpublic class StudentRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tStudent student = new Student(\"Ranga\", 97, 98, 100);\n\t\t\tint number = student.getNumberOfmarks();\t\t\t\n\t\t\tSystem.out.println(\"Number of marks : \" + number);\n\t\t\tint sum = student.getTotalSumOfMarks();\n\t\t\tSystem.out.println(\"Sum of marks : \" + sum);\n\n\t\t\tint maximumMark = student.getMaximumMark();\n\t\t\tSystem.out.println(\"Maximum of marks : \" + maximumMark);\n\t\t\tint minimumMark = student.getMinimumMark();\n\t\t\tSystem.out.println(\"Minimum of marks : \" + minimumMark);\n\n\t\t\tBigDecimal average = student.getAverageMarks();\n\t\t\tSystem.out.println(\"Average of marks : \" + average);\n\t\t\tSystem.out.println(student);\n\t\t}\t\n\t}\n\n```\n\n**_Student.java_**\n\n```java\n\n\tpackage com.in28minutes.arrays;\n\timport java.math.BigDecimal;\n\timport java.math.RoundingMode;\n\timport java.util.ArrayList;\n\n\tpublic class Student {\n\t\tprivate String name;\n\t\tprivate ArrayList\u003cInteger\u003e  marks = new ArrayList\u003cInteger\u003e();\n\n\t\tpublic Student(String name, int...  marks) {\n\t\t\tthis.name = name;\n\t\t\tfor(int mark: marks) {\n\t\t\t\tthis.marks.add(mark);\n\t\t\t}\n\t\t}\n\n\t\tpublic int getNumberOfMarks() {\n\t\t\treturn marks.size();\n\t\t}\n\n\t\tpublic int getTotalSumOfMarks() {\n\t\t\tint sum = 0;\n\t\t\tfor(int mark:marks) {\n\t\t\t\tsum += mark;\n\t\t\t}\t\t\t\n\t\t\treturn sum;\n\t\t}\n\n\t\tpublic BigDecimal getAverageOfMarks() {\n\t\t\tint sum = getTotalSumOfMarks();\n\t\t\tBigDecimal average = new BigDecimal(sum).divide(new BigDecimal(marks.size()), 3, RoundingMode.UP);\n\t\t}\n\n\t\tpublic int getMaximumMark() {\n\t\t\treturn Collections.max(marks);\n\t\t}\n\n\t\tpublic int getMinimumMark() {\n\t\t\treturn Collections.min(marks);\n\t\t}\n\n\t\tpublic String toString() {\n\t\t\treturn name + marks;\n\t\t}\n\t}\n\n```\n\n\nThe Enhanced ```for``` loop works for ```ArrayList```s as well, just like in the case of an array\n\nThe ```Collections.max()``` and ```Collections.min()``` methods can be used to find the maximum and minimum value in an array.\n\n### Step 14: Enhancing ```Student``` Further\n\nLet's now add the features to add and remove a student.\n\n```java\n\n\tpackage com.in28minutes.arrays;\n\n\tpublic class StudentRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tStudent student = new Student(\"Ranga\", 97, 98, 100);\n\t\t\tint number = student.getNumberOfmarks();\n\t\t\tSystem.out.println(\"Number of marks : \" + number);\n\t\t\tint sum = student.getTotalSumOfMarks();\t\t\t\n\t\t\tSystem.out.println(\"Sum of marks : \" + sum);\n\n\t\t\tint maximumMark = student.getMaximumMark();\n\t\t\tSystem.out.println(\"Maximum of marks : \" + maximumMark);\n\t\t\tint minimumMark = student.getMinimumMark();\n\t\t\tSystem.out.println(\"Minimum of marks : \" + minimumMark);\n\n\t\t\tBigDecimal average = student.getAverageMarks();\n\t\t\tSystem.out.println(\"Average of marks : \" + average);\n\t\t\tSystem.out.println(student);\n\t\t\t\n\t\t\tstudent.addMark(35);\t\t\t\n\t\t\tSystem.out.println(student);\n\t\t\tstudent.removeMarkAtIndex(1);\n\t\t\tSystem.out.println(student);\n\t\t}\n\t}\n\n```\n\n**_Student.java_**\n\n```java\n\n\tpackage com.in28minutes.arrays;\n\timport java.math.BigDecimal;\n\timport java.math.RoundingMode;\n\timport java.util.ArrayList;\n\n\tpublic class Student {\n\t\tprivate String name;\n\t\tprivate ArrayList\u003cInteger\u003e  marks = new ArrayList\u003cInteger\u003e();\n\n\t\tpublic Student(String name, int...  marks) {\n\t\t\tthis.name = name;\n\t\t\tfor(int mark: marks) {\n\t\t\t\tthis.marks.add(mark);\n\t\t\t}\n\t\t}\n\n\t\tpublic int getNumberOfMarks() {\n\t\t\treturn marks.size();\n\t\t}\n\n\t\tpublic int getTotalSumOfMarks() {\n\t\t\tint sum = 0;\n\t\t\tfor(int mark:marks) {\n\t\t\t\tsum += mark;\n\t\t\t}\t\t\n\t\t\treturn sum;\n\t\t}\n\n\t\tpublic BigDecimal getAverageOfMarks() {\n\t\t\tint sum = getTotalSumOfMarks();\n\t\t\tBigDecimal average = new BigDecimal(sum).divide(new BigDecimal(marks.size()), 3, RoundingMode.UP);\n\t\t}\n\n\t\tpublic int getMaximumMark() {\n\t\t\treturn Collections.max(marks);\n\t\t}\n\n\t\tpublic int getMinimumMark() {\n\t\t\treturn Collections.min(marks);\n\t\t}\n\n\t\tpublic String toString() {\n\t\t\treturn name + marks;\n\t\t}\n\n\t\tpublic void addMark(int mark) {\n\t\t\tmarks.add(mark);\n\t\t}\n\n\t\tpublic void removeMarkAtIndex(int index) {\n\t\t\tmarks.remove(index);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Number of marks : 3_\n\n_Sum of marks : 3_\n\nAverage of marks : 3_\n\n_Maximum of marks : 3_\n\n_Minimum of marks : 3_\n\n_Ranga[97,98,100]_\n\n_Ranga[97,98,100,35]_\n\n_Ranga[97,100,35]_\n\n## Object Oriented Programming (*OOP*) - Revisited\n\nIn this section, we revisit the principles of *OOP*, armed with the knowledge of\n* Arrays and their variants\n* Built-in Java classes and utilities, and \n* Conditionals and loops (normal and enhanced). \n\n### Step 01: Objects Revisited - State And Behavior\n\nThe attributes of an object determine what it is made up of. At different points in an object's lifetime, the value of any of its attributes can change. \n\nAt any given time, values of these attributes defines the object's **state**. \n\nIn The ```MotorBike``` example, the attribute ```speed``` defines a ```MotorBike```'s state. The ```speed``` of a ```ducati``` defines its state.\n\nHow an object responds to an external event, or a message sent to it, defines its **behavior**. \n\nMessages are delivered to an object using methods. Methods are used to implement an object's **behavior**. \n\nThe methods ```setSpeed```, ```increaseSpeed``` and ```decreaseSpeed``` have an effect on the observed speed of the ```MotorBike```s. The future `state` of a `MotorBike` depends on `behavior` and current `state`.\n\n`behavior` affects `state`. And `state` affects `behavior`. \n\n\n**_MotorBikeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBikeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMotorBike ducati = new MotorBike(100);\n\t\t\tMotorBike honda = new MotorBike(200);\n\t\t\tMotorBike yamaha = new MotorBike();\n\t\t\tducati.start();\n\t\t\thonda.start();\n\t\t\tyamaha.start();\n\n\t\t\tystem.out.println(ducati.getSpeed());\n\t\t\tSystem.out.println(honda.getSpeed());\n\t\t\tSystem.out.println(yamaha.getSpeed());\n\n\t\t\tducati.increseSpeed(50);\n\t\t\tyamaha.setSpeed(250);\n\t\t\thonda.increaseSpeed(100);\n\t\t\tyamaha.decreaseSpeed(50);\n\t\t\tSystem.out.println(ducati.getSpeed());\n\t\t\tSystem.out.println(honda.getSpeed());\n\t\t\tSystem.out.println(yamaha.getSpeed());\n\t\t}\n\t}\n\n```\n\n\n**_MotorBike.java_**\n\n```java\n\n\tpackage com.in28minutes.oops;\n\n\tpublic class MotorBike {\n\t\t//state\n\t\tprivate int speed;\n\t\t//behavior\n\t\tMotorBike() {\n\t\t\tthis(5);\n\t\t}\n\n\t\tMotorBike(int speed) {\n\t\t\tif(speed \u003e 0)\n\t\t\t\tthis.speed = speed;\n\t\t}\n\t\t\n\t\tpublic void start() {\n\t\t\tSystem.out.println(\"Bike started!\");\n\t\t}\n\n\t\tpublic void setSpeed(int speed) {\n\t\t\tif(speed \u003e 0)\n\t\t\t\tthis.speed = speed;\n\t\t}\n\n\t\tpublic int getSpeed() {\n\t\t\treturn this.speed;\n\t\t}\n\n\t\tpublic void increaseSpeed(int howMuch) {\n\t\t\tsetSpeed(this.speed + howMuch);\n\t\t}\n\n\t\tpublic void decreaseSpeed(int howMuch) {\n\t\t\tsetSpeed(this.speed - howMuch);\n\t\t}\n\t}\n\n```\n\n### Step 02: Managing ```class``` state\n\nAt a basic level, when we design a class, we decide:\n* `state` - member variables\n* `how to create objects` - Define constructors\n* `behavior` - What methods are exposed\n\nConsider the example of a ```Fan``` ```class```.\n\nThe above three major areas that correspond to its design could be as follows:\n\n* State\n\t* make\n\t* radius\n\t* color\n\t* isOn\n\t* speed\n* Constructors\n\t*  Fan(String make, double radius, String color)\n* Behavior\n\t* void switchOn()\n\t* void SwitchOff()\n\t* void changeSpeed(int change)\n\t* String toString()\n\nLet's try to write a simple ```Fan``` ```class```, that covers all these aspects. \n\n**_Fan.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\t\n\tpublic class Fan {\n\t\t//state\n\t\tprivate String make;\n\t\tprivate double radius;\n\t\tprivate String color;\n\t\tprivate boolean isOn;\n\t\tprivate byte speed;\t//levels: 0 to 5\n\n\t\t//constructors\n\n\t\tpublic Fan(String make, double radius, String color) {\n\t\t\tthis.make = make;\n\t\t\tthis.radius = radius;\n\t\t\tthis.color = color;\n\t\t}\n\n\t\t//methods\n\t\tpublic String toString() {\n\t\t\treturn String.format(\"Make : %s, Radius : %f, Color : %s, Is On : %b, Speed : %d\",\n\t\t\t\t\t\t\t\t\tmake,\n\t\t\t\t\t\t\t\t\tradius,\n\t\t\t\t\t\t\t\t\tcolor,\n\t\t\t\t\t\t\t\t\tisOn,\n\t\t\t\t\t\t\t\t\tspeed);\n\t\t}\n\t}\n\n```\n\n**_FanRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class FanRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tFan fan = new Fan(\"Fan-Tastic\", 0.456, \"GREEN\");\n\t\t\tSystem.out.println(fan);\n\t\t}\n\t}\n\n```\n**_Console Output_**\n\n_Make : Fan-tastic, Radius : 0.45600, Color : GREEN, Is On : false, Speed : 0_\n\nThe fields which were not set by the constructor, namely ```isOn``` and ```speed```, assumed the language default values for their data types, namely ```false``` (for ```booelan```) and ```0``` (for ```int```).\n\n### Step 03: Augmenting ```Fan``` With Behavior\n- - - \n\nWe need to decide what kind of behavior should be provided by a `Fan` object.\n\nThe default state attributes of the ```Fan``` class objects, namely ```make```, ```color``` and ```radius``` are fixed at manufacturing time, and cannot be altered by a user of this ```class```'s instances. \n\nThe other two state attributes, ```isOn``` and ```speed``` need to be exposed to change by ```Fan``` object users. We will offer methods that change them.\n\n##### Snippet-01 : The ```Fan``` ```class``` - v4\n\n**_FanRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class FanRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tFan fan = new Fan(\"Fan-Tastic\", 0.456, \"GREEN\");\n\t\t\tSystem.out.println(fan);\n\t\t\tfan.switchOn();\n\t\t\tSystem.out.println(fan);\n\t\t\tfan.setSpeed((byte)5);\n\t\t\tSystem.out.println(fan);\n\t\t\tfan.switchOff();\n\t\t\tSystem.out.println(fan);\n\t\t}\n\t}\n\n```\n\n**_Fan.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class Fan {\n\t\t//state\n\t\tprivate String make;\n\t\tprivate double radius;\n\t\tprivate String color;\n\t\tprivate boolean isOn;\n\t\tprivate byte speed;\t//levels: 0 to 5\n\n\t\t//constructors\n\t\tpublic Fan(String make, double radius, String color) {\n\t\t\tthis.make = make;\n\t\t\tthis.radius = radius;\n\t\t\tthis.color = color;\n\t\t}\n\n\t\t//methods\n\t\tpublic String toString() {\n\t\t\treturn String.format(\"Make : %s, Radius : %f, Color : %s, Is On : %b, Speed : %d\",\n\t\t\t\t\t\t\t\t\tmake,\n\t\t\t\t\t\t\t\t\tradius,\n\t\t\t\t\t\t\t\t\tcolor,\n\t\t\t\t\t\t\t\t\tisOn,\n\t\t\t\t\t\t\t\t\tspeed);\n\t\t}\n\n\t\t//isOn\n\t\t/*public void isOn(boolean isOn) {\n\t\t\tthis.isOn = isOn;\n\t\t}*/\n\n\t\tpublic void switchOn() {\n\t\t\tisOn = true;\n\t\t\tsetSpeed((byte)1);\n\t\t}\n\n\t\tpublic void switchOff() {\n\t\t\tisOn = false;\n\t\t\tsetSpeed((byte)0);\n\t\t}\n\n\t\tpublic void setSpeed(byte speed) {\n\t\t\tthis.speed = speed;\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Make : Fan-Tastic, Radius : 0.45600, Color : GREEN, Is On : false, Speed : 0_\n\n_Make : Fan-Tastic, Radius : 0.45600, Color : GREEN, Is On : true, Speed : 1_\n\n_Make : Fan-Tastic, Radius : 0.45600, Color : GREEN, Is On : true, Speed : 5_\n\n_Make : Fan-Tastic, Radius : 0.45600, Color : GREEN, Is On : false, Speed : 0_\n\n##### Snippet-01 Explained\n\n* Regarding the state attribute ```isOn```:\n\t* A state modifier method such as ```public void isOn(boolean)``` is not preferred, even though it does alter this attribute. This is because it is not intuitive from the ```class``` user's perspective.\n\t* Alternatively, methods such as ```public void switchOn()``` and ```public void switchOff()``` not only toggle the attribute ```isOn```, but are also intuitive and useful to the ```Fan``` ```class``` users (Here, the ```FanRunner``` class).\n\n* Regarding the state attribute ```speed```:\n\t*  ```setSpeed``` is both intuitive as well as useful, so not much rethinking needed here\n\t*  ```speed``` needs to be affected by the operations ```switchOn()``` and ```switchOff()```. We have added calls to ```setSpeed()``` in these method definitions.\n\n\n#### Summary\n\nThe best way to design a class is using an `Outside In` thought process:\n* Who all could possibly be using my ```class```?\n* What functionality would they absolutely require?\n\n### Step 04: Programming Exercise PE-OOP-01\n\n1. Write a simple ```Rectangle``` ```class``` , while covering the following constituents:\n* State\n\t* length\n\t* width\n* Constructors\n* Behavior or Methods\n\n#### Solution To PE-OOP-01\n\n**_RectangleRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class RectangleRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tRectangle rectangle = new Rectangle(12, 23);\n\t\t\tSystem.out.println(rectangle);\n\t\t\trectangle.setWidth(25);\n\t\t\tSystem.out.println(rectangle);\n\t\t\trectangle.setLength(20);\n\t\t\tSystem.out.println(rectangle);\n\t\t}\n\t}\n\n```\n\n**_Rectangle.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class Rectangle {\n\t\t//state:\n\t\t\tprivate int length;\n\t\t\tprivate int width;\n\t\t\n\t\t//creation:\n\t\tpublic Rectangle(int length, int width) {\n\t\t\tthis.length = length;\n\t\t\tthis.width = width;\n\t\t}\n\n\t\t//behaviors:\n\t\tpublic int getLength() {\n\t\t\treturn length;\n\t\t}\n\n\t\tpublic int getWidth() {\n\t\t\treturn width;\n\t\t}\n\n\t\tpublic void setLength(int length) {\n\t\t\tthis.length = length;\n\t\t}\n\n\t\tpublic void setWidth(int width) {\n\t\t\tthis.width = width;\n\t\t}\n\n\t\tpublic int area() {\n\t\t\treturn length * width;\n\t\t}\n\n\t\tpublic int perimeter() {\n\t\t\treturn 2*(length + width);\n\t\t}\n\n\t\tpublic String toString() {\n\t\t\treturn String.format(\"Rectangle - length : %d, width : %d, area : %d, perimeter : %d\", \n\t\t\t\t\t\t\t\t\tlength,\n\t\t\t\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\t\t\tarea(),\n\t\t\t\t\t\t\t\t\tperimeter());\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Rectangle - length : 12, width : 23, area : 276, perimeter : 70_\n\n_Rectangle - length : 12, width : 25, area : 300, perimeter : 74_\n\n_Rectangle - length : 20, width : 25, area : 500, perimeter : 90_\n\n#### Solution Explained\n\n* A ```Rectangle``` object created without a specified ```length``` and ```width``` makes no practical sense, therefore a default constructor is not provided.\n\n### Step 06: Understanding Object Composition\n\nLet's take a re-look at the state attributes of the ```Fan``` ```class```:\n\n**_Fan.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class Fan {\n\t\t//state\n\t\tprivate String make;\n\t\tprivate double radius;\n\t\tprivate String color;\n\t\tprivate boolean isOn;\n\t\tprivate byte speed;\n\t\t\n\t\t//constructors\n\t\t//methods\n\t}\n\n```\n\nAll member variables of 'Fan' class are primitive variables. Can we make it complex and include other classes?\n\n##### Snippet-01 : Object composition - State\n\n**_CustomerRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class CustomerRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tCustomer customer = new Customer();\n\t\t}\n\t}\n\n```\n\n**_Address.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class Address {\n\t\t//state\n\t\tprivate String doorNo;\n\t\tprivate String streetInfo;\n\t\tprivate String city;\n\t\tprivate String zipCode;\n\n\t\t//creation\n\t\t//behaviors\n\t}\n\n```\n\n**_Customer.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class Customer {\n\t\t//state\n\t\tprivate String name;\n\t\tprivate Address homeAddress;\n\t\tprivate Address workAddress;\n\n\t\t//creation\n\t\t//behaviors\n\t}\n\n```\n\n##### Snippet-01 Explained\n\n```Customer customer``` is composed of:\n*  ```name```,\n*  ```homeAddress```, and\n*  ```workAddress```. \n\n```String``` is a built-in type, and is simple. ```Address``` is a user defined type, and is composed of:\t\n* ```doorNo```,\n* ```streetInfo```,\n* ```city```, and\n* ```zipCode```\n\t\n##### Snippet-02 : Object Composition v2 - Construction\n\nLet's now add constructors to allow easy creation of these objects.\n\n**_CustomerRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class CustomerRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\t//Customer customer = new Customer();\n\t\t\tAddress homeAddress = new Address(\"Flat No. 51\", \"Hiranandani Gardens\", Mumbai\", \"400076\");\n\t\t\tAddress workAddress = new Address(\"Administrative Office\", \"Western Block\", \"Mumbai\", \"400076\");\n\t\t\tCustomer customer = new Customer(\"Ashwin Tendulkar\", homeAddress, workAddress);\n\t\t}\n\t}\n\n```\n\n**_Address.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class Address {\n\t\t//state\n\t\tprivate String doorNo;\n\t\tprivate String streetInfo;\n\t\tprivate String city;\n\t\tprivate String zipCode;\n\n\t\t//creation\n\t\tpublic Address(String doorNo, String streetInfo, String city, String zipCode) {\n\t\t\tthis.doorNo = doorNo;\n\t\t\tthis.streetInfo = streetInfo;\n\t\t\tthis.city = city;\n\t\t\tthis.zipCode = zipCode;\n\t\t}\n\n\t\t//behaviors\n\t}\n\n```\n\n**_Customer.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class Customer {\n\t\t//state\n\t\tprivate String name;\n\t\tprivate Address homeAddress;\n\t\tprivate Address workAddress;\n\n\t\t//creation\n\t\t//workAddress not mandatory for creation\n\t\tpublic Customer(String name, String homeAddress) {\n\t\t\tthis.name = name;\n\t\t\tthis.homeAddress = homeAddress;\n\t\t}\n\n\t\t//behaviors\n\t}\n\n```\n\n##### Snippet-9 : Object Composition v3 : Behaviors\n\nLet's add methods to provide behavior.\n\n**_CustomerRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class CustomerRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\t//Customer customer = new Customer();\n\t\t\tAddress homeAddress = new Address(\"Flat No. 51\", \"Hiranandani Gardens\", \"Mumbai\", \"400076\");\n\t\t\tCustomer customer = new Customer(\"Ashwin Tendulkar\", homeAddress);\n\t\t\tSystem.out.println(customer);\n\t\t\tAddress workAddress = new Address(\"Administrative Office\", \"Western Block\", \"Mumbai\", \"400076\");\n\t\t\tcustomer.setWorkAddress(workAddress);\n\t\t\tSystem.out.println(customer);\n\t\t}\n\t}\n\n```\n\n**_Address.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class Address {\n\t\t//state\n\t\tprivate String doorNo;\n\t\tprivate String streetInfo;\n\t\tprivate String city;\n\t\tprivate String zipCode;\n\n\t\t//creation\n\t\tpublic Address(String doorNo, String streetInfo, String city, String zipCode) {\n\t\t\tsuper();\n\t\t\tthis.doorNo = doorNo;\n\t\t\tthis.streetInfo = streetInfo;\n\t\t\tthis.city = city;\n\t\t\tthis.zipCode = zipCode;\n\t\t}\n\n\t\t//behaviors\n\t\tpublic String toString() {\n\t\t\treturn doorNo + \", \" + streetInfo + \", \" + city + \" - \" + zipCode;\n\t\t}\n\t}\n\n```\n\n**_Customer.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class Customer {\n\t\t//state\n\t\tprivate String name;\n\t\tprivate Address homeAddress;\n\t\tprivate Address workAddress;\n\n\t\t//creation\n\t\t//workAddress not mandatory for creation\n\t\tpublic Customer(String name, String homeAddress) {\n\t\t\tthis.name = name;\n\t\t\tthis.homeAddress = homeAddress;\n\t\t}\n\n\t\t//behaviors\n\t\t//certain components of homeAddress and workAddress can be modified, not the name\n\t\tpublic void setHomeAddress(Address homeAddress) {\n\t\t\tthis.homeAddress = homeAddress;\n\t\t}\n\n\t\tpublic void setWorkAddress(Address workAddress) {\n\t\t\tthis.workAddress = workAddress;\n\t\t}\n\n\t\tpublic Address getHomeAddress() {\n\t\t\treturn homeAddress;\n\t\t}\n\n\t\tpublic Address getWorkAddress() {\n\t\t\treturn workAddress;\n\t\t}\n\n\t\tpublic String toString() {\n\t\t\treturn String.format(\"Customer [%s] lives at [%s], works at [%s]\", \n\t\t\t\t\t\t\t\t\tname,\n\t\t\t\t\t\t\t\t\thomeAddress,\n\t\t\t\t\t\t\t\t\tworkAddress);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Customer [Ashwin Tendulkar] lives at [Flat No. 51, Hiranandani Gardens, Mumbai - 400076], works at [null]_\n\n_Customer [Ashwin Tendulkar] lives at [Flat No. 51, Hiranandani Gardens, Mumbai - 400076], works at [Administrative Office, Western Block, Mumbai - 400076]_\n\n### Step 07: Programming Exercise PE-OOP-02\n\n#### Exercises\n\nWrite a program that manages Books and their Reviews:\n\n* Book:\n\t* Id\n\t* Name\n\t* Author\n* Review:\n\t* Id\n\t* Description\n\t* Rating\n\n```java\n\n\tBook book = new Book(123, \"Object Oriented Programming With Java\", \"Ranga\");\n\tbook.addReview(new Review(10, \"Great Book\", 4));\n\tbook.addReview(new Review(101, \"Awesome\", 5));\n\tSystem.out.println(book);\n\n```\n\n#### Solution To PE-OOP-02\n\n**_BookReviewRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class BookReviewRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tBook book = new Book(123, \"Object Oriented Programming With Java\", \"Ranga\");\n\t\t\tbook.addReview(new Review(10, \"Great Book\", 4));\n\t\t\tbook.addReview(new Review(101, \"Awesome\", 5));\n\t\t\tSystem.out.println(book);\n\t\t}\n\t}\n\n```\n\n**_Review.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class Review {\n\t\tprivate int id;\n\t\tprivate String description;\n\t\tprivate byte rating;\n\n\t\tpublic Review(int id, String description, byte rating) {\n\t\t\tthis.id = id;\n\t\t\tthis.description = description;\n\t\t\tthis.rating = rating;\n\t\t}\n\n\t\tpublic String toString() {\n\t\t\treturn \"(Review-\" + id + \", \" + description + \", \" + rating + \")\";\n\t\t}\n\t}\n\n```\n\n**_Book.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class Book {\n\t\tprivate int id;\n\t\tprivate String title;\n\t\tprivate String author;\n\n\t\tprivate ArrayList\u003cReview\u003e reviewList = new ArrayList\u003cReview\u003e();\n\t\tpublic Book(int id, String title, String author) {\n\t\t\tthis.id = id;\n\t\t\tthis.title = title;\n\t\t\tthis.author = author;\n\t\t}\n\n\t\tpublic void addReview(Review review) {\n\t\t\treviewList.add(review);\n\t\t}\n\n\t\tpublic String toString() {\n\t\t\treturn \"Book-\" + id + \",  \" + title + \", \" + author + \", \" + reviews);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Book-123, Object Oriented Programming With Java, Ranga, [(Review-10, Great Book\", 4), (Review-101, Awesome, 5)]_\n\n### Step 07: The Need For Inheritance\n\nLet's look at two classes `Person` and `Student`.\n\n\n**_Person.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\n\tpublic class Person {\n\t\tprivate String name;\n\t\tprivate String email;\n\t\tprivate String phoneNumber;\n\t\t\n\t\tpublic void setName(String name) {\n\t\t\tthis.name = name;\n\t\t}\n\n\t\tpublic String getName() {\n\t\t\treturn name;\n\t\t}\n\n\t\tpublic void setEmail(String email) {\n\t\t\tthis.email = email;\n\t\t}\n\n\t\tpublic String getEmail() {\n\t\t\treturn email;\n\t\t}\n\n\t\tpublic void setPhoneNumber(String phoneNumber) {\n\t\t\tthis.phoneNumber = phoneNumber;\n\t\t}\n\n\t\tpublic String getPhoneNumber() {\n\t\t\treturn phoneNumber;\n\t\t}\n\t}\n\n``` \n\n**_StudentWithoutInheritance.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\n\tpublic class StudentWithoutInheritance {\n\t\tprivate String name;\n\t\tprivate String email;\n\t\tprivate String phoneNumber;\n\t\tprivate String college;\n\t\tprivate int year;\n\n\t\tpublic void setName(String name) {\n\t\t\tthis.name = name;\n\t\t}\n\n\t\tpublic String getName() {\n\t\t\treturn name;\n\t\t}\n\n\t\tpublic void setEmail(String email) {\n\t\t\tthis.email = email;\n\t\t}\n\n\t\tpublic String getEmail() {\n\t\t\treturn email;\n\t\t}\n\n\t\tpublic void setPhoneNumber(String phoneNumber) {\n\t\t\tthis.phoneNumber = phoneNumber;\n\t\t}\n\n\t\tpublic String getPhoneNumber() {\n\t\t\treturn phoneNumber;\n\t\t}\n\n\t\tpublic void setCollege(String college) {\n\t\t\tthis.college = college;\n\t\t}\n\n\t\tpublic String getCollege() {\n\t\t\treturn college;\n\t\t}\n\n\t\tpublic void setYear(int year) {\n\t\t\tthis.year = year;\n\t\t}\n\n\t\tpublic int getYear() {\n\t\t\treturn year;\n\t\t}\n\t}\n\n```\n\nIn above code examples, you can see that there is a lot of \n* The member fields of ```Person```, namely ```name```, ```email``` and ```phoneNumber```, are replicated in ```Student```.\n* The setter and getter methods pertaining to the above fields of ```Person``` get repliated in ```Student``` as well.\n\n\nEvery `Student` is a `Person`. What if we could extend `Person` class instead of duplicating everything?\n\n#### Enter Inheritance\n\n```Student``` **is a** ```Person```. Java supports one of the basic Object Oriented Programming Paradigms : **Inheritance**.  \n\n```Student``` can *inherit* from ```Person```, to model the fact that a ```Student``` *is a* ```Person```. \n\nThis is accomplished by using the Java keyword ```extends```, during class definition of ```Student```. \n\n```java\n\n\tpublic class Person {\n\t\t// \u003cPerson Definition\u003e\n\t}\n\n\tpublic class Student extends Person {\n\t\t// \u003cStudent Definition, after reusing Person Code\u003e\n\t}\n\n```\n\nInheritance is a mechanism of code reuse. In this case, all the fields and methods previously defined in ```Person``` are available for ```Student``` as well.\n\nIn this Inheritance relationship, ```Person``` is called the **super-class** of ```Student```. Likewise, ```Student``` is the **sub-class** of ```Person```.\n\nLet's now look at how we go about changing the ```Student``` ```class``` definition.\n\n##### Snippet-02 : Student inherits from Person - v1\n\n**_Person.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\n\tpublic class Person {\n\t\tprivate String name;\n\t\tprivate String email;\n\t\tprivate String phoneNumber;\n\n\t\tpublic void setName(String name) {\n\t\t\tthis.name = name;\n\t\t}\n\n\t\tpublic String getName() {\n\t\t\treturn name;\n\t\t}\n\n\t\tpublic void setEmail(String email) {\n\t\t\tthis.email = email;\n\t\t}\n\n\t\tpublic String getEmail() {\n\t\t\treturn email;\n\t\t}\n\n\t\tpublic void setPhoneNumber(String phoneNumber) {\n\t\t\tthis.phoneNumber = phoneNumber;\n\t\t}\n\n\t\tpublic String getPhoneNumber() {\n\t\t\treturn phoneNumber;\n\t\t}\n\t}\n\n``` \n\n\n**_Student.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\n\tpublic class Student extends Person {\n\t\tprivate String collegeName;\n\t\tprivate int year;\n\n\t\tpublic void setCollegeName(String college) {\n\t\t\tthis.collegeName = collegeName;\n\t\t}\n\n\t\tpublic String getCollegeName() {\n\t\t\treturn collegeName;\n\t\t}\n\n\t\tpublic void setYear(int year) {\n\t\t\tthis.year = year;\n\t\t}\n\n\t\tpublic int getYear() {\n\t\t\treturn year;\n\t\t}\n\t}\n\n```\n\n**_StudentRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\tpublic class StudentRunner {\n\t\tpublic static void main(String[] args)\n\t\t\tStudent student = new Student();\n\t\t\t// \u003c all setter() and getter() methods of Person and Student available \u003e\n\t\t\tstudent.setName(\"Ranga\");\t\t\t\n\t\t\tstudent.setEmail(\"in28minutes@gmail.com\");\n\t\t}\n\t}\n\n```\n\n### Step 09:  Introducing ```Object``` class\n\nIn the Java language, every class, whether an in-built Java library class, or a user-defined class, implicitly inherits from the class ```Object```. \n\nThis ```Object``` class is available in the Java system package ```java.lang```. This class is at the root of the Java class hierarchy. All classes, including arrays, implement/inherit the methods of this ```class```. \n\nLet's take a look at the ```Person``` and ```Student``` classes.\n\n##### Snippet-01 : The Object class\n\n**_Person.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\n\tpublic class Person {\n\t\tprivate String name;\n\t\tprivate String email;\n\t\tprivate String phoneNumber;\n\n\t\tpublic void setName(String name) {\n\t\t\tthis.name = name;\n\t\t}\n\n\t\tpublic String getName() {\n\t\t\treturn name;\n\t\t}\n\n\t\tpublic void setEmail(String email) {\n\t\t\tthis.email = email;\n\t\t}\n\n\t\tpublic String getEmail() {\n\t\t\treturn email;\n\t\t}\n\n\t\tpublic void setPhoneNumber(String phoneNumber) {\n\t\t\tthis.phoneNumber = phoneNumber;\n\t\t}\n\n\t\tpublic String getPhoneNumber() {\n\t\t\treturn phoneNumber;\n\t\t}\n\t}\n\n``` \n\n\n**_Student.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\n\tpublic class Student extends Person {\n\t\tprivate String collegeName;\n\t\tprivate int year;\n\t\t\n\t\tpublic void setCollegeName(String college) {\n\t\t\tthis.collegeName = collegeName;\n\t\t}\n\n\t\tpublic String getCollegeName() {\n\t\t\treturn collegeName;\n\t\t}\n\n\t\tpublic void setYear(int year) {\n\t\t\tthis.year = year;\n\t\t}\n\n\t\tpublic int getYear() {\n\t\t\treturn year;\n\t\t}\n\t}\n\n```\n\n**_StudentRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\n\tpublic class StudentRunner {\n\t\tpublic static void main(String[] args)\n\t\t\t//Student student = new Student();\n\t\t\t//student.setName(\"Ranga\");\n\t\t\t//student.setEmail(\"in28minutes@gmail.com\");\n\n\t\t\tPerson person = new Person();\n\t\t\tString personStr = person.toString();\n\t\t\tSystem.out.println(personStr);\n\t\t\tSystem.out.println(person);\n\t\t\tint hashCode = person.hashCode();\t\t\t\n\t\t\tperson.notify();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_com.in28minutes.oops.level2.inheritance.Person@7a46a697_\n\n_com.in28minutes.oops.level2.inheritance.Person@7a46a697_\n\n##### Snippet-01 Explained\n\nMethods of the ```Object``` ```class``` such as ```toString()```, ```hashCode()``` and ```notify()``` are available to objects of ```class``` ```Person``` as default implementations.\n\nThe statement ```System.out.println(person);``` actually gets translated to ```System.out.println(person.toString())```, as the Java system implicitly makes the call ```person.toString()``` as it is inherited from ```class``` ```Object``` for use in the ```String``` context.\n\n### Step 10: Inheritance And Method Overriding\n\nSub-class inherit features from super-class\n* state attributes : super-class member variables\n* behavior components  : super-class method definitions\n\nThese are of course, available for access (and modification), and invocation, respectively, within the sub-class. \n\nYou can also override super class method implementations in a sub class - **method overriding**. \n\n##### Snippet-01: Method Overriding\n\n**_Person.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\n\tpublic class Person {\n\t\tprivate String name;\n\t\tprivate String email;\n\t\tprivate String phoneNumber;\n\n\t\tpublic void setName(String name) {\n\t\t\tthis.name = name;\n\t\t}\n\n\t\tpublic String getName() {\n\t\t\treturn name;\n\t\t}\n\n\t\tpublic void setEmail(String email) {\n\t\t\tthis.email = email;\n\t\t}\n\n\t\tpublic String getEmail() {\n\t\t\treturn email;\n\t\t}\n\n\t\tpublic void setPhoneNumber(String phoneNumber) {\n\t\t\tthis.phoneNumber = phoneNumber;\n\t\t}\n\n\t\tpublic String getPhoneNumber() {\n\t\t\treturn phoneNumber;\n\t\t}\n\n\t\tpublic String toString() {\n\t\t\treturn String.format(\"Person %s , Email : %s, Phone Number : %s\", name, email, phoneNumber);\n\t\t}\n\t}\n\n``` \n\n**_PersonRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\n\tpublic class PersonRunner {\n\t\tpublic static void main(String[] args)\n\t\t\tPerson person = new Person();\n\t\t\tperson.setName(\"Ranga\");\n\t\t\tperson.setEmail(\"in28minutes@gmail.com\");\n\t\t\tperson.setPhoneNumber(\"9898989898\");\n\t\t\tString personStr = person.toString();\n\t\t\tSystem.out.println(personStr);\n\t\t\tSystem.out.println(person);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Person Ranga , Email : in28minutes@gmail.com, Phone Number : 9898989898_\n\n_Person Ranga , Email : in28minutes@gmail.com, Phone Number : 9898989898_\n\n##### Snippet-01 Explained\n\nBy defining the method ```toString()``` within the ```Person``` sub-```class```, we are overriding the default version provided by the ```Object``` super-```class```.\n\n### Step 11: Classroom Exercise CE-OOP-01 \n\nCreate an Employee class extending Student Class with following attributes:\n* Title\n* Employer\n* EmployeeGrade\n* Salary\n\nCreate a method toString() within Employee to print all state attribute values, including those of Person.\n\n##### Snippet-01 : Employee Inheritance\n\n**_Person.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\n\tpublic class Person {\n\t\tprivate String name;\n\t\tprivate String email;\n\t\tprivate String phoneNumber;\n\n\t\tpublic void setName(String name) {\n\t\t\tthis.name = name;\n\t\t}\n\n\t\tpublic String getName() {\n\t\t\treturn name;\n\t\t}\n\n\t\tpublic void setEmail(String email) {\n\t\t\tthis.email = email;\n\t\t}\n\n\t\tpublic String getEmail() {\n\t\t\treturn email;\n\t\t}\n\n\t\tpublic void setPhoneNumber(String phoneNumber) {\n\t\t\tthis.phoneNumber = phoneNumber;\n\t\t}\n\n\t\tpublic String getPhoneNumber() {\n\t\t\treturn phoneNumber;\n\t\t}\n\n\t\tpublic String toString() {\n\t\t\treturn Sring.format(\"Person %s , Email : %s, Phone Number : %s\", name, email, phoneNumber);\n\t\t}\n\t}\n\n``` \n\n**_Employee.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\timport java.math.BigDecimal;\n\n\tpublic class Employee extends Person {\n\t\tprivate String title;\n\t\tprivate String employerName;\n\t\tprivate char employeeGrade;\n\t\tprivate BigDecimal salary;\n\n\t\tpublic void setTitle(String title) {\n\t\t\tthis.title = title;\n\t\t}\n\n\t\tpublic String getTitle() {\n\t\t\treturn title;\n\t\t}\n\n\t\tpublic void setEmployerName(String employer) {\n\t\t\tthis.employerName = employerName;\n\t\t}\n\n\t\tpublic String getEmployerName() {\n\t\t\treturn employerName;\n\t\t}\n\n\t\tpublic void setEmployeeGrade(char  employeeGrade) {\n\t\t\tthis.employeeGrade = employeeGrade;\n\t\t}\n\n\t\tpublic char getEmployeeGrade() {\n\t\t\treturn employeeGrade;\n\t\t}\n\n\t\tpublic void setSalary(BigDecimal  salary) {\n\t\t\tthis.salary = salary;\n\t\t}\n\n\t\tpublic BigDecimal getSalary() {\n\t\t\treturn salary;\n\t\t}\n\n\t\tpublic String toString() {\n\t\t\treturn String.format(\"Employee Title: %s, Employer: %s, Employee Grade: %c, Salary: %s\",\n\t\t\t\t\t\t\t\t\ttitle,\n\t\t\t\t\t\t\t\t\temployerName,\n\t\t\t\t\t\t\t\t\temployeeGrade,\n\t\t\t\t\t\t\t\t\tsalary);\n\t\t}\n\t}\n\n```\n\n**_EmployeeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\n\tpublic class EmployeeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tEmployee employee = new Employee();\n\t\t\temployee.setName(\"Ranga\");\n\t\t\temployee.setEmail(\"in28minutes@gmail.com\");\n\t\t\temployee.setPhoneNumber(\"123-456-7890\");\n\t\t\temployee.setTitle(\"Programmer Analyst\");\n\t\t\temployee.setEmployerName(\"In28Minutes\");\n\t\t\temployee.setEmployeeGrade('A');\n\t\t\temployee.setSalary(new BigDecimal(\"50000\"));\n\t\t\tSystem.out.println(employee);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Employee Title: Programmer Analyst, Employer: In28Minutes, Employee Grade: A, Salary: 50000.0000_\n\n##### Snippet-01 Explained\n\nWe have not printed the underlying ```Person``` object details in ```Employee.toString()``` method overriding. Let's look to do that next.\n\n### Step 12: Constructors, And Calling ```super()``` \n\nThe ```super``` keyword allows an sub-class to access the attributes present in the super-class. \n\n##### Snippet-01 : Calling Person.toString()\n\n**_Employee.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\timport java.math.BigDecimal;\n\n\tpublic class Employee extends Person {\n\t\t//focusing only on the toString() method\n\t\tpublic String toString() {\n\t\t\treturn String.format(\"Employee Name: %s, Email: %s, Phone Number: %s, Title: %s, Employer: %s, Employee Grade: %c, Salary: %s\",\n\t\t\t\t\t\t\t\t\tsuper.getName(),\n\t\t\t\t\t\t\t\t\tsuper.getEmail(),\n\t\t\t\t\t\t\t\t\tsuper.getPhoneNumber(),\n\t\t\t\t\t\t\t\t\ttitle,\n\t\t\t\t\t\t\t\t\temployerName,\n\t\t\t\t\t\t\t\t\temployeeGrade,\n\t\t\t\t\t\t\t\t\tsalary);\n\t\t}\n\t}\n\n```\n\n**_EmployeeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\t\n\tpublic class EmployeeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tEmployee employee = new Employee();\n\t\t\temployee.setName(\"Ranga\");\n\t\t\temployee.setEmail(\"in28minutes@gmail.com\");\n\t\t\temployee.setPhoneNumber(\"123-456-7890\");\n\t\t\temployee.setTitle(\"Programmer Analyst\");\n\t\t\temployee.setEmployerName(\"In28Minutes\");\n\t\t\temployee.setEmployeeGrade('A');\t\t\n\t\t\temployee.setSalary(new BigDecimal(\"50000\"));\n\t\t\tSystem.out.println(employee);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Employee Name: Ranga, Email: in28minutes@gmail.com, Phone Number: 123-456-7890, Title: Programmer Analyst, Employer: In28Minutes, Employee Grade: A, Salary: 50000.0000_\n\nThe ```super``` keyword allows an sub-class to access the attributes present in the super-class. Hence, we were able to invoke the getter methods of the ```Person``` object within the ```Employee``` object, like this within ```Employee.toString()```\n\t* ```super.getName()```\n\t* ```super.getEmail()```\n\t* ```super.getPhoneNumber()```\n\n\n#### Sub-Class Contructor \n\nWhat happens when a sub class object is created? Does the super class constructor get called?\n\n##### Snippet-7 : Person class\n\n**_Person.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\n\tpublic class Person {\n\n\t\tpublic Person() {\n\t\t\tSystem.out.println(\"Inside Person Constructor\");\n\t\t}\n\n\t}\n\n``` \n\n**_Employee.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\timport java.math.BigDecimal;\n\n\tpublic class Employee extends Person {\n\n\t\tpublic Employee() {\n\t\t\t//super();\n\t\t\tSystem.out.println(\"Inside Employee Constructor\");\n\t\t}\n\n\t}\n\n```\n\n**_EmployeeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\n\tpublic class EmployeeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tEmployee employee = new Employee();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Inside Person Constructor_\n\n_Inside Employee Constructor_\n\n##### Snippet-02 Explained\n\nWhen a sub-class object is created\n* sub-class constructor is called and it implicitly invokes its super-class constructor. \n\nThe Java compiler inserts the code ```super();``` (if it is not explicitly added by the programmer) as the first statement in the body of the sub-class default constructor, here ```Employer()```. \n* The statement ```super();``` is the invocation of the super-class default constructor. \n* Hence, the body of the super-class constructor is always invoked before the body of the sub-class constructor.\n\n##### Snippet-3 : ```Person``` - Non-Default Constructor\n\nLet's remove the no argument constructor and add a one argument constructor to `Person` class.\n\n```\n\t\tpublic Person(String name) {\n\t\t\tthis.name = name;\n\t\t}\n```\n\n**_PersonRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\n\tpublic class PersonRunner {\n\t\tpublic static void main(String[] args)\n\t\t\tPerson person = new Person(\"Ranga\");\n\t\t\tperson.setEmail(\"in28minutes@gmail.com\");\n\t\t\tperson.setPhoneNumber(\"123-456-7890\");\n\t\t\tSystem.out.println(person);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Person Ranga , Email : in28minutes@gmail.com, Phone Number : 123-456-7890_\n\n##### Snippet-03 Explained\n\nWhen we added the constructor with one argument for ```class``` ```Employee```, the existing code in **_EmployeeRunner.java_** will cause a compilation error, because there is no longer any default constructor for ```Person``` ! \n\n```super()``` cannot be called from within the default constructor of ```Employee```.\n\nOne option is to put the no argument constructor back.\n\n```java\n\n\tpublic Person() {\n\t\tSystem.out.println(\"Inside Person Constructor\");\n\t}\n\n```\n\nBut, it doesn't really make sense to create a ```Person``` without a ```name```, does it? \n\nThe solution in this case would be to call the single-argument constructor ```Person(String)``` by an invocation such as ```super(name);```\n\n```\n\t\tpublic Employee(String name, String title, String employerName, char employeeGrade) {\n\t\t\tsuper(name);\n\t\t\tthis.title = title;\n\t\t\tthis.employerName = employerName;\n\t\t\tthis.employeeGrade = employeeGrade;\n\t\t}\n```\n\n**_EmployeeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\t\n\tpublic class EmployeeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tEmployee employee = new Employee(\"Ranga\", \"Programmer Analyst\", \"In28Minutes\", 'A');\n\t\t\tSystem.out.println(employee);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Employee Name: Ranga, Email: null, Phone Number: null, Title: Programmer Analyst, Employer: In28Minutes, Employee Grade: A, Salary: null_\n\n##### Snippet-10 : EmployeeRunner complete\n\nLet's provide setters to set the non mandatory attributes.\n\n**_EmployeeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\n\tpublic class EmployeeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tEmployee employee = new Employee(\"Ranga\", \"Programmer Analyst\", \"In28Minutes\", \t\t\t'A');\n\t\t\temployee.setEmail(\"in28minutes@gmail.com\");\n\t\t\temployee.setPhoneNumber(\"123-456-7890\");\n\t\t\temployee.setSalary(new BigDecimal(\"50000\"));\n\t\t\tSystem.out.println(employee);\n\t\t}\n \t}\n\n```\n\n**_Console Output_**\n\n_Employee Name: Ranga, Email: in28minutes@gmail.com, Phone Number: 123-456-7890, Title: Programmer Analyst, Employer: In28Minutes, Employee Grade: A, Salary: 50000.0000_\n\n\n##### Snippet-10: ```Student``` updated\n\nLet's add a two argument construtor to the `Student` class.\n\n**_Student.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\n\tpublic class Student extends Person {\n\t\tprivate String collegeName;\n\t\tprivate int year;\n\t\n\t\tpublic Student(String name, String collegeName) {\n\t\t\tsuper(name);\n\t\t\tthis.collegeName = collegeName;\n\t\t}\n\n\t\tpublic String getCollegeName() {\n\t\t\treturn collegeName;\n\t\t}\n\n\t\tpublic void setYear(int year) {\n\t\t\tthis.year = year;\n\t\t}\n\n\t\tpublic int getYear() {\n\t\t\treturn year;\n\t\t}\n\n\t\tpublic String toString() {\n\t\t\treturn \"Student : \" + super.name() + \", College: \" + collegeName;\n\t\t}\n\t}\n\n```\n\n**_StudentRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.inheritance;\n\n\tpublic class StudentRunner {\n\t\tpublic static void main(String[] args)\n\t\t\t//Student student = new Student();\n\t\t\tStudent student = new Student(\"Ranga\", \"IIT Bombay\");\n\t\t\tSystem.out.println(student);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Student : Ranga, College : IIT Bombay_\n\n### Step 13: Multiple Inheritance, Reference Variables And ```instanceof```\n\nIn other programming languages, Multiple Inheritance is allowed. A class can directly inherit from two or more classes. \n\nHowever, in Java, direct Multiple Inheritance is not allowed.\n\n##### Snippet-01 : Multiple Inheritance\n\n```java\n\n\tjshell\u003e class Animal {\n\t   ..\u003e\u003e }\n\t| created class Animal\n\tjshell\u003e class Pet {\n\t   ..\u003e\u003e }\n\t| created class Pet\n\n\tjshell\u003e class Dog extends Animal, Pet {\n\t   ..\u003e\u003e }\n\t| Error:\n\t| '{' expected\n\t| class Dog extends Animal, Pet {\n\t|_________________________^\n\tjshell\u003e**\n\n```\n\n`class Dog extends Animal, Pet {}` throws an error. You cannot extend two classes.\n\n#### Inheritance Chains\n\nHowever you can create an inheritance chain.\n*  ```class``` ```C``` **is a** ```class``` ```B```\n*  ```class``` ```B``` **is a** ```class``` ```A```\n\nLet's check out a small code snippet.\n\n##### Snippet-02 : An Inheritance Chain\n\n`Dog``` **is a** ```Pet```, ```Pet``` **is a** ```Animal```. This is an example of what is called an **inheritance hierarchy**.\n\n```java\n\n\tjshell\u003e class Animal {\n\t   ..\u003e\u003e }\n\t| created class Animal\n\tjshell\u003e class Pet extends Animal {\n\t   ..\u003e\u003e public void groom() {\n\t   ..\u003e\u003e System.out.println(\"Pet Groom\");\n\t   ..\u003e\u003e }\n\t   ..\u003e\u003e }\n\t| created class Pet_\n\tjshell\u003e class Dog extends Pet {\n\t   ..\u003e\u003e }\n\t| created class Dog\n```\n\n If you want, you can visualize in your mind as :  *```Dog``` --\u003e ```Pet``` --\u003e ```Animal``` --\u003e ```Object```* (Yes, ```Object``` is sitting at the top of *all* inheritance hierarchies in Java!)\n\nThe statement ```Dog dog = new Dog();``` sets off constructor invocations up the inheritance hierarchy:\n\t*  ```Dog()``` invokes ```Pet()```\n\t\t*  ```Pet()``` invokes ```Animal()```\n\t\t\t*  ```Animal()``` invokes ```Object()```\n\n\n```java\n\tjshell\u003e Dog dog = new Dog();\n\tdog ==\u003e Dog@23a6e47f\n```\n\nThe expression ```dog.toString()``` does a traversal up the inheritance hierarchy as well:\n\t* Since ```Dog.toString()``` is not defined, the compiler looks for ```Pet.toString()```\n\t* Since ```Pet.toString()``` is not defined, the compiler looks for ```Animal.toString()```\n\t* Since ```Animal.toString()``` is not defined, the compiler looks for ```Object.toString()```, which is always provided as the default implementation for all sub-classes of ```class``` ```Object``` in Java.\n\n```java\n\tjshell\u003e dog.toString();\n\t$1 ==\u003e \"Dog@23a6e47f\"\n```\n\nThe invocation ```dog.groom();``` is also resolved by traversing up the inheritance hierarchy.\n\n```java\n\tjshell\u003e dog.groom();\n\t\"Pet Groom\"\n```\n\n\nThe statement ```Pet pet = new Dog();``` is really interesting. In Java, it is permitted for a *super-class reference variable to reference a sub-class object instance*.\n\nThrough such a reference, method invocations are also permitted, and the correct thing gets done. Hence, ```pet.groom();``` causes the output \"*```Pet Groom```*\".\n\nHowever, the converse assignment is not allowed. *A sub-class reference variable*  **_cannot_** *reference a super-class object instance*. \n\t* The statement ```Dog dog = new Pet();``` therefore, causes a compiler error. \n\n```java\n\tjshell\u003e Pet pet = new Dog();\n\tpet ==\u003e Dog@22d37d54\n\tjshell\u003e pet.groom();\n\tPet Groom\n```\n\n```java\n\tjshell\u003e Dog dog = new Pet();\n\t| Error:\n\t| incompatible types: Pet cannot be converted to Dog\n\t| Dog dog = new Pet();\n\t|___________^-------^\n```\n\n\n\nThe ```instanceof``` operator is to find the relationship between an object and a class. If the object is an instance of the class or its sub class, it returns true. \n\n\n```java\n\tjshell\u003e pet instanceof Pet\n\t$2 ==\u003e true\n\tjshell\u003e pet instanceof Dog\n\t$3 ==\u003e true\n```\n\nThe ```instanceof``` operator throws an error if the object and class are unrelated.\n\n```java\n\tjshell\u003e pet instanceof String\n\t| Error:\n\t| incompatible types: Pet cannot be converted to java.lang.String\n\t| pet instanceof String\n\t|_^-^\n\tjshell\u003e pet instanceof Animal\n\t$4 ==\u003e true\n\tjshell\u003e pet instanceof Object\n\t$5 ==\u003e true\n```\n\nThe ```instanceof``` operator returns ```false``` if the object is an instance of a super class of the class provided.\n\n```java\n\tjshell\u003e Animal animal  new Animal();\n\tanimal ==\u003e Animal@3632be31\n\tjshell\u003e animal instanceof Pet\n\t$6 ==\u003e false\n\tjshell\u003e animal instanceof Dog\n\t$7 ==\u003e false\n\tjshell\u003e animal instanceof Object\n\t$8 ==\u003e true\n\tjshell\u003e\n\n```\n\n### Step 14: Introducing Abstract Classes\n\nAn ```abstract class``` can contain ```abstract``` methods.\n\nAn abstract method does not have a method definition.\n\nHere's how a typical class looks like. You can create methods inside the class and you can create instances of the class.\n\n```java\n\n\tjshell\u003e class Animal {\n\t   ..\u003e\u003e public void bark() {\n\t   ..\u003e\u003e System.out.println(\"Animal Bark\");\n\t   ..\u003e\u003e }\n\t   ..\u003e\u003e }\n\t| created class Animal\n\tjshell\u003e Animal animal = new Animal();\n\tanimal ==\u003e Animal@335eadca\n\tjshell\u003e animal.bark();\n\tAnimal Bark\n```\n\nLet's see how to create an abstract class:\n\n```java\n\tjshell\u003e abstract class AbstractAnimal {\n\t   ..\u003e\u003e abstract public void bark();\n\t   ..\u003e\u003e }\n\t| created class AbstractAnimal\n```\n\nThe syntax is simple: add `abstract` keyword before the class.\n\nAn ```abstract class``` cannot be instantiated.\n```java\n\tjshell\u003e AbstractAnimal animal = new AbstractAnimal();\n\t| Error:\n\t| AbstractAnimal is abstract; cannot be instantiated.\n\t| AbstractAnimal animal = new AbstractAnimal();\n\t|^--------------------------------------------^\n\tjshell\u003e\n```\n\nHowever, it can be sub-classed, creating inheritance hierarchies below it.  A sub-class of an abstract class (often called a **concrete class**) must override its ```abstract``` methods. \n\n\n```java\n\tjshell\u003e class Dog extends AbstractAnimal {\n\t   ..\u003e\u003e }\n\t| Error:\n\t| Dog is not abstract and does not override abstract method bark() in AbstractAnimal\n\t| class Dog extends AbstractAnimal {\n\t|^----------------------------------...\n\tjshell\u003e class Dog extends AbstractAnimal {\n\t   ..\u003e\u003e public void bark() {\n\t   ..\u003e\u003e System.out.println(\"Bow Bow\");\n\t   ..\u003e\u003e }\n\t   ..\u003e\u003e }\n\t| created class Dog\n\tjshell\u003e Dog dog = new Dog();\n\tdog ==\u003e Dog@5a8e6209\n\tjshell\u003e dog.bark();\n\tBow Bow\n\t\n```\n\n### Step 15: Abstract Classes - Design Aspects\n\nWhy do we need an abstract class?\n\nConsider a feast being prepared at a home, and several dishes are on the menu for the event. Obviously, each dish would have certain procedure for it to be prepared. Cooking any dish normally involves following a tried and tested recipe, and its preparation boils down to these basic steps:\n* Prepare the Ingredients\n* Cook the Recipe\n* Cleanup (the Mess created!)\n\nThese steps would be different for each dish but the order of steps remain the same.\n\n\n##### Snippet-01 : The Recipe Hierarchy \n\nLet's use abstract class to build the recipe.\n\n**_AbstractRecipe.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic abstract class AbstractRecipe {\n\t\tpublic void execute() {\n\t\t\tprepareIngredients();\n\t\t\tcookRecipe();\t\t\t\n\t\t\tcleanup();\n\t\t}\n\n\t\tabstract void prepareIngredients();\n\t\tabstract void cookRecipe();\n\t\tabstract void cleanup();\n\t}\n\n```\n\nWe defined abstract methods for each of the steps and created an `execute` method calling them. `execute` method ensures that the order of method call is followed.\n\nYou can define implementations implementing the abstract methods.\n\n**_CurryRecipe.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class CurryRecipe extends AbstractRecipe {\n\t\tpublic CurryRecipe() {\n\t\t\tSystem.out.println(\"[Curry Preparation Method]\");\n\t\t}\n\n\t\t@Override\n\t\tvoid prepareIngredients() {\n\t\t\tSystem.out.println(\"Get Vegetables Cut and Ready\");\n\t\t\tSystem.out.println(\"Get Spices Ready\");\n\t\t}\n\n\t\t@Override\n\t\tvoid cookRecipe() {\n\t\t\tSystem.out.println(\"Steam And Fry Vegetables\");\n\t\t\tSystem.out.println(\"Cook With Spices\");\n\t\t\tSystem.out.println(\"Add Seasoning\");\n\t\t}\n\n\t\t@Override\n\t\tvoid cleanup() {\n\t\t\tSystem.out.println(\"Discard unused Vegetables\");\n\t\t\tSystem.out.println(\"Discard unused Spices\");\n\t\t}\n\t}\n\n```\n\n**_RecipeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class RecipeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tCurryRecipe curryRecipe = new CurryRecipe();\n\t\t\tcurryRecipe.execute();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_[Curry Preparation Method]_\n\n_Get Vegetables Cut and Ready_\n\n_Get Spices Ready_\n\n_Steam And Fry Vegetables_\n\n_Cook With Spices_\n\n_Add Seasoning_\n\n_Discard unused Vegetables_\n\n_Discard unused Spices_\n\n##### Snippet-01 Explained\n\n`CurryRecipe` defines what needs to be done in each step. When we invoke the `execute` method, the steps are executed in order.\n\n##### Snippet-02 : MicrowaveCurryRecipe\n\nWe can easily create more recipes.\n\n**_MicrowaveCurryRecipe.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\t\n\tpublic class MicrowaveCurryRecipe extends AbstractRecipe {\n\t\tpublic MicrowaveCurryRecipe() {\n\t\t\tSystem.out.println(\"[Curry Microwave Method]\");\n\t\t}\n\n\t\t@Override\n\t\tvoid prepareIngredients() {\n\t\t\tSystem.out.println(\"Get Vegetables Cut and Ready\");\n\t\t\tSystem.out.println(\"Switch on Microwave\");\n\t\t}\n\n\t\t@Override\n\t\tvoid cookRecipe() {\n\t\t\tSystem.out.println(\"Microwave Vegetables\");\n\t\t\tSystem.out.println(\"Add Seasoning\");\n\t\t}\n\n\t\t@Override\n\t\tvoid cleanup() {\n\t\t\tSystem.out.println(\"Switch Off Microwave\");\n\t\t\tSystem.out.println(\"Discard unused Vegetables\");\n\t\t}\n\t}\n\n```\n\n**_RecipeRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2;\n\n\tpublic class RecipeRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMicrowaveCurryRecipe mcirowaveRecipe = new MicrowaveCurryRecipe();\n\t\t\tmicrowaveRecipe.execute();\n\t\t}\n\t}\n\n```\n\n\n**_Console Output_**\n\n_[Curry Microwave Method]_\n\n_Get Vegetables Cut and Ready_\n\n_Switch on Microwave_\n\n_Microwave Vegetables_\n\n_Add Seasoning_\n\n_Switch off Microwave_\n\n_Discard unused Vegetables_\n\n##### Snippet-02 Explained\n\n`MicrowaveCurryRecipe` defines what needs to be done in each step. When we invoke the `execute` method, the steps are executed in order. \n\n#### Summary\n\nThis pattern is called a `Template method` pattern. You define an abstract class with the order of steps defined. You leave the implementation of each of the steps to the sub classes.\n\n### Step 16: Abstract Classes - Puzzles\n\nLet's look a few FAQ regarding abstract classes.\n\nAn ```abstract class``` can be created, without any ```abstract``` member methods.\n\n```java\n\n\tjshell\u003e abstract class AbstractTest {\n\t   ...\u003e}\n\t| creates abstract class AbstractTest\n```\n\nAn ```abstract class``` can be a sub class to create another ```abstract class```, without overriding any of the super-class ```abstract``` methods.\n\n```java\n\tjshell\u003e abstract class AbstractAlgorithm {\n\t   ...\u003e abstract void flowChart();\n\t   ...\u003e }\n\t| creates abstract class AbstractAlgorithm\n\tjshell\u003e abstract class AlgorithmTypeOne extends AbstractAlgorithm {\n\t   ...\u003e }\n\t| creates abstract class AlgorithmTypeOne\n\n```\n\nAn ```abstract class``` can have member variables.\n```java\n\tjshell\u003e abstract class AbstractAlgorithm {\n\t   ...\u003e private int stepCount;\n\t   ...\u003e }\n\t| replaced abstract class AbstractAlgorithm\n```\n\nAn ```abstract class``` can have non-abstract methods.\n```java\n\tjshell\u003e abstract class AbstractAlgorithm {\n\t   ...\u003e private int stepCount;\n\t   ...\u003e public int getStepCount() {\n\t   ...\u003e return stepCount;\n\t   ...\u003e }\n\t   ...\u003e }\n\t| replaced abstract class AbstractAlgorithm\n\tjshell\u003e\n\n```\n\n\n### Step 17: Introducing Interfaces\n- - - \n\nWhat does a \"*gaming console*\" mean to you?\n\nA device that has buttons or other controls on it, that enable us to play video games.\n\nWhat are the typical buttons on it?\n- Arrows - up down left right\n- Select\n- etc\n\nGaming console offers an interface to play your games.\n\nWho provides the implementation of what happens when a button is clicked? The game implementor - for example, the implementor of Mario game or the Chess game.\n\nHow do you represent this in Java program?\n\n\n**_GamingConsole.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.interfaces;\n\n\tpublic interface GamingConsole {\n\t\tpublic void up();\n\t\tpublic void down();\n\t\tpublic void left();\n\t\tpublic void right();\n\t}\n\n```\n\n\n```interface``` ```GamingConsole``` contains methods without definitions. \n\nWho provides the implementations?\n\nWelcome `MarioGame`.\n\n**_MarioGame.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.interfaces;\n\n\tpublic class MarioGame implements GamingConsole {\n\t\t@Override\n\t\tpublic void up() {\n\t\t\tSystem.out.println(\"Jump\");\n\t\t}\n\n\t\t@Override\n\t\tpublic void down() {\n\t\t\tSystem.out.println(\"Go into a hole\");\n\t\t}\n\n\t\t@Override\n\t\tpublic void left() {\n\t\t}\n\n\t\t@Override\n\t\tpublic void right() {\n\t\t\tSystem.out.println(\"Go Forward\");\n\t\t}\n\t}\n\n```\n\n`MarioGame` provides a definition for all the methods declared in the interface `GamingConsole`. Syntax is simple. `class MarioGame implements GamingConsole` and implement all the methods.\n\nLet's look at how you can run these games.\n\n**_GameRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.interfaces;\n\n\tpublic class GameRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMarioGame game = new MarioGame();\n\t\t\tgame.up();\n\t\t\tgame.down();\n\t\t\tgame.left();\n\t\t\tgame.right();\n\t\t}\n\t}\n\n```\n\n\n**_Console Output_**\n\n_Jump_\n\n_Go into a hole_\n\n_Go forward_\n\n##### Snippet-01 Explained\n\nThe main advantage of having an interface is that it can be used to enforce a contract for its implementors. \n\n##### Snippet-02 : Code Reuse With Interfaces\n\nLet's look at another example - `ChessGame`.\n\n**_ChessGame.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.interfaces;\n\n\tpublic class ChessGame implements GamingConsole {\n\n\t\t@Override\n\t\tpublic void up() {\n\t\t\tSystem.out.println(\"Move Piece Up\");\n\t\t}\n\n\t\t@Override\n\t\tpublic void down() {\n\t\t\tSystem.out.println(\"Move Piece Down\");\n\t\t}\n\n\t\t@Override\n\t\tpublic void left() {\n\t\t\tSystem.out.println(\"Move Piece Left\");\n\t\t}\n\n\t\t@Override\n\t\tpublic void right() {\n\t\t\tSystem.out.println(\"Move Piece Right\");\n\t\t}\n\t}\n\n```\n\nRunning it is simple. All that you need to do is to comment out `MarioGame game = new MarioGame();` and replace it with an implementation of `ChessGame`.\n\n**_GameRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.interfaces;\n\n\tpublic class GameRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\t//MarioGame game = new MarioGame();\n\t\t\tChessGame game = new ChessGame();\n\t\t\tgame.up();\n\t\t\tgame.down();\n\t\t\tgame.left();\n\t\t\tgame.right();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Move Piece Up_\n\n_Move Piece Down_\n\n_Move Piece Left_\n\n_Move Piece Right_\n\n##### Snippet-2 explained\n\nIn the same ```GamerRunner``` ```class```, if we now instantiate a ```ChessGame``` object instead of a ```MarioGame``` one, none of the other code needs to change. This is because both ```MarioGame``` and ```ChessGame``` implement the same ```interface```, ```GamingConsole```. \n\n#### Using Interface as type for reference variable\n\n```GamingConsole``` is an interface.```MarioGame``` and ```ChessGame``` are it's implementations.\n\nLet's try this -  `GamingConsole game = new ChessGame();`\n\n**_GameRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.interfaces;\n\n\tpublic class GameRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tGamingConsole game = new ChessGame();\n\t\t\tgame.up();\n\t\t\tgame.down();\n\t\t\tgame.left();\n\t\t\tgame.right();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Move Piece Up_\n\n_Move Piece Down_\n\n_Move Piece Left_\n\n_Move Piece Right_\n\n#### Explained\n`GamingConsole game = new ChessGame();` - You can store an implementation of an interface into a reference variable of the type of the interface.\n\nHow does this help?\n\nLet's look at the next example:\n\n##### Snippet-4 : GameRunner Version 4\n\n**_GameRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.interfaces;\n\n\tpublic class GameRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tGamingConsole game = new MarioGame();\n\t\t\tgame.up();\n\t\t\tgame.down();\n\t\t\tgame.left();\n\t\t\tgame.right();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Jump_\n\n_Go into a hole_\n\n_Go forward_\n\n##### Snippet-04 Explained\n\nYou can replace `GamingConsole game = new ChessGame()` with `GamingConsole game = new MarioGame()` and now the program runs the `MarioGame`. Isn't it awesome?\n\n### Step 18: Using Interfaces To Design APIs\n\nConsider a Software Development project, which involves programming a fairly large and complex application.  Project team (Team A) decided to out-source part of this project to an external team (Team B). Let's say this external team needs to implement a farily complex algorithm to achieve a specific task, and which needs to interface with the rest of the application. Work on both parts of the application needs to proceed simultaneously.\n\nSuppose the algorithm logic is implemented using a single method:\n\n\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;\u0026nbsp;```int complexAlgorithm(int number1, int number2);```\n\nHow do we ensure that the work done by both the teams remains compatible?\n\nThey start with defining an interface.\n\n**_ComplexAlgorithm.java_**\n\n```java\n  \n\tpackage com.in28minutes.oops.level2.interfaces;\n\n\tpublic interface ComplexAlgorithm {\n\t\tint complexAlgorithm(int number1, int number2);\n\t}\n\n```\n\nNow the teams can go on their merry way. Team A can create a stub for the interface `OneComplexAlgorithm` and start working on their project.\n\n**_OneComplexAlgorithm.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.interfaces;\n\n\tpublic class OneComplexAlgorithm {\n\t\tpublic int complexAlgorithm(int number1, int number2) {\n\t\t\treturn number1 + number2;\n\t\t}\n\t}\n\n```\n\nTeam B can take time to implement the actual algorithm.\n\n**_ActualComplexAlgorithm.java_**\n\n```java\n\n\tpackage com.in28minutes.oops.level2.interfaces;\n\n\tpublic class ActualComplexAlgorithm {\n\t\tpublic int complexAlgorithm(int number1, int number2) {\n\t\t\t//Your complex implementation will be present here..\n\t\t\treturn number1 * number2;\n\t\t}\n\t}\n\n```\n\n### Step 19: Interfaces - Puzzles And Interesting Facts\n- - -  \n\nLet's look at a few examples to understand interfaces further.\n\n\nAn ```interface``` can be extended by another ```interface```. We can have an inheritance hierarchy purely consisting of interfaces.\n\n```java\n\n\tjshell\u003e interface InterfaceOne {\n\t   ...\u003e void methodOne();\n\t   ...\u003e }\n\t| created interface InterfaceOne\n\n\tjshell\u003e interface InterfaceTwo extends InterfaceOne {\n\t   ...\u003e void methodTwo();\n\t   ...\u003e }\n\t| created interface InterfaceTwo\n```\n\nAn implementation of interface should implement all its methods including the methods in its super interfaces.\n\n```java\n\tjshell\u003e class Implementation implements InterfaceTwo {\n\t   ...\u003e}\n\t| Error:\n\t| Implementation is not abstract and does not implement abstract method methodTwo() of \tInterfaceTwo\n\t| class Implementation implements InterfaceTwo {\n\t|^---------------------------------------------...\n\n\tjshell\u003e public class Implementation implements InterfaceTwo {\n\t   ...\u003e public void methodTwo() {}\n\t   ...\u003e }\n\t| Error:\n\t| Implementation is not abstract and does not implement abstract method methodOne() of \tInterfaceOne\n\t| class Implementation implements InterfaceTwo {\n\t|^---------------------------------------------...\n\n\tjshell\u003e public class Implementation implements InterfaceTwo {\n\t   ...\u003e public void methodTwo() {}\n\t   ...\u003e public void methodOne() {}\n\t   ...\u003e }\n\t| created class Implementation\n```\n\nIf a class is declared as abstract, it can skip providing implementations for all interface methods.\n```java\n\tjshell\u003e public abstract class AbstractImplementation implements InterfaceTwo {\n\t   ...\u003e public void methodOne() {}\n\t   ...\u003e }\n\t| created class AbstractImplementation\n```\n\n```interfaces``` cannot have member variables. An ```interface``` can only have declared **constants**\n\n```java\n\tjshell\u003e interface InterfaceThree {\n\t   ...\u003e int test;\n\t   ...\u003e }\n\t| Error:\n\t| = expected \n\t| int test;\n\t|_________^\n\n\tjshell\u003e interface InterfaceThree {\n\t   ...\u003e int test = 5;\n\t   ...\u003e }\n\t| created interface InterfaceThree\n```\n\nStarting from Java SE 8, an interface can provide a default implementation of the methods it provides.  It can be done by including the keyword ```default``` in the signature of that method, and providing a body to that method in its definition.\n\n\n```java\n\tjshell\u003e interface InterfaceFour {\n\t   ...\u003e public default void print() {\n\t   ...\u003e System.out.println(\"default print\");\n\t   ...\u003e }\n\t   ...\u003e }\n\t| created interface InterfaceFour\n\n\tjshell\u003e class TestPrint implements InterfaceFour {\n\t   ...\u003e }\n\t| created class TestPrint\n\n\n\tjshell\u003e TestPrint testPrint = new TestPrint();\n\ttestPrint ==\u003e TestPrint@6ebc05a6\n\tjshell\u003e testPrint.print();\n\tdefault print\n```\n\nImplementations of ```interface``` can override the default method implementation.\n\n```java\n\tjshell\u003e class ParticularPrint implements InterfaceFour {\n\t   ...\u003e public void print() {\n\t   ...\u003e System.out.println(\"particular print\");\n\t   ...\u003e }\n\t   ...\u003e }\n\t| created class ParticularPrint\n```\n```java\n\tjshell\u003e ParticularPrint particularPrint = new ParticularPrint();\n\tparticularPrint ==\u003e ParticularPrint@5fad14c4\n\tjshell\u003e particularPrint.print();\n\tparticular print\n\tjshell\u003e\n\n```\n\nNo method declared inside an ```interface``` can be qualified with the ```private``` access specifier. However, an ```abstract class``` can have ```private``` methods declared within.\n\n\n#### Why do we need ```default``` method implementations.\n\nLet's consider a `Provider` interface with three implementations.\n\n```java\n\n\tpublic interface Provider {\n\t\tpublic void doSomething();\n\t}\n\n\tpublic class ImplementorOne {\n\t\t@Override\n\t\tpublic void doSomething() {\n\t\t\tSystem.out.println(\"Do One\");\n\t\t}\n\t}\n\n\tpublic class ImplementorTwo {\n\t\t@Override\n\t\tpublic void doSomething() {\n\t\t\tSystem.out.println(\"Do Two\");\n\t\t}\n\t}\n\n\tpublic class ImplementorThree {\n\t\t@Override`\n\t\tpublic void doSomething() {\n\t\t\tSystem.out.println(\"Do Three\");\n\t\t}\n\t}\n\n```\n\nWhat happens if a new method is added to the `interface`?\n\n```java\n\n\tpublic interface Provider {\n\t\tpublic void doSomething();\n\t\tpublic void doMore();\n\t}\n\n```\n\nCompilation Error! All implementations classes ```ImplementationOne```, ```ImplementationTwo``` and ```ImplementationThree``` **must** me updated to implement ```doMore()``` in each case. \n\nAlternative : provide a default implementation for `doMore`.\n\n```java\n\n\tpublic interface Provider {\n\t\tpublic void doSomething();\n\t\n\t\tpublic default void doMore(){\n\t\t\tSystem.out.println(\"Do More\");\n\t\t}\n\t}\n\n```\n\nNo other code needs to immediately change, and specific implementation classes can override this default version, as and when needed.\n\nThis is especially useful in building and extending frameworks. You are not breaking a user of your framework interface when you add new methods to the interface.\n\n### Step 20:  ```abstract class``` And ```interface``` : A Comparison\n\n```abstract class``` and ```interface``` are very different, except that they have a very similar syntax. \n\nWhen would you want to use them in your application?\n\n#### interface\n\n```interface``` is a **Contract**.\n\nAn ```interface``` is primarily used when you have two software components that need to communicate with each other, and there is a need to establish a contract. \n\nRecall the following example: `ComplexAlgorithm` defines the interface which helps both the teams involved.\n\n```java\n\n\tpackage com.in28minutes.oops.level2.interfaces;\n\tpublic interface ComplexAlgorithm {\n\t\tint complexAlgorithm(int number1, int number2);\n\t}\n\n```\n\n#### abstract class\n\nAn ```abstract class``` is primarily used when you want to generalize behavior by creating a super class. \n\nRecall the following example we had discussed:\n\n```java\n\n\tpublic abstract class AbstractRecipe {\n\t\tpublic void execute() {\n\t\t\tprepareIngredients();\n\t\t\tcookRecipe();\n\t\t\tcleanup();\n\t\t}\n\n\t\tabstract void prepareIngredients();\n\t\tabstract void cookRecipe();\n\t\tabstract void cleanup();\n\t}\n\n```\n \n#### Syntactical Comparison\n\nHere are important syntactical differences:\n* No method declared inside an ```interface``` can be qualified with a ```private``` access specifier. However, an ```abstract class``` can have ```private``` methods.\n* An ```interface``` cannot have declared member variables. An ```abstract class``` can have member variable declarations.\n* A ```class``` or an ```abstract class``` can implement multiple ```interface```s. But, an ```interface``` can extend only one ```interface```, and a ```class``` or an ```abstract class``` can extend only one ```class``` or ```abstract class```.\n\n### Step 21: Programming Exercise PE-OOP-03\n\n#### Exercises\n\nTODO\n\n#### Solution To PE-OOP-03\n\n#### Solution - 1\n\n#### Solution - 2\n\n### Step 21: Introducing Polymorphism\n\nTODO\n\n# Introducing Collections\n\nArrays are not dynamic data structures. They can store only a fixed maximum number of elements.\n\nInserting or removing elements into an array needs a lot of work.\n\nCollections are in-built implementations available to support dynamic data structures in Java programs. The commonly used collections are based on Lists, Trees and Hash Tables. \n\nJava provides very good collection implementations.\n\nTo make it simple to understand all collections, we will start with the interfaces - such as ```List```, ```Set```, ```Queue```, ```Map``` and others. \n\nAfter that, we will look at implementations of these interfaces, such as ```LinkedList```, ```HashTable``` and  ```TreeMap```, among others.\n\n#### The Collection Interfaces\n\nLet's start with the `List` interface\n\n#### The ```List``` ```interface```\n\nThe ```List``` ```interface``` is used to implement an **ordered collection** in Java programs. An ordered collection is one, where the programmer has control over the position where an element can be inserted into, or accessed from the collection.\n\nIf an element's insertion position is not specified, it is added at the end of the ```List```.\n\nA ```List``` typically allows *duplicate* elements. \n \n##### Snippet-1 : Creating a List\n\nWe can see examples of creating a list and accessing element data below:\n\n```java\n\n\tjshell\u003e List\u003cString\u003e words = List.of(\"Apple\", \"Bat\", \"Cat\");\n\twords ==\u003e [Apple, Bat, Cat]\n\tjshell\u003e words.size()\n\t$1 ==\u003e 3\n\tjshell\u003e words.isEmpty()\n\t$2 ==\u003e false\n\tjshell\u003e words.get(0)\n\t$3 ==\u003e Apple\n\tjshell\u003e words.contains(\"Dog\")\n\t$4 ==\u003e false\n\tjshell\u003e words.contains(\"Cat\")\n\t$5 ==\u003e true\n\tjshell\u003e words\n\twords ==\u003e [Apple, Bat, Cat]\n\tjshell\u003e words.indexOf(\"Cat\")\n\t$6 ==\u003e 2\n\tjshell\u003e words.indexOf(\"Dog\")\n\t$7 ==\u003e -1\n\tjshell\u003e\n\n```\n\n#### ```List``` Immutability\n\nConsider the ```List``` ```words``` we created in the last snippet.\n\n```List\u003cString\u003e words = List.of(\"Apple\", \"Bat\", \"Cat\");```\n\nLists created using the ```static``` ```of``` method are *immutable*.\n\n```java\n\n\tjshell\u003e List\u003cString\u003e words = List.of(\"Apple\", \"Bat\", \"Cat\");\n\twords ==\u003e [Apple, Bat, Cat]\n\tjshell\u003e words.add(\"Dog\");\n\t| java.lang.UnsupportedOperationExcetion thrown:\n\t| at ImmutableCollections.uoe (ImmutableCollections.java:71)\n\t| at ImmutableCollections$AbstractImmutableList.add (ImmutableCollections.java:77)\n\t| at (#15:1)\n\tjshell\u003e\n\n```\n\n#### Creating A Mutable ```List```s\n\nThe way to create ```List``` data structures that can be updated over time, is to instantiate built-in ```collection``` classes that implement the ```List``` interface. \n\nExamples are ```ArrayList```, ```LinkedList``` and ```Vector```.\n\n##### Snippet-3: Mutable Lists\n\nLet's look at a few examples:\n\n```java\n\n\tjshell\u003e List\u003cString\u003e words = List.of(\"Apple\", \"Bat\", \"Cat\");\n\twords ==\u003e [Apple, Bat, Cat]\n\n\tjshell\u003e List\u003cString\u003e wordsArrayList = new ArrayList\u003cString\u003e(words);\n\twordsArrayList ==\u003e [Apple, Bat, Cat]\n\n\tjshell\u003e List\u003cString\u003e wordsLinkedList = new LinkedList\u003cString\u003e(words);\n\twordsLinkedList ==\u003e [Apple, Bat, Cat]\n\n\tjshell\u003e List\u003cString\u003e wordsVector = new Vector\u003cString\u003e(words);\n\twordsVector ==\u003e [Apple, Bat, Cat]\n\n\tjshell\u003e wordsArrayList.add(\"Dog\");\n\t$1 ==\u003e true\n\n\tjshell\u003e wordsArrayList\n\twordsArrayList ==\u003e [Apple, Bat, Cat, Dog]\n\n\tjshell\u003e\n\n```\n\n#### ```ArrayList``` vs ```LinkedList``` \n\n```ArrayList``` uses an array to store elements.\n* Positional access and modification of elements is very efficient, with constant-time algorithmic complexity.\n* Insertion and deletion of elements are expensive. In a 20 element list, to insert an element at first position, all 20 elements should be moved.\n\nThe data structure used to implement a ```LinkedList``` is of the type linked-list, which is a chain of blocks of memory slots.\n* Inserting and Deleting values is easy. This is because in a chain of blocks, each link is nothing but a reference to the next block. Insertion only involves adjustment of these links to accommodate new values, and does not require extensive copying and shifting of existing elements.\n* Positional access and modification of elements is less efficient than in an ```ArrayList```, because access always involves traversal of links.\n\nOptimization: the underlying data structure for a ```LinkedList``` is actually a doubly-linked list, with each element having both forward and backward links to elements around it. \n\n#### ```Vector``` vs ```ArrayList```\n\n```Vector``` has been with Java since v1.0, whereas ```ArrayList``` was added later, in v1.2. Both of them use an array as the underlying data structure. \n\n```Vector``` is thread-safe. In ```Vector```, all methods are ```synchronized```. \n\n\u003e Look at other thread safe `List` implementations as `Vector` has poor concurrency.\n\n#### ```List``` Operations\nWe will examine common ```List``` operations on an ```ArrayList```. Similar operations can also be done on a ```LinkedList``` or a ```Vector```.\n\n##### Snippet-4 : List Insertions\n\nWe look at examples for\n* Insertion at end (default)\n* Positional insertion\n* Inserting duplicate entries is allowed\n* Adding all elements of an external list, to the current list\n\t* At the end\n\t* Positional insertion is also available, as in single element insertion\n\n```java\n\n\tjshell\u003e List\u003cString\u003e words = List.of(\"Apple\", \"Bat\", \"Cat\");\n\twords ==\u003e [Apple, Bat, Cat]\n\tjshell\u003e List\u003cString\u003e wordsArrayList = new ArrayList\u003cString\u003e(words);\n\twordsArrayList ==\u003e [Apple, Bat, Cat]\n\tjshell\u003e wordsArrayList.add(\"Dog\");\n\t$1 ==\u003e true\n\tjshell\u003e wordsArrayList\n\twordsArrayList ==\u003e [Apple, Bat, Cat, **Dog**]\n\tjshell\u003e wordsArrayList.add(\"Elephant\");\n\t$2 ==\u003e true\n\tjshell\u003e wordsArrayList\n\twordsArrayList ==\u003e [Apple, Bat, Cat, Dog, **Elephant**]\n\tjshell\u003e wordsArrayList.add(2, \"Ball\");\n\t*jshell\u003e wordsArrayList\n\twordsArrayList ==\u003e [Apple, Bat, **Ball**, Cat, Dog, Elephant]\n\tjshell\u003e wordsArrayList.add(\"Ball\");\n\tjshell\u003e wordsArrayList\n\twordsArrayList ==\u003e [Apple, Bat, Ball, Cat, Dog, Elephant, **Ball**]\n\tjshell\u003e List\u003cString\u003e newList = List.of(\"Yak\", \"Zebra\");\n\tnewList ==\u003e [Yak, Zebra]\n\tjshell\u003e wordsArrayList.addAll(newList);\n\t$3 ==\u003e true\n\tjshell\u003e wordsArrayList\n\twordsArrayList ==\u003e [Apple, Bat, Ball, Cat, Dog, Elephant, Ball,  **Yak**, **Zebra**]\n\tjshell\u003e\n\n```\n\n\n##### Snippet-5 : Element Modification\n\nLet's look at examples of\n* Modifying elements at a specific position.\n* Deleting elements\n\n```java\n\n\tjshell\u003e wordsArrayList\n\twordsArrayList ==\u003e [Apple, Bat, Ball, Cat, Dog, Elephant, Ball,  Yak, Zebra]\n\tjshell\u003e wordsArrayList.set(6, \"Fish\");\n\t$4 ==\u003e \"Ball\"\n\tjshell\u003e wordsArrayList\n\twordsArrayList ==\u003e [Apple, Bat, Ball, Cat, Dog, Elephant, **Fish**,  Yak, Zebra]\n\tjshell\u003e wordsArrayList.remove(2);\n\t$5 ==\u003e \"**Ball**\"\n\tjshell\u003e wordsArrayList\n\twordsArrayList ==\u003e [Apple, Bat, Cat, Dog, Elephant, Fish,  Yak, Zebra]\n\tjshell\u003e wordsArrayList.remove(\"Dog\");\n\t$6 ==\u003e true\n\tjshell\u003e wordsArrayList\n\twordsArrayList ==\u003e [Apple, Bat, Cat, Elephant, Fish,  Yak, Zebra]\n\tjshell\u003e wordsArrayList.remove(\"Dog\");\n\t$6 ==\u003e false\n\tjshell\u003e\n\n```\n\n##### Snippet-6 : Iterating within ArrayList\n\nLet's now look at how to iterate around the contents of a `List`\n\nBasic for loop:\n\n```java\n\n\tjshell\u003e List\u003cString\u003e words = List.of(\"Apple\", \"Bat\", \"Cat\");\n\twords ==\u003e [Apple, Bat, Cat]\n\tjshell\u003e for(int i=0; i\u003cwords.size(); i++) {\n\t...\u003e System.out.println(words.get(i));\n\t...\u003e }\n\tApple\n\tBat\n\tCat\n```\n\nUsing enhanced for loop:\n```java\n\tjshell\u003e for(String word:words) {\n\t...\u003e System.out.println(word);\n\t...\u003e }\n\tApple\n\tBat\n\tCat\n```\n\nUsing iterators:\n```java\n\tjshell\u003e Iterator wordsIterator = words.iterator();\n\twordsIterator ==\u003e java.util.AbstractList$Itr@3712b94\n\tjshell\u003e while(wordsIterator.hasNext()) {\n\t...\u003e System.out.println(wordsIterator.next());\n\t...\u003e }\n\tApple\n\tBat\n\tCat\n```\n#### Choosing Between Iteration Modes\n- - - \n\n* For non-mutating iterations, an enhanced ```for``` loop is the most convenient\n* For mutating iterations:\n* Deletions: An enhanced ```for``` loop is not recommended, as we saw in the example. ```\"Bat\"``` was removed, but ```\"Cat\"``` was not, because the iteration itself was affected.\n* Iterators can be used for such iterations.\n\n\n##### Snippet-6\n\n```java\n\n\tjshell\u003e List\u003cString\u003e words = List.of(\"Apple\", \"Bat\", \"Cat\");\n\twords ==\u003e [Apple, Bat, Cat]\n\tjshell\u003e List\u003cString\u003e wordsAL = new ArrayList\u003c\u003e(words);\n\twordsAL ==\u003e [Apple, Bat, Cat]\n\tjshell\u003e for(String word:words) {\n\t  ...\u003e if(word.endsWith(\"at\"))\n\t   ...\u003e System.out.println(word);\n\t   ...\u003e }\n\t   ...\u003e }\n\tBat\n\tCat\n\tjshell\u003e for(String word:wordsAL) {\n\t   ...\u003e if(word.endsWith(\"at\"))\n\t   ...\u003e wordsAL.remove(word);\n\t   ...\u003e }\n\t   ...\u003e }\n\tjshell\u003e wordsAL\n\twordsAL ==\u003e [Apple, Cat]\n\tjshell\u003e Iterator wordsIterator = wordsAL.iterator();\n\twordsIterator ==\u003e java.util.AbstractList$Itr@3712b94\n\tjshell\u003e while(wordsIterator.hasNext()) {\n\t   ...\u003e if(wordsIterator.next().endsWith(\"at\")){\n\t   ...\u003e wordsIterator.remove();\n\t   ...\u003e }\n\t   ...\u003e }\n\tjshell\u003e wordsAL\n\twordsAL ==\u003e [Apple]\n\tjshell\u003e\n\n```\n\n#### ```List``` : Type Safety\n\nA ```List``` collection does not store primitives. It only stores object references. When we attempt to store primitive types, such as those of ```int```, ```char``` or ```double```, they get implicitly converted to their wrapper class types, namely ```Integer```, ```Character``` and ```Double``` respectively. Primitive data type elements get *auto-boxed*.\n\n##### Snippet-7 : Type safety\n\nThe ```ArrayList.indexOf()``` method is not overloaded, there is only one version. SO, when passed an ```int``` argument, it is auto-boxed to an ```Integer``` object, and the method gets executed. \n* However, the ```ArrayList.remove()``` method has two overloaded versions:\n\t* ```ArrayList.remove(int index)``` : attempts to delete an element at the specified index in the ```ArrayList```\n\t* ```ArrayList.remove(Object o)``` : attempts to delete the specified element, if ti is present in the ```ArrayList\t```.\n\n```java\n\n\tjshell\u003e List values = List.of(\"A\", 'A', 1, 1.0);\n\tvalues ==\u003e [\"A\", 'A', 1, 1.0]\n\tjshell\u003e values.get(2)\n\t$1 ==\u003e 1\n\tjshell\u003e values.get(2) instanceof Integer\n\t$2 ==\u003e true\n\tjshell\u003e values.get(1) instanceof Character\n\t$3 ==\u003e true\n\tjshell\u003e values.get(3) instanceof Double\n\t$4 ==\u003e true\n\tjshell\u003e List\u003cString\u003e textValues = List.of(\"A\", 'A', 1, 1.0);\n\t| Error\n\t| Error\n\t| List\u003cString\u003e textValues = List.of(\"A\", 'A', 1, 1.0);\n\t|___________________________^------------------------^\n\tjshell\u003e List\u003cInteger\u003e numbers = List.of(101, 102, 103, 104, 105);\n\tnumbers ==\u003e [101, 102, 103, 104, 105]\n\tjshell\u003e numbers.indexOf(101)\n\t$5 ==\u003e 0\n\tjshell\u003e List\u003cInteger\u003e numbersAL = new ArrayList\u003c\u003e(numbers);\n\tnumbersAL ==\u003e [101, 102, 103, 104, 105]\n\tjshell\u003e numbersAL.indexOf(101)\n\t$6 ==\u003e 0\n\tjshell\u003e numbersAL.remove(101)\n\tjava.lang.IndexOutOfBoundsException!!\n\tjshell\u003e numbersAL.remove(Integer.valueOf(101))\n\t$7 ==\u003e true\n\tjshell\u003e numbersAL\n\tnumbersAL ==\u003e [102, 103, 104, 105]\n\tjshell\u003e\n\n```\n\n#### Sorting a ```List```\n\n##### Snippet-8 : List sort\n\nThe ```List``` obtained from ```List.of()``` is immutable, hence cannot be sorted itself. Hence, create a mutable ```ArrayList``` out of it.\n\nThe ```ArrayList.sort()``` method requires the definition of a ```Comparator``` object. Easier option is to use ```Collections.sort()``` instead.\n\n\n\n```java\n\n\tjshell\u003e List\u003cInteger\u003e numbers = List.of(123, 12, 3, 45);\n\tnumbers ==\u003e [123, 12, 3, 45]\n\tjshell\u003e List\u003cInteger\u003e numbersAL = new ArrayList\u003c\u003e(numbers);\n\tnumbersAL ==\u003e [123, 12, 3, 45]\n\tjshell\u003e numbersAL.sort();\n\t| Error:\n\t| required: java.util.Comparator\u003c? super java.lang.Integer\u003e\n\t| numbersAL.sort();\n\t|^-------------^\n\tjshell\u003e Collections.sort(numbersAL);\n\tjshell\u003e numbersAL\n\tnumbersAL ==\u003e [3, 12, 45, 123]\n\tjshell\u003e\n\n```\n\n#### Sorting List\n\n##### Snippet-9 : Sorting List\n\nLet's create a Student class and try to sort it using `Collections.sort`\n\n\n**_Student.java_**\n\n```java\n\n\tpackage collections;\n\t\n\tpublic class Student {\n\t\tprivate int id;\n\t\tprivate String name;\n\t\t\n\t\tpublic Student(int id, String name) {\n\t\t\tsuper();\n\t\t\tthis.id = id;\n\t\t\tthis.name = name;\n\t\t}\n\n\t\tpublic int getId() {\n\t\t\treturn id;\n\t\t}\n\n\t\tpublic void setId(int id) {\n\t\t\tthis.id = id;\n\t\t}\n\n\t\tpublic String getName() {\n\t\t\treturn name;\t\t\n\t\t}\n\n\t\tpublic void setName(String name) {\n\t\t\tthis.name = name;\n\t\t}\n\n\t\tpublic String toString() {\n\t\t\treturn id + \" \" + name;\n\t\t}\n\t}\n\n```\n\n**_StudentsCollectionRunner.java_**\n\n```java\n\n\tpackage collections;\n\timport java.util.Collections;\n\timport java.util.List;\n\timport java.util.ArrayList;\n\n\tpublic class StudentsCollectionRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cStudent\u003e students = List.of(new Student(1, \"Ranga\"),\n\t\t\t\t\t\t\t\t\t\t\tnew Student(100, \"Adam\"),\n\t\t\t\t\t\t\t\t\t\t\tnew Student(2, \"Eve\"));\n\t\t\tArrayList\u003cStudent\u003e studentsAl = new ArrayList\u003c\u003e(students);\n\t\t\tSystem.out.println(studentsAl);\n\t\t\tCollections.sort(studentsAl);\n\t\t\tSystem.out.println(studentsAl);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n**_COMPILER ERROR_**\n\n##### Snippet-9 Explained\n\nTo the method ```Collections.sort()```, only those ```List```s can be passed, the type of whose elements ```T```, implements the ```Comparator\u003c? super T\u003e``` ```interface```. \n\n```Student``` does not implement the interface. Result - Compilatino error.\n##### Snippet-10 : Implementing Comparator Interface\n\n**_StudentsCollection.java_**\n\n```java\n\n\tpackage collections;\n\timport java.util.Comparable;\n\n\tpublic class Student implements Comparable\u003cStudent\u003e {\n\t\t// Same as earlier\n\t\t@Override\n\t\tpublic int compareTo(Student that) {\n\t\t\treturn Integer.compare(this.id, that.id);\n\t\t} \n\t}\n\n```\n\n**_StudentsCollectionRunner.java_**\n\n```java\n\n\tpackage collections;\n\timport java.util.Collections;\n\timport java.util.List;\n\timport java.util.ArrayList;\n\n\tpublic class StudentsCollectionRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cStudent\u003e students = List.of(new Student(1, \"Ranga\"),\n\t\t\t\t\t\t\t\t\t\t\tnew Student(100, \"Adam\"),\n\t\t\t\t\t\t\t\t\t\t\tnew Student(2, \"Eve\"));\n\t\t\tArrayList\u003cStudent\u003e studentsAl = new ArrayList\u003c\u003e(students);\n\t\t\tSystem.out.println(studentsAl);\t\t\t\n\t\t\tCollections.sort(studentsAl);\n\t\t\tSystem.out.println(studentsAl);\n\t\t}\n\t}\n\n```\n\n\n**_Console Output_**\n\n_[1 Ranga, 100 Adam, 2 Eve]_\n\n_[1 Ranga, 2 Eve, 100 Adam]_\n\n##### Snippet-10 Explained\n\n`Integer.compare(x, y)`  returns the value 0 if x == y; a value less than 0 if x \u003c y; and a value greater than 0 if x \u003e y. \n\nIf you change the order of parameters:\n\n```java\n\n\t@Override\n\tpublic int compareTo(Student that) {\n\t\treturn Integer.compare(that.id, this.id);\n\t}\n\n``` \n\nOutput changes to:\n\n_[100 Adam, 2 Eve, 1 Ranga]_\n\n#### The ```Comparator``` ```interface```\n\nWhat if there is a need for sorting Student's in multiple ways? What if we want to sort Students in ascending order of id's in some situations and in descending order of id's in some other situations?\n\n```Collections.sort``` has an overloaded version that has a signature that looks like:\n\n```java\n\n\t@SuppressWarnings({\"unchecked\", \"rawtypes\" })\n\tpublic static \u003cT\u003e sort(List\u003cT\u003e list, Comparator\u003c? super T\u003e c)\n\t\tlist.sort(c);\n\t}\n\n``` \n\nTo be able to invoke this version of ```Collections.sort```, we will need to define a suitable ```Comparator``` implementation, that works with ```Student``` objects.\n\nAs you may have already guessed, we would need to define two different ```Comparator``` implementations: one for ascending sort, and another for descending sort.\n\n##### Snippet-11 : Implementing Student Comparators\n\n```java\n\n\tpackage collections;\n\timport java.util.Collections;\n\timport java.util.List;\n\timport java.util.ArrayList;\n\timport java.util.Comparator;\n\n\tclass DescStudentComparator implements Comparator\u003cStudent\u003e {\n\t\t@Override\n\t\tpublic int compare(Student student1, Student student2) {\n\t\t\treturn Integer.compare(student2.getId(), student1.getId());\t\t\n\t\t}\n\t}\n\n```\n\n```java\n\n\tpublic class StudentsCollectionRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cStudent\u003e students = List.of(new Student(1, \"Ranga\"),\n\t\t\t\t\t\t\t\t\t\t\tnew Student(100, \"Adam\"),\n\t\t\t\t\t\t\t\t\t\t\tnew Student(2, \"Eve\"));\n\t\t\tArrayList\u003cStudent\u003e studentsAl = new ArrayList\u003c\u003e(students);\n\t\t\tSystem.out.println(studentsAl);\t\t\t\n\t\t\tCollections.sort(studentsAl);\n\t\t\tSystem.out.println(\"Ascending : \" + studentsAl);\n\t\t\tCollections.sort(studentsAl, new DescStudentComparator());\n\t\t\tSystem.out.println(\"Descending : \" studentsAl);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_[1 Ranga, 100 Adam, 2 Eve]_\n\n_Ascending : [1 Ranga, 2 Eve, 100 Adam]_\n\n_Descending : [100 Adam, 2 Eve, 1 Ranga]_\n\n#### ```sort``` method Of ```List```\n\nYou can call `sort` method on the `List` by passing it a `Comparator` implementation - `studentsAl.sort(new AscStudentComparator())`.\n\n##### Snippet-12 : Comparator for ArrayList.sort()\n\n\n**_StudentsCollectionRunner.java_**\n\n```java\n\n\tpackage collections;\n\timport java.util.Collections;\n\timport java.util.List;\n\timport java.util.ArrayList;\n\timport java.util.Comparator;\n\n\tpublic class StudentsCollectionRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cStudent\u003e students = List.of(new Student(1, \"Ranga\"),\n\t\t\t\t\t\t\t\t\t\t\tnew Student(100, \"Adam\"),\n\t\t\t\t\t\t\t\t\t\t\tnew Student(2, \"Eve\"));\n\n\t\t\tArrayList\u003cStudent\u003e studentsAl = new ArrayList\u003c\u003e(students);\n\t\t\tSystem.out.println(studentsAl);\n\t\t\tstudentsAl.sort(new AscStudentComparator());\n\t\t\tSystem.out.println(\"Asc : \" + studentsAl);\t\t\t\n\t\t\tstudentsAl.sort(new DescStudentComparator());\n\t\t\tSystem.out.println(\"Desc : \" + studentsAl);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_[1 Ranga, 100 Adam, 2 Eve]_\n\n_Asc : [1 Ranga, 2 Eve, 100 Adam]_\n\n_Desc : [100 Adam, 2 Eve, 1 Ranga]_\n\n### The ```Set``` ```interface```\n\nMathematically, a set is a collection of unique items. Similarly, the Java ```Set``` ```interface``` also specifies a contract for collections having unique elements.\n* If ```object1.equals(object2)``` returns ```true```, then only one of ```object1``` and ```object2``` have a place in a ```Set``` implementation.\n\nThere is no positional element access provided by the ```Set``` implementations.\n\n##### Snippet-13 : Set\n\nLet's look at a few examples:\n\nThe collection returned by ```Set.of()``` is immutable, hence does not support the ```add()```  method. \n\n```java\n\n\tjshell\u003e Set\u003cString\u003e set = Set.of(\"Apple\", \"Banana\", Cat\");\n\tset ==\u003e [Banana, Apple, Cat]\n```\n\n\nCreate a ```HashSet``` collection instead, which supports the ```add()```, in order to test the uniqueness property of a ```Set```.\n\n\n\n```java\n\tjshell\u003e set.add(\"Apple\");\n\t| java.lang.UnsupportedOperationException thrown:\n\tjshell\u003e Set\u003cString\u003e hashSet = new HashSet\u003c\u003e(set);\n\thashSet ==\u003e [Apple, Cat, Banana]\n```\n\nThe ```HashSet.add()``` operation returns a ```false``` value, indicating that inserting a duplicate \"Apple\" entry has failed.\n\n```java\n\tjshell\u003e hashSet.add(\"Apple\");\n\t$1 ==\u003e false\n\tjshell\u003e hashSet\n\thashSet ==\u003e [Apple, Cat, Banana]\n```\n\nNote that when the ```hashSet``` was constructed using the ```set```, the order of the elements got permuted/changed. Also originally, when we created the ```set``` from the ```Set.of()``` method, the order printed was different from the order of initialization. This confirms the fact that a ```Set``` collection does not give any importance to element order, and therefore, does not support positional access. Hence, the compiler error on call to ```hashSet.add(int, String)```.\n\n```java\n\tjshell\u003e hashSet.add(2, \"Apple\");\n\t| Error:\n\t| no suitable method found for add(int, java.lang.String)\n\t| hashSet.add(2, \"Apple\");\n\t|^----------^\n\tjshell\u003e\n\n```\n\n#### Understanding Data Structures\n\n##### Hash Table\n* Hash Table: A data structure that attempts to combine the best of both worlds:\t\n\t* Very efficient element access\n\t* Very efficient element insertion and deletion \n* Buckets : They are the slots in the hash table, into which elements are inserted and chained together. As you can see, a hash table is effectively a large array of buckets, each containing a small linked list.\n* Hashing: A procedure called **hashing** used in the construction of the Hash Table. The term **hash** generally means *mix up the order of elements*.\n* Hashing Function: A formula to determine/compute which bucket a particular element gets inserted into. For illustration: ```hash(elem)``` could compute ```elem mod 13``` mathematically, and uses that value to index into the table, to locate the bucket insertion. The ```Object.hashCode()``` could be used as a hashing function.\n* Collisions: Leads to chaining within a bucket, where a linked list grows. The larger the table, and the cleverer the hashing function, the lesser the chance for collisions.\n\n##### Tree\n* Tree: Stores elements in sorted order. For every node in the tree, elements of all nodes in its left sub-tree are lesser than its contained element. Conversely, elements of all nodes in its right sub-tree are greater than its contained element.\n* Insertions: Given any node, we know by comparing the new element with the node's element, where to go about inserting it, to maintain sorted order.\n* Access : More efficient than linked lists.\n\n#### ```Set``` Implementations\n\n* HashSet\n* LinkedHashSet\n* TreeSet\n\n##### Snippet-14 : HashSet\n\nIn a ```HashSet```, elements are neither stored in the order of insertion, nor in sorted order.\n\n```java\n\n\tjshell\u003e Set\u003cInteger\u003e numbers = new HashSet\u003c\u003e();\n\tnumbers ==\u003e []\n\tjshell\u003e numbers.add(765432);\n\t$1 ==\u003e true\n\tjshell\u003e numbers.add(76543);\n\t$2 ==\u003e true\n\tjshell\u003e numbers.add(7654);\n\t$3 ==\u003e true\n\tjshell\u003e numbers.add(765);\n\t$4 ==\u003e true\n\tjshell\u003e numbers.add(76);\n\t$5 ==\u003e true\n\tjshell\u003e numbers\n\tnumbers ==\u003e [765432, 7654, 76, 765, 76543]\n\tjshell\u003e\n\n```\n##### Snippet-15 : LinkedHashSet\n\nIn a ```LinkedHashSet```, elements are stored in the order of insertion.\n\n```java\n\n\tjshell\u003e Set\u003cInteger\u003e numbers = new LinkedHashSet\u003c\u003e();\n\tnumbers ==\u003e []\n\tjshell\u003e numbers.add(765432);\n\t$1 ==\u003e true\n\tjshell\u003e numbers.add(76543);\n\t$2 ==\u003e true\n\tjshell\u003e numbers.add(7654);\n\t$3 ==\u003e true\n\tjshell\u003e numbers.add(765);\n\t$4 ==\u003e true\n\tjshell\u003e numbers.add(76);\n\t$5 ==\u003e true\n\tjshell\u003e numbers\n\tnumbers ==\u003e [765432, 76543, 7654, 765, 76]\n\tjshell\u003e numbers.add(7654321);\n\t$5 ==\u003e true\n\tjshell\u003e numbers\n\tnumbers ==\u003e [765432, 76543, 7654, 765, **7654321**]\n\tjshell\u003e\n\n```\n\n##### Snippet-16 : TreeSet\n- - - \n\nIn a ```TreeSet```, elements are stored in sorted order.\n\n```java\n\n\tjshell\u003e Set\u003cInteger\u003e numbers = new TreeSet\u003c\u003e();\n\tnumbers ==\u003e []\n\tjshell\u003e numbers.add(765432);\n\t$1 ==\u003e true\n\tjshell\u003e numbers.add(76543);\n\t$2 ==\u003e true\n\tjshell\u003e numbers.add(7654);\n\t$3 ==\u003e true\n\tjshell\u003e numbers.add(765);\n\t$4 ==\u003e true\n\tjshell\u003e numbers.add(76);\n\t$5 ==\u003e true\n\tjshell\u003e numbers\n\tnumbers ==\u003e [76, 765, 7654, 76543, 765432]\n\tjshell\u003e numbers.add(7);\n\t$5 ==\u003e true\n\tjshell\u003e numbers\n\tnumbers ==\u003e [**7**, 76, 765, 7654, 76543, 765432]\n\tjshell\u003e\n\n```\n#### Exercise Set\n- - - \n1. Create a ```List`` of characters, such as:\n\n\t```List\u003cCharacter\u003e list = List.of('A', 'Z', 'A', 'B', 'Z, 'F);```\n\n* Write a procedure to list out the unique characters in this list\n* Write a procedure to list out these unique characters in sorted order\n* Write a procedure to list out these unique characters in the order in which they were present in the original list \n#### Solution\n\n**_SetRunner.java_**\n\n```java\n\n\tpackage collections;\n\timport java.util.List;\n\timport java .util.Set;\n\timport java.util.HashSet;\n\timport java.util.LinkedHashSet;\n\timport java.util.TreeSet;\n\n\tpublic class SetRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cCharacter\u003e characters = List.of('A', 'Z', 'A', 'B', 'Z, 'F);\n\t\t\tSet\u003cCharacter\u003e hashSetChars = new HashSet\u003c\u003e(characters);\n\t\t\tSystem.out.println(\"Unique Characters: \" + hashSetChars);\n\t\t\tSet\u003cCharacter\u003e treeSetChars = new TreeSet\u003c\u003e(characters);\n\t\t\tSystem.out.println(\"Sorted Order: \" + treeSetChars);\t\t\t\n\t\t\tSet\u003cCharacter\u003e linkedSetChars = new LinkedHashSet\u003c\u003e(characters);\n\t\t\tSystem.out.println(\"Inserted Order: \" + linkedSetChars);  \n\t\t}\t\n\t}\n\n``` \n\n**_Console Output_**\n\n_Unique Characters: [A, B, F, Z]_\n\n_Sorted Order: [A, B, F, Z]_\n\n_Inserted Order: [A, Z, B, F]_\n\n#### Solution Explained\n\nIn this example, the order to elements traversed in ```hashSetChars``` happened to be the same as that in ```treeSetChars```. Such an order is not always guaranteed, as we saw in the earlier examples.\n\n#### ```TreeSet``` In Depth\n\n* Super-Interfaces\n\t* Set\n\t* NavigableSet\n\n##### Snippet-16 : NavigableSet Operations\n\nLet's look at few operations:\n\n```java\n\n\tjshell\u003e TreeSet\u003cInteger\u003e numbers = new TreeSet\u003c\u003e(Set.of(65, 54, 34, 12, 99));\n\tnumbers ==\u003e [12, 34, 54, 65, 99]\n\tjshell\u003e numbers.floor(40);\n\t$1 ==\u003e 34\n```\n```floor()``` method is inclusive, ```lower()``` is exclusive\n\n```java\n\tjshell\u003e numbers.floor(34);\n\t$2 ==\u003e 34\n\tjshell\u003e numbers.lower(34);\n\t$3 ==\u003e 12\n```\n\n```ceiling()``` method is inclusive, ```higher()``` is exclusive\n\n```java\n\tjshell\u003e numbers.ceiling(36);\n\t$4 ==\u003e 54\n\tjshell\u003e numbers.ceiling(34);\n\t$5 ==\u003e 34\n\tjshell\u003e numbers.higher(34);\n\t$6 ==\u003e 54\n```\n\n```subSet(Object, Object)``` method is only lower-inclusive. So, the left bound is like ```lower()```, and right bound is like ```higher()```. The overloaded version ```subSet(Object, boolean, Object, boolean)``` can be used to configure lower- and upper inclusiveness of the returned subset.\n\n```java\n\tjshell\u003e numbers.subSet(20, 80);\n\t$7 ==\u003e [34, 54, 65]\n\tjshell\u003e numbers.subSet(34, 54);\n\t$8 ==\u003e [34]\n\tjshell\u003e numbers.subSet(34, 65);\n\t$9 ==\u003e [34, 54]\n\tjshell\u003e numbers.subSet(34, true, 65, true);\n\t$10 ==\u003e [34, 54, 65]\n\tjshell\u003e numbers.subSet(34, false, 65, false);\n\t$11 ==\u003e [54]\n```\n\n```headSet()``` returns the subset of elements preceding the given element value. ```tailsSet()``` returns the subset of elements succeeding the given element value\n```java\n\tjshell\u003e numbers.headSet(50);\n\t$12 ==\u003e [12, 34]\n\tjshell\u003e numbers.tailSet(50);\n\t$13 ==\u003e [54, 65, 99]\n\tjshell\u003e\n\n```\n\n#### The ```Queue``` Interface\n\n```Queue``` ```interface``` : ```extends``` the ```Collection``` ```interface```. \n* Elements are arranged in order of processing, such as in a To-Do List.\n\n#### The ```PriorityQueue``` Collection\n\nThe ```PriorityQueue``` collection is a built-in Java ```class```, that ```implements``` the ```Queue``` ```interface```. Elements are stored in a sorted natural order, by default. We can also specify a different custom order, called the *order of priority* (customized by the programmer).\n\n##### Snippet-17 : PriorityQueue\n\nThe ```PriorityQueue``` ```queue``` stores the strings in ascending alphabetic order by default. \n\n* ```queue.poll()``` de-queue's the element at the beginning of the natural order \n\n\n```java\n\n\tjshell\u003e Queue\u003cString\u003e queue = new PriorityQueue\u003c\u003e();\n\tnumbers ==\u003e [12, 34, 54, 65, 99]\n\tjshell\u003e queue.poll();\n\t$1 ==\u003e null\n\tjshell\u003e queue.offer(\"Apple\");\n\t$2 ==\u003e true\n\tjshell\u003e queue.addAll(List.of(\"Zebra\", \"Monkey\", \"Cat\"));\n\t$3 ==\u003e true\n\tjshell\u003e queue\n\tqueue ==\u003e [Apple, Cat, Monkey, Zebra]\n\tjshell\u003e queue.poll();\n\t$4 ==\u003e \"Apple\"\n\tjshell\u003e queue\n\tqueue ==\u003e [Cat, Monkey, Zebra]\n\tjshell\u003e queue.poll();\n\t$5 ==\u003e \"Cat\"\n\tjshell\u003e queue.poll();\n\t$6 ==\u003e \"Monkey\"\n\tjshell\u003e queue.poll();\n\t$7 ==\u003e \"Zebra\"\n\tjshell\u003e queue.poll();\n\t$8 ==\u003e null\n\tjshell\u003e\n\n```\n\n##### Snippet-18 : Custom Priority PriorityQueue\n\nA custom priority order on the elements in a PriorityQueue can be specified by passing an implementation of ```Comparator\u003c? super T\u003e``` ```interface``` to the ```PriorityQueue\u003cT\u003e``` constructor. \n\nLet's implement a `StringLengthComparator`.\n\n**_QueueRunner.java_**\n\n```java\n\n\tpackage collections;\n\timport java.util.Comparator;\n\timport java.util.List;\n\timport java.util.Queue;\n\timport java.util.PriorityQueue;\n\n\tclass StringLengthComparator implements Comparator\u003cString\u003e {\n\t\t@Override\n\t\tpublic int compare(String left, String right) {\n\t\t\treturn Integer.compare(left.length(), right.length());\n\t\t}\n\t}\n\n\tpublic class QueueRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tQueue\u003cString\u003e queue = new PriorityQueue\u003c\u003e(new StringLengthComparator());\n\t\t\tqueue.addAll(List.of(\"Zebra\", \"Monkey\", \"Cat\"));\n\t\t\tqueue.poll();\n\t\t\tqueue.poll();\n\t\t\tqueue.poll();\n\t\t\tqueue.poll();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Cat_\n\n_Zebra_\n\n_Monkey_\n\n_null_\n\n\n#### The ```Map``` ```interface```\nThe ```Map``` ```interface``` specifies a contract to implement collections of elements, that are in the form of ```(key, value)``` pairs.  \n\nLet's say you want to store how many times a character is repeated in a sequence of characters.\n* If the sequence inserted is: ```{'A', 'C', 'A', 'C', 'E', 'C', 'M', 'D', 'H', 'A'}```\n* The map contents would end up being: ```{('A', 3), ('C', 3), ('E', 1), ('M', 1), ('D', 1), ('H', 1)}```.\n\nSince the kind of elements stored in a map (```(key, value)``` pairs)  are different from any other collection categories in Java, the ```Map``` ```interface``` is unique. So unique, that it even does not extend the ```Collection``` ```interface```! \n\nThe ```interface``` definition looks something like:\n\n```java\n\n\tpublic interface Map\u003cK, V\u003e {\n\n\t\t//Method Declarations\n\n\t}\n\n```\n\n* The Java collection classes that ```implement``` the ```Map``` ```interface``` are:\n\t* ```HashMap```\n\t* ```HashTable```\n\t* ```LinkedHashMap```\n\t* ```TreeMap```\n\n#### ```Map``` Collections : Concepts\n\n* ```HashMap```\n\t* Unordered\n\t* Unsorted\n\t* Key's ```hashCode()``` value is used in the hashing function\n\t* Allows a key with a ```null``` value.\n\n* ```HashTable```\n\t* Thread-safe version of ```HashMap```. Has ```synchronized``` methods where required.\n\t* Unordered\n\t* Unsorted\n\t* Key's ```hashCode()``` value is used in the hashing function\n\t* Does not allow a ```null``` key.\n\n* ```LinkedHashMap```\n\t* Insertion order of elements is maintained (which is optional as well)\n\t* Unsorted\n\t* Iteration is faster\n\t* Insertion and Deletion are slower\n\n* ```TreeMap```\n\t* Additionally implements the ```NavigableMap``` ```interface```\n\t* Elements are maintained in sorted order of keys\n\n#### ```Map``` ```interface``` : Basic Operations\n\n##### Snippet-19 : Basic Map Operations\n\nThe ```Map.of()``` method takes a sequence of objects, which are interpreted as being key and value entries in alternation. \n* The total number of arguments is expected to be an even number. \n* This method creates an immutable ```Map```, with the ```(key, value)``` pairs in no specific order.\n\n\n```java\n\n\tjshell\u003e Map\u003cString, Integer\u003e map = Map.of(\"A\", 3, \"B\", 5, \"Z\", 10);\n\tmap ==\u003e {Z=10, A=3, B=5}\n\tjshell\u003e map.get(\"Z\");\n\t$1 ==\u003e 10\n\tjshell\u003e map.get(\"A\");\n\t$2 ==\u003e 3\n\tjshell\u003e map.get(\"C\");\n\t$3 ==\u003e null\n\tjshell\u003e map.size();\n\t$4 ==\u003e 3\n\tjshell\u003e map.isEmpty();\n\t$5 ==\u003e false\n\tjshell\u003e map.containsKey(\"A\");\n\t$6 ==\u003e true\n\tjshell\u003e map.containsKey(\"F\");\n\t$7 ==\u003e false\n\tjshell\u003e map.containsValue(3);\n\t$8 ==\u003e true\n\tjshell\u003e map.containsValue(4);\n\t$9 ==\u003e false\n\tjshell\u003e map.keySet();\n\t$10 ==\u003e [Z, A, B]\n\tjshell\u003e map.values();\n\t$11 ==\u003e [10, 3, 5]\n\tjshell\u003e\n\n```\n\n##### Snippet-20 : Mutable Maps\n\nTo be able to add values to a map, let's create a `HashMap`.\n\n```java\n\n\tjshell\u003e Map\u003cString, Integer\u003e map = Map.of(\"A\", 3, \"B\", 5, \"Z\", 10);\n\tmap ==\u003e {Z=10, A=3, B=5}\n\tjshell\u003e Map\u003cString, Integer\u003e hashMap = new HashMap\u003c\u003e(map);\n\thashMap ==\u003e {A=3, Z=10, B=5}\n\tjshell\u003e hashMap.put(\"F\", 5);\n\t$1 ==\u003e null\n\tjshell\u003e hashMap\n\thashMap ==\u003e {A=3, Z=10, B=5, F=5}\n\tjshell\u003e hashMap.put(\"Z\", 11);\n\t$2 ==\u003e 10\n\tjshell\u003e hashMap\n\thashMap ==\u003e {A=3, Z=11, B=5, F=5}\n\tjshell\u003e\n\n```\n\n#### ```Map``` Collections: Comparing Operations\n##### Snippet-21 : ```Map``` Implementations\n\n```HashMap``` elements are not guaranteed to be stored either in inserted order, or in the sorted order of keys.\n\n```java\n\n\tjshell\u003e HashMap\u003cString, Integer\u003e hashMap = new HashMap\u003c\u003e();\n\thashMap ==\u003e {}\n\tjshell\u003e hashMap.put(\"Z\", 5);\n\t$1 ==\u003e null\n\tjshell\u003e hashMap.put(\"A\", 15);\n\t$2 ==\u003e null\n\tjshell\u003e hashMap.put(\"F\", 25);\n\t$3 ==\u003e null\n\tjshell\u003e hashMap.put(\"L\", 250);\n\t$4 ==\u003e null\n\tjshell\u003e hashMap\n\thashMap ==\u003e {A=15, F=25, Z=5, L=250}\n```\n\n```LinkedHashMap``` elements are stored in inserted order.\n```java\n\tjshell\u003e LinkedHashMap\u003cString, Integer\u003e linkedHashMap = new LinkedHashMap\u003c\u003e();\n\tlinkedHashMap ==\u003e {}\n\tjshell\u003e linkedHashMap.put(\"Z\", 5);\n\t$5 ==\u003e null\n\tjshell\u003e linkedHashMap.put(\"A\", 15);\n\t$6 ==\u003e null\n\tjshell\u003e linkedHashMap.put(\"F\", 25);\n\t$7 ==\u003e null\n\tjshell\u003e linkedHashMap.put(\"L\", 250);\n\t$8 ==\u003e null\n\tjshell\u003e linkedHashMap\n\thashMap ==\u003e {Z=5, A=15, F=25, L=250}\n```\n\n```TreeMap``` elements are stored in the natural sorted order of the keys.\n\n\n```java\t\n\tjshell\u003e TreeMap\u003cString, Integer\u003e treeMap = new TreeMap\u003c\u003e();\n\ttreeMap ==\u003e {}\n\tjshell\u003e treeMap.put(\"Z\", 5);\n\t$9 ==\u003e null\n\tjshell\u003e treeMap.put(\"A\", 15);\n\t$10 ==\u003e null\n\tjshell\u003e treeMap.put(\"F\", 25);\n\t$11 ==\u003e null\n\tjshell\u003e treeMap.put(\"L\", 250);\n\t$12 ==\u003e null\n\tjshell\u003e treeMap\n\ttreeMap ==\u003e {A=15, F=25, L=250, Z=5}\n\tjshell\u003e\n\n```\n\n#### Exercise Set\n1. Given the string:  ```\"This is an awesome occassion. This has never happened before.\"```, do the following processing on it:\n\t* Find the number of occurrences of each unique character in this string\n\t* Find the number of occurrences of each unique word in this string\n#### Solution\n\n**_MapRunner.java_**\n\n```java\n\n\tpackage collections;\n\timport java.util.Map;\n\timport java.util.HashMap;\n\n\tpublic class MapRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tString str = \"This is an awesome occassion. This has never happened before.\";\n\t\t\tchar[] characters = str.toCharArray();\n\t\t\tMap\u003cCharacter, Integer\u003e occurrences = new HashMap\u003c\u003e();\n\t\t\tfor(char character:characters) {\n\t\t\t\tInteger count = occurrences.get(character);\t\t\t\n\t\t\t\tif(count == null) {\n\t\t\t\t\toccurrences.put(character, 1);\n\t\t\t\t} else {\n\t\t\t\t\toccurrences.put(character, count+1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tSystem.out.println(occurrences);\n\t\t\tString words = text.split(\" \");\n\t\t\tMap\u003cString, Integer\u003e frequency = new HashMap\u003c\u003e();\n\t\t\tfor(String word:words) {\n\t\t\t\tInteger number = frequency.get(word);\n\t\t\t\tif(number == null) {\n\t\t\t\t\tfrequency.put(word, 1);\n\t\t\t\t} else {\n\t\t\t\t\tfrequency.put(word, number+1);\n\t\t\t\t}\n\t\t\t}\n\t\t\tSystem.out.println(frequency);\n\t\t}\n\t}\n\n```\n\n#### Revisiting ```TreeMap```\nLet's look at some more interesting operations of Data Structures based on ```TreeMap```.\n##### Snippet-13 : Treemap Operations\n\nEntries in a ```TreeMap``` are always sorted. \n\n```java\n\njshell\u003e TreeMap\u003cString, Integer\u003e treeMap = new TreeMap\u003c\u003e();\ntreeMap ==\u003e {}\njshell\u003e treeMap.put(\"F\", 25);\n$1 ==\u003e null\njshell\u003e treeMap.put(\"Z\", 5);\n$2 ==\u003e null\njshell\u003e treeMap.put(\"L\", 250);\n$3 ==\u003e null\njshell\u003e treeMap.put(\"A\", 15);\n$4 ==\u003e null\njshell\u003e treeMap.put(\"B\", 25)\n$5 ==\u003e null\njshell\u003e treeMap.put(\"G\", 25);\n$6 ==\u003e null\njshell\u003e treeMap\ntreeMap ==\u003e {A=15, B=25, F=25, G=25, L=250, Z=5}\n```\n\n`TreeMap` implements ```NavigableMap``` ```interface``` as well.\n\n```java\njshell\u003e treeMap.higherKey(\"B\");\n$7 ==\u003e \"F\"\njshell\u003e treeMap.higherKey(\"C\");\n$8 ==\u003e \"F\"\njshell\u003e treeMap.ceilingKey(\"B\");\n$9 ==\u003e \"B\"\njshell\u003e treeMap.ceilingKey(\"C\");\n$10 ==\u003e \"F\"\njshell\u003e treeMap.lowerKey(\"B\");\n$11 ==\u003e \"A\"\njshell\u003e treeMap.floorKey(\"B\");\n$12 ==\u003e \"B\"\njshell\u003e treeMap.firstEntry();\n$713 ==\u003e A=15\njshell\u003e treeMap.lastentry();\n$14 ==\u003e Z=5\njshell\u003e treeMap.subMap(\"C\", \"Y\");\n$7 ==\u003e {F=25, G=25, L=250}\njshell\u003e treeMap.subMap(\"B\", \"Z\");\n$7 ==\u003e {B=25, F=25, G=25, L=250}\njshell\u003e treeMap.subMap(\"B\", true, \"Z\", true);\n$7 ==\u003e {B=25, F=25, G=25, L=250, Z=5}\njshell\u003e\n\n```\n\n#### Java Collections : Conclusions With Tips\n\nThe collection interfaces we have explored, as well as their implementation classes, are:\n* ```List```\n* ```Set```\n* ```Queue```\n* ```Map```\n\nLet's quickly review what we've learnt:\n* When you use a \"Hashed\" Java collection (hash table based), such as ```HashMap``` or ```HashSet```, it will be unordered, unsorted and will iterate over its elements in no particular order.\n* When you encounter a \"Linked\" Java collection (linked list based), such as a ```LinkedHashSet``` or a ```LinkedHashMap```, it will maintain insertion order, but will be unsorted. \n* When we make use of a \"Tree\"-based Java collection (stored in a tree data structure), such as ```TreeSet``` or ```TreeMap``` it always maintains natural sorted order. It would implement one of the navigable category of interfaces, such as ```NavigableSet``` or ```NavigableMap```.\n\n## Introducing Generics\n\nRecommended Videos\n- Generics - https://www.youtube.com/watch?v=v4o0wyFPwEs\n\nWhy do we need Generics? \n\nLet's look at a scenario where want to write a wrapper class around the ```ArrayList``` data structure, maybe to do some better custom error-checking and stuff. For now, we will just look at basic wrapper functionality, the error checking intent is just an excuse!\n\n##### Snippet-1\n\n**_GenericsRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.generics;\n\timport com.in28minutes.generics.MyCustomList;\n\t\n\tpublic class GenericsRunner {\n\t\tpublic static void main(String[] args) {\n\t\tMyCustomList list = new MyCustomList();\n\t\tlist.addElement(\"Element-1\");\n\t\tlist.addElement(\"Element-2\");\n\t\tlist.addElement(\"Element-3\");\n\t\t}\n\t}\n\n```\n\n\n**_MyCustomList.java_**\n\n```java\n\n\tpackage com.in28minutes.generics;\n\n\tpublic class MyCustomList {\n\t\tArrayList\u003cString\u003e list = new ArrayList\u003c\u003e();\n\t\t\n\t\tpublic void addElement(String element) {\n\t\t\tlist.add(element);\n\t\t}\n\n\t\tpublic void removeElement(String element) {\n\t\t\tlist.remove(element);\n\t\t}\n\t}\n\n```\n\n##### Snippet-1 Explained\n\nThe ```MyCustomList``` ```class``` is a wrapper for ```ArrayList``` of ```String```s. Insertion and deletion of elements into this data structure is straightforward. \n\nLet's sy I would want to create `MyCustomList` for other types. Should we write additional wrapper classes ```MyCustomList``` and so on?\n\nLet's look at an example:\n\n##### Snippet-2 : Implementing a Generic\n\n**_MyCustomList.java_**\n\n```java\n\n\tpackage com.in28minutes.generics;\n\t\n\tpublic class MyCustomList\u003cT\u003e {\n\t\tArrayList\u003cT\u003e list = new ArrayList\u003c\u003e();\n\t\t\n\t\tpublic void addElement(T element) {\n\t\t\tlist.add(element);\n\t\t}\n\n\t\tpublic void removeElement(T element) {\n\t\t\tlist.remove(element);\n\t\t}\n\n\t\tpublic String toString() {\n\t\t\treturn list.toString();\n\t\t}\n\t}\n\n```\n\n**_GenericsRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.generics;\n\timport com.in28minutes.generics.MyCustomList;\n\n\tpublic class GenericsRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMyCustomList\u003cString\u003e list = new MyCustomList\u003c\u003e();\n\t\t\tlist.addElement(\"Element-1\");\t\t\t\n\t\t\tlist.addElement(\"Element-2\");\n\t\t\tSystem.out.println(list);\t\t\t\n\t\t\t\n\t\t\tMyCustomList\u003cInteger\u003e list2 = new MyCustomList\u003c\u003e();\t\t\t\n\t\t\tlist2.addElement(Integer.valueOf(5));\n\t\t\tlist2.addElement(Integer.valueOf(9));\n\t\t\tSystem.out.println(list2);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_[Element-1, Element-2]_\n\n_[5, 9]_\n\n##### Snippet-2 Explained\n\nThe identifier ```T``` in the definition of the Generic ```class``` ```MyCustomList\u003cT\u003e``` is a placeholder for the actual type of the container. It is this placeholder that truly converts the ```MyCustomList``` ```class``` into a template.\n\nThe naming convention for these type placeholders is:\n\t* Always use UpperCase letters of the alphabet (such as ```T```, or ```S```), or\n\t* intuitive words such as ```TYPE```\n\nAt the time of actual instantiation of ```MyCustomList``` inside ```GenericsRunner.main```, this placeholder is substituted by the actual type:\n* When ```MyCustomList\u003cString\u003e list``` is created, ```T``` is substituted by ```String```\n* When ```MyCustomList\u003cInteger\u003e list2``` is created, ```T``` is substituted by ```Integer```\n\n#### Exercise Set - 18\n1. Write a method ```get``` inside the generic class ```MyCustomList```, which returns the element at a particular index (passed as argument) in its list storage.\n#### Solution\n\n**_MyCustomList.java_**\n\n```java\n\n\tpackage com.in28minutes.generics;\n\n\tpublic class MyCustomList\u003cT\u003e {\n\t\tArrayList\u003cT\u003e list = new ArrayList\u003c\u003e();\n\t\t\n\t\tpublic void addElement(T element) {\n\t\t\tlist.add(element);\n\t\t}\n\n\t\tpublic void removeElement(T element) {\n\t\t\tlist.remove(element);\n\t\t}\n\n\t\tpublic String toString() {\n\t\t\treturn list.toString();\n\t\t}\n\n\t\tpublic T get(int index) {\n\t\t\treturn list.get(index);\n\t\t}\n\t}\n\n```\n\n**_GenericsRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.generics;\n\timport com.in28minutes.generics.MyCustomList;\n\n\tpublic class GenericsRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tMyCustomList\u003cString\u003e list = new MyCustomList\u003c\u003e();\n\t\t\tlist.addElement(\"Element-1\");\n\t\t\tlist.addElement(\"Element-2\");\t\t\t\n\t\t\tString text = list.get(0);\n\t\t\tSystem.out.println(text);\n\n\t\t\tMyCustomList\u003cInteger\u003e list2 = new MyCustomList\u003c\u003e();\n\t\t\tlist2.addElement(Integer.valueOf(5));\n\t\t\tlist2.addElement(Integer.valueOf(9));\n\t\t\tInteger num = list2.get(1);\n\t\t\tSystem.out.println(num);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Element-1_\n\n_9_\n\n#### Solution Explained\n\nWe have defined a method ```MyCustomList\u003cT\u003e.get``` whose return type is generic as well. The return type has the same placeholder ```T``` as the template in the definition of ```MyCustomList\u003cT\u003e```.\n* For ```MyCustomList\u003cString\u003e list```, ```list.get``` returns a ```String```\n* For ```MyCustomList\u003cInteger\u003e list2```, ```list2.get``` returns an ```Integer```\n\n#### Implementing Type Restrictions on Generics\n\nWe saw above that we could use ```MyCustomList\u003cT\u003e``` to be instantiated into data structures for storing ```String```s as well as for ```Integer```s. \n\nWhat if we wanted to to use ```MyCustomList\u003cT\u003e``` purely for storing numeric values?\n\n##### Snippet-3 : Generic Type Restrictions\n\n**_MyCustomList.java_**\n\n```java\n\n\tpackage com.in28minutes.generics;\n\n\tpublic class MyCustomList\u003cT extends Number\u003e {\n\t\tArrayList\u003cT\u003e list = new ArrayList\u003c\u003e();\n\t\t\n\t\tpublic void addElement(T element) {\n\t\t\tlist.add(element);\n\t\t}\n\n\t\tpublic void removeElement(T element) {\n\t\t\tlist.remove(element);\n\t\t}\n\n\t\tpublic String toString() {\n\t\t\treturn list.toString();\n\t\t}\n\n\t\tpublic T get(int index) {\n\t\t\treturn list.get(index);\n\t\t}\n\t}\n\n```\n\n**_GenericsRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.generics;\n\timport com.in28minutes.generics.MyCustomList;\n\n\tpublic class GenericsRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\t//MyCustomList\u003cString\u003e list = new MyCustomList\u003c\u003e();\n\t\t\tMyCustomList\u003cLong\u003e list1 = new MyCustomList\u003c\u003e();\n\t\t\tlist1.addElement(5l);\n\t\t\tlist1.addElement(7l);\n\t\t\tLong long = list1.get(0);\t\t\t\n\t\t\tSystem.out.println(long);\n\n\t\t\tMyCustomList\u003cInteger\u003e list2 = new MyCustomList\u003c\u003e();\n\t\t\tlist2.addElement(Integer.valueOf(5));\n\t\t\tlist2.addElement(Integer.valueOf(9));\n\t\t\tInteger num = list2.get(1);\n\t\t\tSystem.out.println(num);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_5_\n\n_9_\n\nWhen we specify `T extends Number` as the type, we can use all the methods in the API of ```class``` ```Number``` are available for use. \n\n#### Generic Methods\nWe can create generic methods as well. Let's look at a few examples:\n\n##### Snippet-4 : Generic Method\n\n**_GenericsRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.generics;\n\timport com.in28minutes.generics.MyCustomList;\n\n\tpublic class GenericsRunner {\n\t\tstatic \u003cX\u003e X doSomething(X value) {\n\t\t\treturn value;\n\t\t}\n\n\t\tstatic \u003cX extends List\u003e void duplicate(X list) {\n\t\t\tlist.add(list);\n\t\t}\n\n\t\tpublic static void main(String[] args) {\n\t\t\tString text = doSomething(\"Hello\");\n\t\t\tInteger value = doSomething(Integer.valueOf(7));\n\t\t\tArrayList\u003cString\u003e list = doSomething(new ArrayList\u003cString\u003e(List.of(\"A\", \"B\", C\")));\n\t\t\tduplicate(list);\n\t\t\tSystem.out.println(list);\t\t\t\n\t\t\tLinkedList\u003cInteger\u003e list2 = doSomething(new LinkedList\u003cString\u003e(List.of(1, 2, 3)));\n\t\t\tduplicate(list2);\n\t\t\tSystem.out.println(list2);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_[A, B, C, A, B, C]_\n\n_[1, 2, 3, 1, 2, 3]_\n\n#### Generics And Wild-Cards \n\nYou can use wild card with generics too - `? extends Number`\n\n##### Snippet-5\n\n**_GenericsRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.generics;\n\timport com.in28minutes.generics.MyCustomList;\n\n\tpublic class GenericsRunner {\n\t\tstatic double sumOfNumberList(List\u003c? extends Number\u003e numbers) {\n\t\t\tdouble sum = 0.0;\t\t\t\n\t\t\tfor(Number number:numbers) {\n\t\t\t\tsum += number;\n\t\t\t}\n\t\t\treturn sum;\n\t\t}\n\n\t\tpublic static void main(String[] args) {\n\t\t\tSystem.out.println(sumOfNumberList(List.of(1, 2, 3, 4, 5)));\n\t\t\tSystem.out.println(sumOfNumberList(List.of(1.1, 2.1, 3.1, 4.1, 5.1)));\n\t\t\tSystem.out.println(sumOfNumberList(List.of(1l, 2l, 3l, 4l, 5l)));\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_15.0_\n\n_15.5_\n\n_15.0_\n\n##### Snippet-5 Explained\nThe symbol ```?``` in the definition of the method ```static double sumOfNumberList(List\u003c? extends Number\u003e numbers)``` is the **wild-card** symbol. It denotes the fact that in order to be a valid argument to ```sumOfNumberList```, ```numbers``` can be a ```List``` of any elements, so long as all of them are of type sub-classed from ```Number```. \n* This includes ```Integer```, ```Long```, ```Short```, ```Byte```, ```Float``` and ```Double```. \n* It also includes their primitive type counterparts, since they can be converted implicitly to their Wrapper class counterparts. \n* Of course, all these elements of ```List``` ```numbers``` need to be of a homogeneous type.\n\n#### Restricted Heterogeneous Lists\n\nThe generic wildcard we saw in the previous section is referred to as a **Upper-Bounded Wild-Card**. It can be used to specify homogeneous types with a restriction. There is another category of wild-cards called **Lower-Bounded Wild-Card**, which can be used with create **Heterogeneous** types of elements , within the restriction. Here is an example.\n\n##### Snippet-6 : More wild-cards\n\n**_GenericsRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.generics;\n\timport com.in28minutes.generics.MyCustomList;\n\n\tpublic class GenericsRunner {\n\t\tstatic void addAFewNumbers(List\u003c? super Number\u003e numbers) {\n\t\t\tnumbers.add(1);\n\t\t\tnumbers.add(1l);\n\t\t\tnumbers.add(1.0);\t\t\t\n\t\t\tnumbers.add(1.0l);\n\t\t}\n\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cNumber\u003e numberList = new ArrayList\u003c\u003e();\n\t\t\taddAFewNumbers(numberList);\n\t\t\tSystem.out.println(numberList);\n\t\t}\n\t}\n\n```\n\n\n**_Console Output_**\n\n_[1, 1, 1.0. 1.0]_\n\n## Introduction to Functional Programming\n\nWhat's all the fuss around Functional Programming about?\n\nLet's find out.\n\nFunctional Programming Videos\n- Part 1 - https://www.youtube.com/watch?v=aFCNPHfvqEU \n- Part 2 - https://www.youtube.com/watch?v=5Xw1_IREXQs\n\n### Step 01: Introducing Functional Programming\n\nLet's look at a typical program to loop around a list and print its content.\n\n##### Snippet-01 : OOP List Traversal \n\n**_FunctionalProgrammingRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\n\timport java.util.List;\n\n\tpublic class FunctionalProgrammingRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cString\u003e list = List.of(\"Apple\", \"Banana\", \"Cat\", \"Dog\");\n\t\t\tfor(String str:list) {\n\t\t\t\tSystem.out.println(str);\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Apple_\n\n_Banana_\n\n_Cat_\n\n_Dog_\n\n##### Snippet-01 Explained\n\nAbove approach focuses on the **how**.\n\nWe looped around the list, accessed individual elements of a ```List``` and did  ```System.out.println()``` to print each element. \n\nFunctional Programming allows us to focus on the **what**.\n\n##### Snippet-02 : ```printBasic()``` And ```printFunctional()``` \n\n**_FunctionalProgrammingRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\n\timport java.util.List;\n\n\tpublic class FunctionalProgrammingRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cString\u003e list = List.of(\"Apple\", \"Banana\", \"Cat\", \"Dog\");\n\t\t\t//printBasic(list);\n\t\t\tprintFunctional(list);\n\t\t}\n\n\t\tpublic static void printBasic(List\u003cString\u003e list) {\n\t\t\tfor(String str:list) {\n\t\t\t\tSystem.out.println(str);\n\t\t\t}\n\t\t}\n\n\t\tpublic static void printFunctional(List\u003cString\u003e list) {\n\t\t\tlist.stream().forEach(\n\t\t\t\t\t\t\t\t\telement -\u003e System.out.println(element)\n\t\t\t\t\t\t\t\t );\t\t\t\t\t\t\t\t\t\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Apple_\n\n_Banana_Cat_\n\n_Dog_\n\n##### Snippet-02 Explained\n\n`list.stream().forEach(element -\u003e System.out.println(element))` - for each element in list stream, print it.\n\n```element -\u003e System.out.println(element)``` is called a **lambda expression**.\n\n### Step 02: Looping Through A ```List```\n\nIn the previous step , we use this snippet of code - `list.stream().forEach(element -\u003e System.out.println(element))`\n\nWe are **\"Passing a function as a method argument\"**. \n\nLet's use JShell to explore this further.\n\nLet's try to print a list of numbers. \n\n##### Snippet-01 : Loop Using FP\n\n```java\n\n\tjshell\u003e List\u003cInteger\u003e list = List.of(1, 4, 7, 9);\n\tlist ==\u003e [1, 4, 7, 9]\n\tjshell\u003e list.stream().forEach(elem -\u003e System.out.println(elem));\n\t1\n\t4\n\t7\n\t9\n\tjshell\u003e\n\t\n```\n\n##### Snippet-01 Explained\n\n`elem -\u003e System.out.println(elem)` is a lambda expression. For each element in list stream, execute the lambda expression.\n### Step 03:  Filtering Results\n\nA ```Stream``` is a sequence of values. The ```filter()``` method can be used to filter the ```Stream``` elements based on some logic.\n  \n##### Snippet-01 : Using ```filter()```\n\n`printBasicWithFiltering` shows the usual approach of filtering.  `printFPWithFiltering` shows the functional approach.\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\n\timport java.util.List;\n\n\tpublic class FunctionalProgrammingRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cString\u003e list = List.of(\"Apple\", \"Bat\", \"Cat\", \"Dog\");\n\t\t\t//printBasicWithFiltering(list);\n\t\t\tprintFPWithFiltering(list);\n\t\t}\n\n\t\tpublic static void printBasicWithFiltering(List\u003cString\u003e list) {\n\t\t\tfor(String str:list) {\n\t\t\t\tif(str.endsWith(\"at\")) {\n\t\t\t\t\tSystem.out.println(str);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tpublic static void printFPWithFiltering(List\u003cString\u003e list) {\n\t\t\tlist.stream()\n\t\t\t\t.filter(elem -\u003e elem.endsWith(\"at\"))\n\t\t\t\t.forEach(element -\u003e System.out.println(element));\n\n\t\t}\t\n\t}\n\n```\n\n\n**_Console Output_**\n\n_Bat_\n\n_Cat_\n\n\n##### Snippet-02 : Printing even/odd numbers\n\nLet's look at how to filter numbers.\n\n```java\n\n\tjshell\u003e List\u003cInteger\u003e list = List.of(1, 4, 7, 9);\n\tlist ==\u003e [1, 4, 7, 9]\n\tjshell\u003e list.stream().forEach(elem -\u003e System.out.println(elem));\n\t1\n\t4\n\t7\n\t9\n\tjshell\u003e list.stream().filter(num -\u003e num%2 == 1).forEach(elem -\u003e System.out.println(elem));\n\t1\n\t7\n\t9\n\tjshell\u003e list.stream().filter(num -\u003e num%2 == 0).forEach(elem -\u003e System.out.println(elem));\n\t4\n\tjshell\u003e\n\n```\n\n##### Snippet-02 Explained\n\nTypically, these are the conditions we write\n* ```num``` is odd : ```if(num % 2 == 1) { /*  */ }```\n* ```num``` is even : ```if(num % 2 == 0){ /*  */ }```\n\nIn the above example, we are using lambda expression to define the same conditions. \n* ```num``` is odd: ```num -\u003e num%2 == 1```\n* ```num``` is even: ```num -\u003e num%2 == 0```\n\n### Step 05: Streams - Aggregated Results\nSometimes we want to aggregate data into a single result. For example, we might want to add all the numbers between ```1``` and ```10```. Or we may want to calculate the average maximum temperature in our city over a month's time. \n\n\n##### Snippet-01 : Sum Of A Sequence\n\nLet's look at how to use `reduce` method to calculation the sum.\n**_FPNumberRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\n\timport java.util.List;\n\n\tpublic class FPNumberRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cInteger\u003e numbers = List.of(4, 6, 8, 13, 3, 15);\n\t\t\t//System.out.println(printBasicSum(numbers));\n\t\t\tint sum = numbers.stream()\n\t\t\t\t\t\t\t .reduce( \n\t\t\t\t\t\t\t\t\t 0,\n\t\t\t\t\t\t\t\t\t (num1, num2) -\u003e num1 + num2\n\t\t\t\t\t\t\t\t\t);\n\t\t\tSystem.out.println(sum);\n\t\t}\n\n\t\tvoid printBasicSum(List\u003cInteger\u003e numbers) {\n\t\t\tint sum=0;\n\t\t\tfor(int num:numbers) {\n\t\t\t\tsum += num;\n\t\t\t}\t\t\n\t\t\tSystem.out.println(sum);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_49_\n\n##### Snippet-01 Explained\n\nThe ```reduce()``` method acts on a pair of elements at a time. The *initial-value* is  ```0```. The lambda expression `(num1, num2) -\u003e num1 + num2` is executed on the elements of the list, a pair at a time.\n \n#### Classroom Exercise CE-01\n\n1. Given the list ```(4, 6, 8, 13, 3, 15)```, compute:\n\t* The sum of even numbers in the list.\n\t* The sum of odd numbers in the list.\n\n#### Solution To CE-01\n\n**_FPNumberRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\n\timport java.util.List;\n\n\tpublic class FPNumberRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cInteger\u003e numbers = List.of(4, 6, 8, 13, 3, 15);\n\t\t\tprintFPEvenSum(numbers);\t\t\t\n\t\t\tprintFPOddSum(numbers);\n\t\t}\n\n\t\tvoid printFPEvenSum(List\u003cInteger\u003e numbers) {\n\t\t\tint sum = numbers.stream()\n\t\t\t\t\t\t\t .filter(elem -\u003e elem %2 == 0)\n\t\t\t\t\t\t\t .reduce(0, (num1, num2) -\u003e num1 + num2);\n\t\t\tSystem.out.println(\"Even Numbers Sum: \" + sum);\n\t\t}\n\n\t\tvoid printFPOddSum(List\u003cInteger\u003e numbers) {\n\t\t\tint sum = numbers.stream()\n\t\t\t\t\t\t\t .filter(elem -\u003e elem %2 == 1)\n\t\t\t\t\t\t\t .reduce(0, (num1, num2) -\u003e num1 + num2);\n\t\t\tSystem.out.println(\"Odd Numbers Sum: \" + sum);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Even Numbers Sum: 18_\n\n_Odd Numbers Sum: 31_\n\n### Step 06: Functional Programming v Structured Programming\n\nLet's have a re-look at the **_FPNumberRunner.java_** program from the previous step. We wrote two variants of the same task that computed the sum of a list of numbers:\n\n* ```basicSum()```: that used the traditional approach\n* ```fpSum()``: which followed the *FP* scheme of things\n\nLet's use them as benchmarks, to illustrate the core differences between *SP* and *FP*. \n\n1. **Structured Programming** (**SP**)\n\n```java\n\n\tpublic int basicSum(List\u003cInteger\u003e numbers) {\n\t\tint sum=0;\n\t\tfor(int num:numbers) {\n\t\t\tsum += num;\n\t\t}\n\t\treturn sum;\n\t}\n\n```\n\n2. **Functional Programming** (**FP**)\n\n```java\n\n\tpublic int  fpSum(List\u003cInteger\u003e numbers) {\n\t\tint sum = numbers.stream()\n\t\t\t\t\t\t .reduce(0, (num1, num2) -\u003e num1 + num2);\n\t\treturn sum;\n\t}\n\n```\n\nHow are these different?\n* **Mutations** (changes to program data):\n\t1. *SP*: Within ```basicSum()```, the variable ```sum``` (a sort of worker variable) is initialized to ```0```, and undergoes *mutations* across iterations of the ```for``` loop. \n\t2. *FP*: We just set up an initial value for ```reduce()``` to work with. We don't have any mutation.\n\n* The **what** and **how** of computation:\n\t1. *SP*: We specify both *what* to do, and *how* to do it. The code loops through the list elements using a ```for```, while also updating the aggregate value in ```sum```.\n\t2. *FP*: We are focused on *what* to do, and very little on the *how* part. ```reduce()``` takes care of what numbers from the *stream* to add up, and you don't bother about how to select them from the *stream*. \n\n\n### Step 07: Some FP Terminology \n\nLet's look at some *FP* terminology a little more formally.\n\n\n#### Lambda Expression\n\n\n```java\n\n\t(num1, num2) -\u003e num1 + num2\n\n```\n\nis equivalent of this method\n\n```java\n\n\tint basicSum(int num1, int num2) {\t\n\t\treturn num1 + num2;\n\t}\n\n``` \n\nA lambda expression can have multiple lines of Java code as well:\n\n```java\n\n\t(num1, num2) -\u003e {\n\t\tSystem.out.println(num1 + \" \" + num2);\n\t\treturn num1 + num2;\n\t}\n\n```\n\nWhy take our word for all this? Let's put this code into an IDE, and then run it, to see for ourselves.\n\n##### Snippet-01 : Lambda Expression\n\n**_FPNumberRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\n\timport java.util.List;\n\n\tpublic class FPNumberRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cInteger\u003e numbers = List.of(4, 6, 8, 13, 3, 15);\n\t\t\tSystem.out.println(numbers);\n\t\t\tprintFPSum(numbers);\n\t\t}\n\n\t\tvoid printFPSum(List\u003cInteger\u003e numbers) {\n\t\t\tint sum = numbers.stream()\n\t\t\t\t\t\t\t .reduce(0,\n\t\t\t\t\t\t\t\t\t (num1, num2) -\u003e {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tSystem.out.println(num1 + \" \" + num2);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn num1 + num2;\n\t\t\t\t\t\t\t\t\t\t\t\t\t }\n\t\t\tSystem.out.println(\"Even Numbers Sum: \" + sum);\t\t\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_[4, 6, 8, 13, 3, 15]_\n\n_0 4_\n\n_4 6_\n\n_10 8_\n\n_18 13_\n\n_31 3_\n\n_34 15_\n\n_49_\n\n\n\n#### Stream\n\nA Stream is a sequence of elements. You can perform different kinds of operations on a stream. \n* **Intermediate Operations**: An operation that *takes a stream* - for example, applies a lambda expression - and produces *another stream* of elements as its result.\n* **Terminal Operations**: A stream operation that takes a stream - for example, applies a lambda expression -  and returns a single result (A single primitive-value/object, or a single collection-of-objects). ```reduce()``` and ```forEach()``` are a couple of such operations.\n\n### Step 08: Intermediate Stream Operations\n\nOutput of an intermediate stream operation is another stream. \n\nThe most popular intermediate stream operations are: \n* ```sorted()```\n* ```distinct()```\n* ```filter()```\n* ```map()```\n\nIn this step, let's check them out one by one.\n\n##### Snippet-01 : ```sorted()``` and other operations\n\n```java\n\n\tjshell\u003e List\u003cInteger\u003e numbers = List.of(3, 5, 8, 213, 45, 4, 7);\n\tnumbers ==\u003e [3, 5, 8, 213, 45, 4, 7]\n\tjshell\u003e numbers.stream().sorted().forEach(elem -\u003e System.out.println(elem));\n\t3\n\t4\n\t5\n\t7\n\t8\n\t45\n\t213\n\tjshell\u003e List\u003cInteger\u003e numbers = List.of(3, 5, 3, 213, 45, 5, 7);\n\tnumbers ==\u003e [3, 5, 3, 213, 45, 5, 7]\n\tjshell\u003e numbers.stream().distinct().forEach(elem -\u003e System.out.println(elem));\n\t3\n\t5\n\t213\n\t45\n\t7\n\tjshell\u003e numbers.stream().distinct().sorted().forEach(elem -\u003e System.out.println(elem));\n\t\n\t3\n\t5\n\t7\n\t45\n\t213\n\tjshell\u003e numbers.stream().distinct().map(num -\u003e num*num).forEach(elem -\u003e System.out.println(elem));\n\t9\n\t25\n\t45369\n\t2025\n\t49\n\tjshell\u003e\n\n```\n\n##### Snippet-01 Explained\n\n* ```sorted()``` preserves the elements of the consumed stream in the result, but also puts them in natural sorted order (Increasing order for numbers, alphabetical order for strings).\n* ```distinct()``` returns a stream retaining only the unique elements of the input stream. This method maintains the relative order of retained elements.\n* You can chain together more than one intermediate operation, such as ```sorted()``` followed by ```distinct()``` above. Such code is sometimes called a *pipeline*.\n*  ```map()``` : Applies a lambda expression to compute new results from the input stream elements. It then returns a stream of these results as output. In our example, ```map()``` takes each element in the ```Stream``` object created by ```number.stream()``,` to its square value.\n\n\n### Step 09: Programming Exercise FP-PE-01\n\n#### Exercises\n\n1. Write a program to print the squares of the first 10 positive integers.\n2. Create a list of the character strings \"Apple\", \"Banana\" and \"Cat\". Print all of them in lower-case.\n3. Create a list of the character strings \"Apple\", \"Banana\" and \"Cat\". Print the length of each string.\n\n#### Solutions To FP-PE-01\n\n**_FPNumberRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\n\tpublic class FPNumberRunner {\n\t\tpublic static void printFPSquares() {\n\t\t\tIntStream.range(1, 11).\n\t\t\t\t\t  map(num -\u003e num*num).\n\t\t\t\t\t  forEach(elem -\u003e System.out.println(elem));\n\t\t}\n\n\t\tpublic static void printLowerCases(List\u003cString\u003e list) {\n\t\t}\n\n\t\tpublic static void printLengths(List\u003cString\u003e list) {\n\t\t\tlist.stream()\n\t\t\t\t.map(s -\u003e s.length())\n\t\t\t\t.forEach(elem -\u003e System.out.println(elem);\n\t\t}\n\n\t\tpublic static void main(String[] args) {\n\t\t\tprintFPSquares();\n\t\t\tList\u003cString\u003e list = List.of(\"Apple\", \"Banana\", \"Cat\");\n\t\t\tprintLowerCases(list);\t\t\n\t\t\tprintLengths(list);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_1_\n\n_4_\n\n_9_\n\n_16_\n\n_25_\n\n_36_\n\n_49_\n\n_64_\n\n_81_\n\n_100_\n\n_apple_\n\n_banana_\n\n_cat_\n\n_5_\n\n_6_\n\n_3_\n\n#### Solution Explained\n\n* The ```map()``` method accepts a lambda expression.\n\n### Step 10:  Terminal Operations\n\nA terminal operation returns a single result (A single object/data-unit, or a single collection). It does not return an output stream.\n\nCommonly used instances of this are:\n\n* ```reduce()```\n* ```max()``` and ```min()```\n\n```java\n\n\tjshell\u003e IntStream.range(1, 11).reduce(0, (n1, n2) -\u003e n1 + n2);\n\t$1 ==\u003e 55\n```\n\n```max()``` expects a lambda expression providing a ```Comparator\u003cT\u003e``` implementation.  ```Integer.compare(n1,n2)``` is an implementation of the ```Comparator\u003cT\u003e``` interface for comparing integers. \n\nWhat if there are no numbers in the Stream? What should be returned? As a Java programmer, we grew up to hate `null`. You don't want to return `null` back.\n\nThe ```Optional``` type provides an alternative: \n* You can query an ```Optional``` object to check if it contains a valid result, by invoking ```isPresent()``` on it. \n* You can get that result by calling ```get()``` on the same object.\n\n\n```java\n\n\tjshell\u003e List.of(23, 12, 34, 53).stream().max();\n\t| Error:\n\t| method max() in interface java.util.stream.Stream\u003cT\u003e cannot be applied to given types\n\t| required : java.lang.Comparator\u003c? super java.lang.Integer\u003e\n\t| found : no argument\n\t| List.of(23, 12, 34, 53).stream().max();\n\t|^-----------------------------------^\n\tjshell\u003e List.of(23, 12, 34, 53).stream().max((n1, n2) -\u003e Integer.compare(n1, n2));\n\t$2 ==\u003e Optional[53]\n\tjshell\u003e $2.isPresent()\n\t$3 ==\u003e true\n\tjshell\u003e List.of(23, 12, 34, 53).stream().max((n1, n2) -\u003e Integer.compare(n1, n2)).get();\n\t$4 ==\u003e 53\n\tjshell\u003e\n\n```\n\n- - - \n### Step 11: More Stream Operations\n\nLet's now play around with a few more terminal operations, such as ```min()``` (terminal operation), and ```filter()``` (intermediate operation). \n\n##### Snippet-01 : min() and max()\n\nUsing ```min()``` is similar to ```max()```.\n\n```java\n\n\tjshell\u003e List.of(23, 12, 34, 53).stream().max((n1, n2) -\u003e Integer.compare(n1, n2)).get()\n\t$1 ==\u003e 53\n\tjshell\u003e List.of(23, 12, 34, 53).stream().min((n1, n2) -\u003e Integer.compare(n1, n2)).get()\n\t$2 ==\u003e 12\n\tjshell\u003e\n\t\n```\n\n##### Snippet-02 : Odd and Even Numbers\n\n```collect()``` method can be called to collect the result of ```filter()``` into a list. `Collectors.toList()` is the utility method used.\n\n```java\n\n\tjshell\u003e List.of(23, 12, 34, 53).stream().filter(e -\u003e e%2==1).forEach(e -\u003e \tSystem.out.println(e))\n\t23\n\t53\n\tjshell\u003e List.of(23, 12, 34, 53).stream().filter(e -\u003e e%2==1).collect(Collectors.toList());\n\t$1 ==\u003e [23, 53]\n\tjshell\u003e\n\n```\n\n#### Classroom Exercise FP-CE-02\n\n1. From a list of 23, 12, 34, 53, create a list of the even numbers in it.\n2. Create a list of squares of the first 10 positive integers.\n\n#### Solutions To FP-CE-02\n\n**_FunctionalProgrammingRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\n\n\tpublic class FPNumberRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cInteger\u003e numbers = List.of(23, 12, 34, 53);\n\t\t\tList\u003cInteger\u003e evens = numbers.stream()\n\t\t\t\t\t\t\t\t\t\t .filter(n -\u003e n%2==0)\n\t\t\t\t\t\t\t\t\t\t .collect(Collectors.toList());\n\n\t\t\tList\u003cInteger\u003e tenSquares = IntStream.range(1, 11)\n\t\t\t\t\t\t\t\t\t\t\t\t.map(n -\u003e n*n)\n\t\t\t\t\t\t\t\t\t\t\t\t.boxed()\n\t\t\t\t\t\t\t\t\t\t\t\t.collect(Collectors.toList());\n\t\t}\n\t}\n\n```\n\n#### Solution Explained\n\n* Solution to #1 is straightforward, given that we already know how to use ```filter()```.\n* Solution #2 uses ```boxed()``` method to convert an ```IntPipeline``` to a ```Stream```. After that, what follows is routine stuff.\n\n### Step 12: The ```Optional\u003cT\u003e``` ```class```\n\nIn an earlier section, we wrote and ran the following code:\n\n```java\n\n\tjshell\u003e List.of(23, 12, 34, 53).stream().max((n1, n2) -\u003e Integer.compare(n1, n2));\n\tOptional[53]\n\tjshell\u003e\n\n```\n\nIn order to get the result in a form you would appreciate, we modified this code to look like:\n\n```java\n\njshell\u003e List.of(23, 12, 34, 53).stream().max((n1, n2) -\u003e Integer.compare(n1, n2)).get();\n53\njshell\u003e\n\n```\n\n```max()``` is a stream operation, that needs to consume a stream. It is possible that the input stream is empty. In that case, the maximum value would be ```null```. It is undesirable in *FP* to encounter an exception during a stream operation. It is extremely inelegant if we are asked to handle an exception in an *FP* code pipeline. \n\nThe ```Optional\u003cT\u003e``` ```class``` was introduced in Java SE 8, as a lifeline in such situations. It covers the possibility of absence of (or ```null```) result from a terminal stream operation. The following example illustrates how you can query, and access the result from, an ```Optional\u003cT\u003e``` object. \n\n```java\n\n\tjshell\u003e List.of(23, 45, 67, 12).stream().filter(num -\u003e num % 2 == 0).max( (n1, n2) -\u003e \tInteger.compare(n1, n2) )\n\t$1 ==\u003e Optional[12]\n\tjshell\u003e $1.get()\n\t$2 ==\u003e 12\n\tjshell\u003e $1.isPresent()\n\t$3 ==\u003e true\n```\nIn case the result is empty, then the value stored in the result is not ```null```, it is ```Optional.empty```.\n\n```java\n\tjshell\u003e List.of(23, 45, 67).stream().filter(num -\u003e num % 2 == 0).max( (n1, n2) -\u003e \tInteger.compare(n1, n2) )\n\t$4 ==\u003e Optional.empty\n\tjshell\u003e $4.isPresent()\n\t$5 ==\u003e false\n\tjshell\u003e $4.orElse(0)\n\t$6 ==\u003e 0\n```\n\nYou can provide a default value for the result using the method ```orElse()```.\n\n```java\n\tjshell\u003e List.of(23, 45, 67).stream().filter(num -\u003e num % 2 == 0).max( (n1, n2) -\u003e \tInteger.compare(n1, n2) ).orElse(0)\n\t$7 ==\u003e 0\n\tjshell\u003e List.of(23, 45, 67, 34).stream().filter(num -\u003e num % 2 == 0).max( (n1, n2) -\u003e \tInteger.compare(n1, n2) ).orElse(0)\n\t$8 ==\u003e 34\n\tjshell\u003e\n\n```\n\n### Step 13: Functional Interfaces : ```Predicate```\n\nWhen we define a lambda expression , a lot of things happen behind the scenes. \n\nAn important concept is a *functional interface*.\n\nLet's explain this term using an example. \n\nThe following code takes a behind-the-scenes look at ```filter()```.\n\n##### Snippet-01: Lambda behind-the-scenes - v1\n\n**_LambdaBehindTheScenesRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\n\timport java.util.List;\n\n\tpublic class LambdaBehindTheScenesRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList.of(23, 43, 34, 45).stream()\n\t\t\t\t\t\t\t\t   .filter(num -\u003e num%2 == 0)\n\t\t\t\t\t\t\t\t   .forEach(e -\u003e System.out.println(e));\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_34_\n\n_36_\n\n_48_\n\n\n##### Snippet-01 Explained\n\nThe signature of ```filter()``` reads is `Stream\u003cT\u003e java.util.stream.Stream.filter(Predicate\u003c? super T\u003e predicate)`.  In this case, ```T``` is ```java.lang.Integer```. \n\n```filter()``` accepts an  object implementing the ```Predicate``` interface, as its argument. It returns a stream, consisting of those elements from the input stream, that match this predicate. \n\nConventionally speaking, a predicate is a logical condition. This predicate is applied to each element, to determine if it should be included in the output stream.\n\nThe ```Predicate\u003cT\u003e``` ```interface is``` an example of a  *Functional Interface*. This interface has one method ```boolean test(T t)```. \n\t\nInstead of `num -\u003e num%2 == 0`, let's implement a `EvenNumberPredicate`.\n\n```java\n\n\t@FunctionalInterface\n\tpublic interface Predicate\u003c? super T\u003e {\n\t\tboolean test(T t) { /*  */ }\n\t\t\t//...\n\t\t}\n\t}\n\t\n```\n\n##### Snippet-02: lambda behind the scenes - v2\n\n**_LambdaBehindTheScenesRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\n\timport java.util.List;\n\timport java.util.function.Predicate;\n\n\tclass EvenNumberPredicate implements Predicate\u003cInteger\u003e {\n\t\t@Override\n\t\tpublic boolean test(Integer number) {\n\t\t\treturn (number%2 == 0);\n\t\t}\n\t}\n\n\tpublic class LambdaBehindTheScenesRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList.of(23, 43, 34, 45, 36, 48).stream()\n\t\t\t\t\t\t\t\t\t\t   .filter(new EvenNumberPredicate())\n\t\t\t\t\t\t\t\t\t\t   .forEach(e -\u003e System.out.println(e));\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_34_\n\n_36_\n\n_48_\n\n##### Snippet-02 Explained\n\n```EvenNumberPredicate``` implements the ```Predicate\u003cInteger\u003e``` interface, and overrides the ```test()``` method.\n\nSomething similar to ```EvenNumberPredicate``` is created when we use lambda expressions ```num -\u003e num%2 == 0```.\n\n### Step 14: Functional Interfaces : ```Consumer```\n\nLet's look at another Functional Interface - ```Consumer\u003cS\u003e```.\n\n```forEach()``` on a stream is actually defined as - ```forEach(Consumer\u003c? super S\u003e action)```\n\nThe ```Consumer\u003cS\u003e``` interface has the following definition:\n\n```java\n\n\t@FunctionalInterface\n\tpublic interface Consumer\u003c? super S\u003e {\n\t\tvoid accept(S s) { /*  */ }\t\n\t\n\t\t//...\n\t\n\t}\n\n```\n\nThe lambda expression used inside ```forEach()``` and other such stream operations, actually represent a `Consumer` implementation. \n\n##### Snippet-01\n\nLet's implement a `SysOutConsumer`.\n\n**_FunctionalProgrammingRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\n\timport java.util.List;\n\timport java.util.stream.Stream;\n\timport java.util.function.Consumer;\n\timport java.util.function.Predicate;\n\n\tclass EvenNumberPredicate implements Predicate\u003cInteger\u003e {\n\t\t@Override\n\t\tpublic boolean test(Integer num) {\n\t\t\treturn num%2 == 0;\n\t\t}\n\t}\n\n\tclass SysOutConsumer implements Consumer\u003cInteger\u003e {\n\t\t@Override\n\t\tpublic void accept(Integer num) {\n\t\t\tSystem.out.println(num);\n\t\t}\n\t}\n\n\tpublic class FPNumberRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cInteger\u003e numbers = List.of(23, 12, 34, 45, 36, 48);\n\t\t\t//List\u003cInteger\u003e evens = numbers.stream()\n\t\t\t\t\t\t\t\t\t\t   .filter(n -\u003e n%2==0)\n\t\t\t\t\t\t\t\t\t\t   .collect(Collectors.toList());\n\n\t\t\tList\u003cInteger\u003e evensToo = numbers.stream()\n\t\t\t\t\t\t\t\t\t\t    .filter(new EvenNumberPredicate())\n\t\t\t\t\t\t\t\t\t\t\t.collect(Collectors.toList());\n\n\t\t\tnumbers.stream()\n\t\t\t\t   .filter(new EvenNumberPredicate())\n\t\t\t\t   .forEach(new SysOutConsumer());\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_12_\n\n_34_\n\n_36_\n\n_48_\n\n##### Snippet-01 Explained\n\n* The code actually speaks for itself. The steps to customize a ```Consumer\u003cS\u003e``` implementation are quote simple, and straightforward.\n* The final code that involves both a custom ```Predicate\u003cT\u003e```, and a custom ```Consumer\u003cS\u003e``` is still quite compact and elegant! \n\n### Step 15: More Functional Interfaces\n\nLet's now look at what happens behind the scenes, for the stream operation ```map()```. Suppose we wanted to print out the squares of all even numbers in a given list.\n\n##### Snippet-01 : ```map()``` Behind The Scenes - v1\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\n\timport java.util.List;\n\timport java.util.stream.Stream;\n\timport java.util.function.Consumer;\n\timport java.util.function.Predicate;\n\n\tclass EvenNumberPredicate implements Predicate\u003cInteger\u003e {\n\t\t@Override\n\t\tpublic boolean test(Integer num) {\n\t\t\treturn num%2 == 0;\n\t\t}\n\t}\n\n\tclass SysOutConsumer implements Consumer\u003cInteger\u003e {\n\t\t@Override\n\t\tpublic void accept(Integer num) {\n\t\t\tSystem.out.println(num);\n\t\t}\n\t}\n\n\tpublic class FPNumberRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cInteger\u003e numbers = List.of(23, 12, 34, 45, 36, 48);\n\t\t\tnumbers.stream()\t\t\n\t\t\t\t   .filter(new EvenNumberPredicate())\n\t\t\t\t   .map(n -\u003e n*n)\n\t\t\t\t   .forEach(new SysOutPredicate());\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_1156_\n\n_1296_\n\n_2304_\n\n##### Snippet-01 Explained \n\nThe signature of the ```map()``` intermediate stream operation is :\n\n```java\n\n\t\u003cR\u003e Stream\u003cR\u003e map(Function\u003c?super T, ? extends R\u003e mapper){}\n\n```\n\n```Function``` is shown below.\n\n```java\n\n\t@FunctionalInterface\n\tpublic interface Function\u003cT,R\u003e {\n\t\tR apply(T t);\n\t}\n\n```\n\nThe method ```apply()``` accepts a ```T``` object as argument, and returns another object of type ```R```. In effect, any ```Function``` implementation can map object of one type to another.\n\n##### Snippet-02 : ```map()``` Behind The Scenes - v2\n\nLet's implement a `NumberSquareMapper`.\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\t\n\timport java.util.List;\n\timport java.util.stream.Stream;\n\timport java.util.function.Consumer;\n\timport java.util.function.Predicate;\n\timport java.util.function.Function;\n\n\tclass EvenNumberPredicate implements Predicate\u003cInteger\u003e {\n\t\t@Override\n\t\tpublic boolean test(Integer num) {\n\t\t\treturn num%2 == 0;\n\t\t}\n\t}\n\n\tclass SysOutConsumer implements Consumer\u003cInteger\u003e {\n\t\t@Override\n\t\tpublic void accept(Integer num) {\n\t\t\tSystem.out.println(num);\n\t\t}\t\n\t}\n\n\tclass NumberSquareMapper implements Function\u003cInteger, Integer\u003e {\n\t\t@Override\n\t\tpublic Integer apply(Integer number) {\n\t\t\treturn number * number;\n\t\t}\t\n\t}\n\n\tpublic class FPNumberRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cInteger\u003e numbers = List.of(23, 12, 34, 45, 36, 48);\n\t\t\tnumbers.stream()\n\t\t\t\t   .filter(num -\u003e num%2 == 0)\n\t\t\t\t   .map(n -\u003e n*n)\n\t\t\t\t   .forEach(e -\u003e System.out.println(e));\n\n\t\t\tnumbers.stream()\n\t\t\t\t   .filter(new EvenNumberPredicate())\n\t\t\t\t   .map(new NumberSquareMapper())\n\t\t\t\t   .forEach(new SysOutPredicate());\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_1156_\n\n_1296_\n\n_2304_\n\n**_1156_**\n\n**_1296_**\n\n**_2304_**\n\n### Step 16: Introducing Method References\n\nWhat is a method reference?\n\nLet's look at an example.\n\n##### Snippet-01: Method References - v1\n\n**_MethodReferencesRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\n\timport java.util.List;\n\n\tpublic class MethodReferencesRunner {\n\t\tpublic static void main(String[] args)\n\t\t\tList.of(\"Ant\", \"Bat\", \"Cat\", \"Dog\", \"Elephant\").stream()\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   .map(s -\u003e s.length())\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   .forEach(l -\u003e System.out.println(l));\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_3_\n\n_3_\n\n_3_\n\n_3_\n\n_8_\n\n##### Snippet-02 : Method References - v2 \n\nMethod references make it easy to create lambda expressions.\n\n`l -\u003e System.out.println(l)` can be replaced with `System.out::println`.\n\n**_MethodReferencesRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\n\timport java.util.List;\n\n\tpublic class MethodReferencesRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList.of(\"Ant\", \"Bat\", \"Cat\", \"Dog\", \"Elephant\").stream()\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   .map(s -\u003e s.length())\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   .forEach(l -\u003e System.out.println(l));\n\n\t\t\tList.of(\"Ant\", \"Bat\", \"Cat\", \"Dog\", \"Elephant\").stream()\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   .map(s -\u003e s.length())\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   .forEach(System.out::println);\n\t\t}\n\t}\n\n```\n\n##### Snippet-03: Method References - v3\n\nLet's define a static method `print` and use it using a method reference.\n\n`MethodReferencesRunner::print` is same as `l -\u003e MethodReferencesRunner.print(l)`\n\n**_MethodReferencesRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\n\timport java.util.List;\n\n\tpublic class MethodReferencesRunner {\n\t\tpublic static void print(Integer number) {\n\t\t\tSystem.out.println(number);\n\t\t}\n\n\t\tpublic static void main(String[] args) {\n\t\t\tList.of(\"Ant\", \"Bat\", \"Cat\", \"Dog\", \"Elephant\").stream()\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   .map(s -\u003e s.length())\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   .forEach(l -\u003e MethodReferencesRunner.print(l));\n\n\t\t\tList.of(\"Ant\", \"Bat\", \"Cat\", \"Dog\", \"Elephant\").stream()\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   .map(s -\u003e s.length())\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   .forEach(MethodReferencesRunner::print);\n\t\t}\n\t}\n\n```\n\n##### Snippet-04 : Method References - v4\n\nInstance method calls can also be replaced with their method references.\n\nOn a `String`, `String::length` is the same as `s -\u003e s.length()`.\n\n**_MethodReferencesRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\n\timport java.util.List;\n\n\tpublic class MethodReferencesRunner {\n\t\tpublic static void print(Integer number) {\n\t\t\tSystem.out.println(number);\n\t\t}\n\n\t\tpublic static void main(String[] args) {\n\t\t\tList.of(\"Ant\", \"Bat\", \"Cat\", \"Dog\", \"Elephant\").stream()\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   .map(s -\u003e s.length())\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   .forEach(MethodReferencesRunner::print);\n\n\t\t\tList.of(\"Ant\", \"Bat\", \"Cat\", \"Dog\", \"Elephant\").stream()\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   .map(String::length)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t   .forEach(MethodReferencesRunner::print);\n\t\t}\n\t}\n\n```\n\n#### Classroom Exercise FP-CE-03\n\n1. Using method references, write java functional code to determine the maximum even number,  in a given list of integers.\n\n#### Solution To FP-CE-03\n\n**_MethodReferencesRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\n\timport java.util.List;\n\n\tpublic class MethodReferencesRunner {\n\t\tpublic static void print(Integer number) {\n\t\t\tSystem.out.println(number);\n\t\t}\n\n\t\tpublic static void main(String[] args) {\n\t\t\tint max = List.of(23, 45, 67, 34).stream()\t\t\n\t\t\t\t\t\t\t\t\t\t\t .filter(num -\u003e num % 2 == 0)\n\t\t\t\t\t\t\t\t\t\t\t .max( (n1, n2) -\u003e Integer.compare(n1, n2) )\n\t\t\t\t\t\t\t\t\t\t\t .orElse(0);\n\n\t\t\tSystem.out.println(max);\n\t\t\tint maximum = List.of(23, 45, 67, 34).stream()\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t .filter(MethodReferencesRunner::isEven)\n\t\t\t\t\t\t\t\t\t\t\t\t .max(Integer::compare)\n\t\t\t\t\t\t\t\t\t\t\t\t .orElse(0);\n\n\t\t\tSystem.out.println(maximum);\n\t\t}\n\n\t\tpublic static booelan isEven(Integer number) {\n\t\t\treturn (number %2 == 0);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_34_\n\n**_34_**\n\n#### Summary\n\nIn this step, we:\n\n* Understood what is a method reference\n* Learned that both built-in, and user defined class methods can be invoked using method references\n* Observed that method references work for static and non-static methods\n\n### Step 17: FP - Functions As First-Class Citizens \n\nAre functions first class citizens in Java?\n\nHere are few questions to think about?\n* Can you pass a function as an argument to a method?\n* Can you assign a function to a variable?\n* Can you obtain a function as a return value, from a method invocation?\n\n#### Passing function as method argument\n\nWe looked at several examples of this earlier.\n\nIn the example below, `num -\u003e num % 2 == 0` is passed to `filter` method.\n\n```\nint max = List.of(23, 45, 67, 34).stream()\t\t\n\t\t\t\t\t\t\t\t .filter(num -\u003e num % 2 == 0)\n\t\t\t\t\t\t\t\t .max( (n1, n2) -\u003e Integer.compare(n1, n2) )\n\t\t\t\t\t\t\t\t .orElse(0);\n```\n\n\n#### Storing functions in reference variables\n\n`evenPredicate` and `oddPredicate` represent functions.\n\n```java\n\n\tpackage com.in28minutes.functionalprogramming;\n\timport java.util.List;\n\timport java.util.function.Predicate;\n\n\tpublic class FPNumberRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cInteger\u003e numbers = List.of(23, 12, 34, 45, 36, 48);\n\t\t\tPredicate\u003c? super Integer\u003e evenPredicate = num -\u003e num % 2 == 0;\t\t\t\n\t\t\tPredicate\u003c? super Integer\u003e oddPredicate = num -\u003e num % 2 == 1;\n\n\t\t\tnumbers.stream()\n\t\t\t\t   .filter(evenPredicate)\n\t\t\t\t   .map(n -\u003e n*n)\n\t\t\t\t   .forEach(e -\u003e System.out.println(e));\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_1156_\n\n_1296_\n\n_2304_\n\n\n#### Returning functions from methods\n\n`createEvenPredicate` and `createOddPredicate` are examples of methods returning functions.\n\n```java\n\n\timport java.util.stream.Stream;\n\timport java.util.function.Predicate;\n\n\tpublic class FPNumberRunner {\n\t\tpublic static Predicate\u003c? super Integer\u003e createEvenPredicate() {\n\t\t\treturn num -\u003e num%2 == 0;\n\t\t}\n\n\t\tpublic static Predicate\u003c? super Integer\u003e createOddPredicate() {\n\t\t\treturn num -\u003e num%2 == 1;\n\t\t}\n\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cInteger\u003e numbers = List.of(23, 12, 34, 45, 36, 48);\n\t\t\t//Predicate\u003c? super Integer\u003e evenPredicate = num -\u003e num % 2 == 0;\n\t\t\t//Predicate\u003c? super Integer\u003e evenPredicate = createEvenPredicate();\n\n\t\t\tnumbers.stream()\n\t\t\t\t   //.filter(num -\u003e num%2 == 0)\n\t\t\t\t   //.filter(evenPredicate)\n\t\t\t\t   .map(n -\u003e n*n)\n\t\t\t\t   .forEach(e -\u003e System.out.println(e));\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_1156_\n\n_1296_\n\n_2304_\n\n\n#### Summary\n\nIn this step, we observed that the following is true for a function:\n* It can be passed as a method argument\n* It can be stored in a reference variable\n* It can be  returned from a method\n\n## Threads and Concurrency\n\nSo far, we've only seen programs that run like a single horse, running round a race course. \n\nHowever, it often makes sense for a program's *main task* to be split into smaller ones (let's call them *sub-tasks*).  \n\nImagine an ant-colony, where a large number of worker ants toil together, to complete what the Queen Ant tells them to do. Groups of ants that are part of separately tasks, work with a free hand.\n\nThe concept of **concurrency** in programming is very similar to what an ant colony is in nature. \n\n### Step 01: Concurrent Tasks: Extending ```Thread```\n\nIn Java, you can run tasks in parallel using threads.  Let's first write a simple program.\n\n##### Snippet-1\n\n**_ThreadBasicsRunner.java_**\n\n```java\n\n\tpublic class ThreadBasicsRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\t//Task1\n\t\t\tfor(int i=101; i\u003c=199; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\n\t\t\t}\n\t\t\tSystem.out.println(\"\\n Task1 Done\");\n\n\t\t\t//Task2\n\t\t\tfor(int i=201; i\u003c=299; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\n\t\t\t}\n\t\n\t\t\tSystem.out.println(\"\\n Task2 Done\");\n\t\t\t//Task3\n\t\t\tfor(int i=301; i\u003c=399; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\t\t\t\n\t\t\t}\n\t\t\tSystem.out.println(\"\\n Task3 Done\");\n\n\t\t\tSystem.out.println(\"Main Done\");\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199_\n\n_Task1 Done_\n\n_201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299_\n\n_Task2 Done_\n\n_301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399_\n\n_Task3 Done_\n\n_Main Done_\n\n##### Snippet-1 Explained\n\nAs you can see, the execution of all three ```for``` loops (that really are independent tasks) is sequential. This is how all our code so far has been running!\n\n### Thread Creation\n\nThere are two ways in which you can create a thread to represent a sub-task, within a program. They are:\n\n* Define your own thread ```class``` to sub-class the **```Thread```** ```class```.\n* Define your own thread ```class``` to implement the **```Runnable```** ```interface```.\n\nIn this step, we will focus on the first alternative.\n\n##### Snippet-01 : A simple Java thread class\n\n**_ThreadBasicsRunner.java_**\n\n```java\n\n\tclass Task1 extends Thread {\n\t\tpublic void run() {\n\t\t\tSystem.out.println(\"Task1 Started \");\n\t\t\tfor(int i=101; i\u003c=199; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\n\t\t\t}\n\t\t\tSystem.out.println(\"\\nTask1 Done\");\n\t\t}\t\n\t}\n\n\tpublic class ThreadBasicsRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\t//Task1\n\t\t\tTask1 task1 = new Task1();\n\t\t\ttask1.start();\n\n\t\t\t//Task2\n\t\t\tfor(int i=201; i\u003c=299; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\n\t\t\t}\n\t\t\tSystem.out.println(\"\\nTask2 Done\");\n\n\t\t\t//Task3\n\t\t\tfor(int i=301; i\u003c=399; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\n\t\t\t}\n\t\t\tSystem.out.println(\"\\nTask3 Done\");\n\t\t\tSystem.out.println(\"\\nMain Done\");\n\t\t}\t\n\t}\n\n```\n\n**_Console Output_**\n\n```\nTask1 Started \n201 101 202 102 203 103 204 104 105 205 206 106 207 107 208 108 209 109 210 110 211 111 212 112 213 113 214 114 215 115 216 116 217 218 117 219 118 220 119 221 120 222 121 122 223 123 224 124 225 125 226 126 227 127 228 128 229 129 230 130 231 131 232 132 233 133 234 134 235 135 236 136 237 137 238 138 239 139 240 140 241 141 242 142 243 143 244 144 245 145 246 247 146 248 147 249 148 250 149 251 150 252 151 253 152 254 153 255 154 256 155 257 156 258 157 259 158 260 159 261 160 262 161 263 162 264 163 265 164 266 165 267 166 268 167 269 168 270 169 271 170 272 171 273 172 274 173 275 174 276 175 277 278 279 176 280 177 281 178 179 282 180 181 182 283 183 284 184 285 185 286 186 287 187 288 289 188 290 189 291 190 292 191 293 192 294 193 194 295 195 196 296 197 297 298 299 198 \nTask2 Done\n301 199 302 \nTask1 Done\n303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 \nTask3 Done\n\nMain Done\n```\n\n##### Snippet-01 Explained\n\nWe defined a ```Task1``` ```class``` to denote our sub-task, with a ```run()``` method definition. However,  when we create such a thread within our ```main()``` method, we don't seem to be invoking ```run()``` in any way! What's happening here? \n\nA thread can be created and launched, by calling a generic method named ```start()```. method. Calling ```start()``` will invoke the individual thread’s ```run()``` method.\n\nFrom the console output, we see that the output of *Task1* overlaps with those of tasks labeled *Task2* and *Task3*. *Task1* is running in parallel with main which is running (*Task2*, *Task3*).\n\n#### Summary\n\nIn this step, we:\n\n* Discovered how to define a thread by sub-classing ```Thread```\n* Demonstrated how to run a Thread\n\n### Step 02: Concurrent Tasks - Implementing Runnable\n\n##### Snippet-01 : Implementing Runnable\n\nIn **Step 01**, we told you that there are two ways a thread could represent a sub-task, in a Java program. One was by sub-classing a ```Thread```, and the other way is to implement ```Runnable```. We saw the first way a short while ago, and it's time now to explore the second. The following example will show you how it's done.\n\n**_ThreadBasicsRunner.java_**\n\n```java\n\n\tclass Task1 extends Thread {\n\t\tpublic void run() {\n\t\t\tSystem.out.println(\"Task1 Started \");\n\t\t\tfor(int i=101; i\u003c=199; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\n\t\t\t}\n\t\t\tSystem.out.println(\"\\nTask1 Done\");\n\t\t}\n\t}\n\n\tclass Task2 implements Runnable {\n\t\t@Override\n\t\tpublic void run() {\n\t\t\tSystem.out.println(\"Task2 Started \");\n\t\t\tfor(int i=201; i\u003c=299; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\t\t\n\t\t\t}\n\t\t\tSystem.out.println(\"\\nTask2 Done\");\n\t\t}\n\t}\n\n\tpublic class ThreadBasicsRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tSystem.out.print(\"\\nTask1 Kicked Off\\n\");\n\t\t\tTask1 task1 = new Task1();\n\t\t\ttask1.start();\n\n\t\t\tSystem.out.print(\"\\nTask2 Kicked Off\\n\");\n\t\t\tTask2 task2 = new Task2();\n\t\t\tThread task2Thread = new Thread(task2);\n\t\t\ttask2Thread.start();\n\n\t\t\tSystem.out.print(\"\\nTask3 Kicked Off\\n\");\n\t\t\tfor(int i=301; i\u003c=399; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\n\t\t\t}\n\t\t\tSystem.out.println(\"\\nTask3 Done\");\n\n\t\t\tSystem.out.println(\"\\nMain Done\");\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n```\n\nTask1 Kicked Off\nTask1 Started \n101 102 103 104 105 106 107 108 109 110 111 \nTask2 Kicked Off\n112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 \nTask1 Done\n\nTask3 Kicked Off\nTask2 Started \n201 202 203 204 205 206 207 208 209 210 211 212 213 301 214 215 216 217 218 302 219 220 221 222 223 224 225 226 227 228 303 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 304 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 305 287 288 289 290 291 292 293 294 295 296 297 298 299 \nTask2 Done\n306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 \nTask3 Done\n\nMain Done\n\n```\n\n\n##### Snippet-01 Explained\n\nIn this example, we implemented ```Runnable``` by implementing the ```run()``` method from ```Runnable``` interface.\n\nTo run Task2 which is implementing `Runnable` interface, we used this code. We are using the `Thread` constructor passing an instance of `Task2`.\n\n```java\nTask2 task2 = new Task2();\nThread task2Thread = new Thread(task2);\ntask2Thread.start();\n```\n\nYou can see from the output that all three tasks are running in parallel.\n\n#### Summary\n\nIn this step, we:\n\n* Explored another way to create threads, by implementing the ```Runnable``` ```interface```\n* Learned to run a thread created using ```Runnable``` ```interface```\n \n### Step 03: The Thread Life-cycle  \n\nA Java Thread goes through a sequence of **states** during its lifetime. The term **life-cycle** is used to describe this fact, and clearly defines what specific state a thread could be in, at various points of time. \n\nLet's consider the following example we explored recently, in _**Step 02**_:\n\n```java\n\n\tclass Task1 extends Thread {\n\t\tpublic void run() {\n\t\t\tfor(int i=101; i\u003c=199; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\n\t\t\t}\n\t\t}\t\n\t}\n\n\tclass Task2 implements Runnable {\n\t\t@Override\n\t\tpublic void run() {\n\t\t\tfor(int i=201; i\u003c=299; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic class ThreadBasicsRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tTask1 task1 = new Task1();\n\t\t\ttask1.start();\n\t\t\tTask2 task2 = new Task2();\n\t\t\tThread task2Thread = new Thread(task2);\n\t\t\ttask2Thread.start();\n\t\t\tfor(int i=301; i\u003c=399; i++) {\t\t\t\n\t\t\t\tSystem.out.print(i + \" \");\n\t\t\t}\n\t\t}\n\t}\n\n```\n\nDifferent states of a thread are:\n\n* **NEW**: A thread is in this state as soon as it's been created, but its ```start()``` method hasn't yet been invoked.\n \n\t* For *Task1* : After the execution of ```Task1 task1 = new Task1();```\n\t* For *Task2* : After the execution of ```Task2 task2 = new Task2();  task2Thread = new Thread(task2);```\n\n* **TERMINATED/DEAD**: When all the statements inside a thread's ```run()``` method have been been completed, that thread is said to have terminated.\n\nA thread can be in any one of the remaining three states, after its ```start()``` method has been invoked.\n \n* **RUNNING**: If the thread is currently running.\n\n* **RUNNABLE**: If the thread is not currently running, but is ready to do so at any time.\n\n* **BLOCKED/WAITING**: If the thread is not currently running on the processor, but is not ready to execute either. This may be the case if it's waiting for an external resource (such as a user's input) or another thread.\n\n#### Summary\n\nIn this step, we:\n\n* Discussed different states of a Thread with an example\n\n### Step 04: Thread Priorities\nJava allows you to *request* the thread scheduler, to change the priority of a thread. The priority of any thread always lies in a fixed range - ```MIN_PRIORITY = 1``` to ```MAX_PRIORITY = 10```.  The default priority that's assigned to any thread, is ```NORM_PRIORITY = 5```. \n\nA request to change this priority is done by invoking the static ```setPriority(int)``` method, available in the ```Thread``` ```class```. This request may or may not be honored in response, so be prepared for that! \n\n### Step 05: Communicating Threads\n\nAny program where threads are not explicitly created is a single-threaded application. The thread that we refer to here is the *main thread*, executing the program's ```main()``` method.\n\nSometimes, threads might depend on one another. \n\nLet consider the example from **Step 02**. We want to add a condition - *Task3* should execute only after *Task1* terminates.\n\n**_ThreadBasicsRunner.java_**\n\n```java\n\n\tclass Task1 extends Thread {\n\t\tpublic void run() {\n\t\t\tSystem.out.println(\"Task1 Started \");\n\t\t\tfor(int i=101; i\u003c=199; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\n\t\t\t}\n\t\t}\n\t}\n\n\tclass Task2 implements Runnable {\n\t\t@Override\n\t\tpublic void run() {\n\t\t\tSystem.out.println(\"Task2 Started \");\n\t\t\tfor(int i=201; i\u003c=299; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\n\t\t\t}\n\t\t\tSystem.out.println(\"\\nTask2 Done\");\n\t\t}\n\t}\n\n\tpublic class ThreadBasicsRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tSystem.out.print(\"\\nTask1 Kicked Off\\n\");\n\t\t\tTask1 task1 = new Task1();\t\t\n\t\t\ttask1.start();\n\t\t\tSystem.out.print(\"\\nTask2 Kicked Off\\n\");\n\t\t\tTask2 task2 = new Task2();\n\t\t\tThread task2Thread = new Thread(task2);\n\t\t\ttask2Thread.start();\n\t\t\n\t\t\ttask1.join();\n\t\t\t\n\t\t\tSystem.out.print(\"\\nTask3 Kicked Off\\n\");\n\t\t\tfor(int i=301; i\u003c=399; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\n\t\t\t}\n\t\t\tSystem.out.println(\"\\nTask3 Done\");\n\t\t\tSystem.out.println(\"\\nMain Done\");\n\t\t}\n\t}\n\n```\n\n##### Snippet-5 Explained\n\n```task1.join()``` waits until task1 completes. So, the code after ```task1.join()``` will executed only on completion of `task1`.\n\nIf we want *Task3* to be executed only after both *Task1* and *Task2* are done, the code in ```main()``` needs to look as follows:\n\n##### Snippet-6 : Task3 after Task1 and Task2\n\n**_ThreadBasicsRunner.java_**\n\n```java\n\n\tpublic static void main(String[] args) {\n\t\tSystem.out.print(\"\\nTask1 Kicked Off\\n\");\n\t\tTask1 task1 = new Task1();\n\t\ttask1.start();\n\n\t\tSystem.out.print(\"\\nTask2 Kicked Off\\n\");\n\t\tTask2 task2 = new Task2();\n\t\tThread task2Thread = new Thread(task2);\n\t\ttask2Thread.start();\n\n\t\ttask1.join();\n\t\ttask2Thread.join();\n\n\t\tSystem.out.print(\"\\nTask3 Kicked Off\\n\");\n\t\tfor(int i=301; i\u003c=399; i++) {\n\t\t\tSystem.out.print(i + \" \");\n\t\t}\n\t\tSystem.out.println(\"\\nTask3 Done\");\n\t\tSystem.out.println(\"\\nMain Done\");\n\t\t\n\t}\n\n```\n\n##### Snippet-6 Explained\n\nIt is important to note that *Task1* and *Task2* are still independent sub-tasks. The thread scheduler is free to interleave their executions. However, *Task3* is kicked off only after both of them terminate.\n\n#### Summary\n\nIn this step, we:\n\n* Understood the need for thread communication\n* Learned that Java provides mechanisms for threads to wait for each other\n* Observed how the ```join()``` method can be used to sequence thread execution\n  \n### Step 07: ```synchronized``` Methods, And ```Thread``` Utilities\n\nWhen a thread gets tired, you can put it to bed. Heck, you can do it even when it's fresh and raring to go! It's under your control, remember? \n\nThe ```Thread``` class provides a couple of methods:\n* ```public static native void sleep(int millis)``` : Calling this method will cause the thread in question, to go into a *blocked* / *waiting* state for **at least** ```millis``` milliseconds.\n* ```public static native void yield()``` : Request thread scheduler to execute some other thread. The scheduler is free to ignore such requests.\n\n##### Snippet-01 : Thread utilities\n\n**jshell\u003e** ```Thread.sleep(1000)```\n\n\n**jshell\u003e** ```Thread.sleep(10000)```\n\n\n**jshell\u003e**\n\n##### Snippet-7 Explained\n\n* ```Thread.sleep(1000)``` causes the ```JShell``` prompt to appear after a delay of *at least* 1 second. This delay is even more visible, when we execute ```Thread.sleep(10000)```.\n\n\n### Step 08: Drawbacks of earlier approaches\n\nWe saw few of the methods for synchronization in the `Thread` class\n\n* ```start()```\n* ```join()```\n* ```sleep()```\n* ```wait()```\n\n\nAbove approaches have a few drawbacks:\n* **No Fine-Grained Control**: Suppose, for instance , we want *Task3* to run after *any one* of *Task1* or *Task2* is done. How do we do it?\n* **Difficult to maintain**: Imagine managing 5-10 threads with code written in earlier examples. It would become very difficult to maintain. \n* **NO Sub-Task Return Mechanism**: With the ```Thread``` ```class``` or the ```Runnable``` ```interface```, there is no way to get the result from a sub-task.\n\n### Step 09: Introducing ```ExecutorService```\n\nIn order to address the serious limitations of the ```Thread``` API, a new ```Executor Service``` was added in **Java SE 5**. \n\nThe ```ExecutorService``` is a framework you can use to manage threads in your code, better.  It has built-in ways to:\n* Create and launch threads more intuitively\n* Manage thread state and its life-cycle more easily\n* Synchronize between threads with more control, and\n* Handle groups of threads neatly\n\nThe ```ExecutorService``` provides utilities to achieve each one of these. Let's start with thread creation, which the next example takes care of.\n\n##### Snippet-01 : Creating a Thread\n\n**_ExecutorServiceRunner.java_**\n\n```java\n\n\timport java.util.concurrent.ExecutorService;\n\timport java.util.concurrent.Executors;\n\t\n\tclass Task1 extends Thread {\n\t\tpublic void run() {\n\t\t\tSystem.out.println(\"Task1 Started \");\n\t\t\tfor(int i=101; i\u003c=199; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\n\t\t\t}\n\t\t\tSystem.out.println(\"\\nTask1 Done\");\n\t\t}\n\t}\n\n\tclass Task2 implements Runnable {\n\t\t@Override\n\t\tpublic void run() {\n\t\t\tSystem.out.println(\"Task2 Started \");\n\t\t\tfor(int i=201; i\u003c=299; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\n\t\t\t}\n\t\t\tSystem.out.println(\"\\nTask2 Done\");\n\t\t}\n\t}\n\n\n\tpublic class ExecutorServiceRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tExecutorService executorService = Executors.newSingleThreadExecutor();\n\t\t\texecutorService.execute(new Task1());\n\t\t\texecutorService.execute(new Thread(new Task2()));\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Task1 Started_\n\n_101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199_\n\n_Task1 Done_\n\n_Task2 Started_\n\n_201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299_\n\n_Task2 Done_\n\n##### Snippet-01 Explained\n\n`ExecutorService executorService = Executors.newSingleThreadExecutor()` creates a single threaded executor service. That's why the tasks ran serially, one after the other.\n\n##### Snippet-02 : main runs in parallel\n\nLet's update the main method to do more things:\n\n```java\n\n\tpublic class ExecutorServiceRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tExecutorService executorService = Executors.newSingleThreadExecutor();\n\t\t\texecutorService.execute(new Task1());\n\t\t\texecutorService.execute(new Thread(new Task2()));\n\t\t\tSystem.out.print(\"\\nTask3 Kicked Off\\n\");\n\n\t\t\tfor(int i=301; i\u003c=399; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\n\t\t\t}\n\t\t\tSystem.out.println(\"\\nTask3 Done\");\n\t\t\tSystem.out.println(\"\\nMain Done\");\n\t\t\texecutorService.shutdown();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n```\nTask1 Started \n101 \nTask3 Kicked Off\n102 301 103 302 104 303 105 304 106 305 107 306 108 109 110 111 112 307 113 114 115 116 117 118 119 120 121 122 308 123 309 124 310 125 311 126 312 127 313 128 314 129 315 130 316 131 132 133 317 134 318 135 319 136 137 320 138 321 139 322 140 323 141 324 142 325 143 326 144 145 146 147 327 148 149 328 150 329 151 330 152 331 332 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 333 194 334 195 196 335 197 198 199 336 \nTask1 Done\n337 338 Task2 Started \n339 201 202 203 204 205 206 207 340 341 208 209 210 211 212 213 214 215 216 217 218 219 220 342 221 222 223 224 225 343 344 226 345 346 227 347 348 228 229 349 230 231 232 350 233 351 352 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 353 249 354 355 250 356 251 357 358 252 359 253 360 254 255 361 256 362 363 257 258 364 259 365 366 260 367 261 262 368 263 264 369 265 370 266 371 267 268 372 269 373 270 374 375 271 376 377 272 378 273 379 274 380 275 381 382 276 277 383 278 384 279 385 386 280 387 281 388 282 283 284 389 285 390 391 286 392 287 393 288 394 395 289 396 290 397 291 398 399 \nTask3 Done\n\nMain Done\n292 293 294 295 296 297 298 299 \nTask2 Done\n\n```\n\n##### Snippet-02 Explained\n\nThe only order that we see in the resulting chaos is: *Task2* starts execution only after *Task1* is done.\n\nThreads managed by `ExecutorService` run in parallel with `main` method.\n\n### Step 10: Executor -  Customizing Number Of Threads\n\nWith the ```ExecutorService```, it is possible to create a *pool* of threads.\n\nThe following examples will show you how you can create thread pools of varying kinds, and of course, of different sizes. \n\n##### Snippet-03 : Executors for Concurrent threads\n\n**_ExecutorServiceRunner.java_**\n\n```java\n\n\tpublic class ExecutorServiceRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tExecutorService executorService = Executors.newFixedThreadPool(2);\n\t\t\texecutorService.execute(new Task1());\n\t\t\texecutorService.execute(new Thread(new Task2()));\n\t\t\tSystem.out.print(\"\\nTask3 Kicked Off\\n\");\n\n\t\t\tfor(int i=301; i\u003c=399; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\n\t\t\t}\n\t\t\tSystem.out.println(\"\\nTask3 Done\");\n\t\t\tSystem.out.println(\"\\nMain Done\");\n\t\t\texecutorService.shutdown();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n```\nTask1 Started \n\nTask3 Kicked Off\n301 101 302 303 304 Task2 Started \n305 306 102 307 103 201 104 308 105 202 106 309 107 203 108 310 109 110 204 111 311 112 205 113 312 114 206 115 313 116 207 117 314 118 208 119 315 120 209 121 316 122 210 317 211 123 212 318 213 124 125 126 127 128 319 129 320 214 321 130 322 215 323 131 324 216 325 132 326 217 327 133 328 218 329 134 330 219 331 135 332 220 333 136 334 221 335 137 336 222 337 138 338 223 339 139 340 224 341 140 342 225 343 141 344 226 345 142 346 227 347 143 228 348 144 349 229 350 145 351 230 352 146 353 231 354 147 355 232 356 148 357 233 358 149 359 234 360 150 361 235 362 151 363 236 364 237 152 238 365 239 153 240 366 241 242 154 243 367 244 155 245 368 246 156 157 247 369 248 158 249 370 250 159 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 371 267 372 373 374 268 269 160 270 271 375 376 377 378 379 380 381 382 383 161 162 163 164 165 384 166 272 167 168 169 170 171 172 385 173 386 387 273 388 389 174 390 391 274 392 175 393 275 394 176 395 276 396 397 177 398 178 179 277 180 399 181 278 182 183 \nTask3 Done\n\nMain Done\n184 185 279 280 281 282 283 186 187 284 285 286 188 189 287 288 289 190 191 290 192 291 193 292 194 293 195 196 294 295 296 297 298 299 \nTask2 Done\n197 198 199 \nTask1 Done\n```\n\n##### Snippet-03 Explained\n\nWe created `ExecutorService` by using `Executors.newFixedThreadPool(2)`. So, 'ExecutorService` uses two parallel threads at a maximum.\n* *Task1* and *Task2* execute concurrently as part of the ```ExecutorService```, and\n* The thread running ```main()``` executes concurrently with this thread pool, created by ```ExecutorService```.\n\n\n##### Snippet-04 : All-Executor Task Execution\n\nLet's create a simple example to allow to play with 'ExecutorService'.\n\n**_ExecutorServiceRunner.java_**\n\n```java\n\n\timport java.util.concurrent.ExecutorService;\n\timport java.util.concurrent.Executors;\n\n\tclass Task extends Thread {\n\t\tprivate int number;\n\t\t\n\t\tpublic Task(int number) {\n\t\t\tthis.number = number;\n\t\t}\n\n\t\tpublic void run() {\n\t\t\tSystem.out.println(\"Task \" + number + \" Started\");\n\t\t\tfor(int i=number*100; i\u003c=number*100+99; i++) {\n\t\t\t\tSystem.out.print(i + \" \");\n\t\t\t}\n\t\t\tSystem.out.println(\"\\nTask \" + number +\" Done\");\n\t\t}\n\t}\n\n\tpublic class ExecutorServiceRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tExecutorService executorService = Executors.newFixedThreadPool(2);\n\t\t\texecutorService.execute(new Task(1));\n\t\t\texecutorService.execute(new Task(2));\n\t\t\texecutorService.execute(new Task(3));\n\t\t\texecutorService.shutdown();\n\t\t}\n\t}\n\n```\n\n\n##### Snippet-04 Explained\n\n`Executors.newFixedThreadPool(2)` - Two threads in parallel. The thread ```new Task(3)``` is executed only after any one of ```new Task(1)``` and ```new Task(2)``` have completed their execution.\n\n##### Snippet-04 : Larger Thread Pool Size\n\n```java\n\n\tpublic class ExecutorServiceRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tExecutorService executorService = Executors.newFixedThreadPool(3);\n\t\t\texecutorService.execute(new Task(1));\n\t\t\texecutorService.execute(new Task(2));\n\t\t\texecutorService.execute(new Task(3));\n\t\t\texecutorService.execute(new Task(4));\n\t\t\texecutorService.execute(new Task(5));\n\t\t\texecutorService.execute(new Task(6));\n\t\t\texecutorService.execute(new Task(7));\n\t\t\texecutorService.shutdown();\n\t\t}\n\t}\n\n```\n\n\n##### Snippet-04 Explained\n\nWe made the pool larger to 3:\n* Initially Tasks ```1```, ```2```, ```3``` are added to the ```ExecutorService``` and are started.\n* As soon as any one of them is terminated, another task from the thread pool is picked up for execution, and so on. A classic case of musical chairs, with regard to the slots available in the ```ExecutorService``` thread pool, is played out here!\n\n#### Summary\n\nIn this step, we:\n\n* Explored how one can create pools of threads of the same kind, using the ```ExecutorService```\n* Noted how one could specify the size of a thread pool\n\n### Step 11:  ```ExecutorService```: Returning Values From Tasks\n\n##### Snippet-01: Returning a Future Object\n\nSo far, we have only seen sub-tasks that are largely independent, and which don't return any result to the main program that launched them.\n\nTo be able to return a value from a Thread, Java provides a ```Callable\u003cT\u003e``` interface.\n\nThe next example tells you how to implement ```Callable\u003cT\u003e```, and use it with ```ExecutorService```.\n\n**_ExecutorServiceRunner.java_**\n\n```java\n\n\timport java.util.concurrent.ExecutorService;\n\timport java.util.concurrent.Executors;\n\timport java.util.concurrent.Callable;\n\n\tclass CallableTask implements Callable\u003cString\u003e {\n\t\tprivate String name;\n\n\t\tpublic CallableTask(String name) {\n\t\t\tthis.name = name;\n\t\t}\n\n\t\t@Override\n\t\tpublic String call() throws Exception {\n\t\t\tThread.sleep(1000);\n\t\t\treturn \"Hello \" + name;\n\t\t}\n\t}\n\n\tpublic class CallableRunner {\n\t\tpublic static void main(String[] args) throws InterruptedException, ExecutionException {\n\t\t\tExecutorService executorService = Executors.newFixedThreadPool(1);\n\t\t\tFuture\u003cString\u003e welcomeFuture = executorService.submit(new CallableTask(\"in28Minutes\"));\n\t\t\tSystem.out.println(\"CallableTask in28Minutes Submitted\");\n\t\t\tString welcomeMessage = welcomeFuture.get();\n\t\t\tSystem.out.println(welcomeMessage);\n\t\t\texecutorService.shutdown();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_CallableTask in28Minutes Submitted_\n\n_Hello in28Minutes_\n\n##### Snippet-01 Explained\n\n- `class CallableTask implements Callable\u003cString\u003e` - Implement `Callable`. Return type is `String`\n- `public String call() throws Exception {` - Implement `call` method and return a `String` value back.\n-  ```executorService.submit(new CallableTask(String))``` adds a callable task to its thread pool. This puts the task thread in a **RUNNABLE** state. Subsequently, the program goes ahead to invoke its ```call()``` method.\n- `welcomeFuture.get()` - Ensures that the `main` thread waits for the result of the operation. \n\n\n#### Summary\n\nIn this step, we:\n\n* Understood the need for a mechanism, to create sub-tasks that return values\n* Discovered that Java has a ```Callable\u003cT\u003e``` interface to do exactly this\n* Saw that the ```ExecutorService``` is capable of managing ```Callable``` threads\n\n### Step 11: Executors - Waiting For Many Callable Tasks To Complete\n\n```ExecutorService``` framework also allows you to create a pool of ```Callable``` threads. Not only that, you can collect their return values together.\n\n##### Snippet-01 : Waiting for Multiple ```Callable``` Threads \n\n**_MultipleCallableRunner.java_**\n\n```java\n\n\timport java.util.concurrent.ExecutorService;\n\timport java.util.concurrent.Executors;\n\timport java.util.concurrent.Callable;\n\n\tclass CallableTask implements Callable\u003cString\u003e {\n\t\tprivate String name;\n\n\t\tpublic CallableTask(String name) {\n\t\t\tthis.name = name;\n\t\t}\n\n\t\t@Override\n\t\tpublic String call() throws Exception {\n\t\t\tThread.sleep(1000);\n\t\t\treturn \"Hello \" + name;\n\t\t}\n\t}\n\n\tpublic class MultipleCallableRunner {\n\t\tpublic static void main(String[] args) throws InterruptedException, ExecutionException {\n\t\t\tExecutorService executorService = Executors.newFixedThreadPool(1);\n\t\t\tList\u003cCallableTask\u003e tasks = List.of(new CallableTask(\"in28Minutes\"),\n\t\t\t\t\t\t\t\t\t\t\t\tnew CallableTask(\"Ranga\"),\n\t\t\t\t\t\t\t\t\t\t\t\tnew CallableTask(\"Adam\"));\n\t\t\tList\u003cFuture\u003cString\u003e\u003e welcomeAll = executorService.invokeAll(tasks);\n\t\t\tfor(Future\u003cString\u003e welcomeFuture : welcomeAll) {\n\t\t\t\tSystem.out.println(welcomeFuture.get());\n\t\t\t}\n\t\t\texecutorService.shutdown();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Hello in28Minutes_\n\n_Hello Ranga_\n\n_Hello Adam_\n\n##### Snippet-01 Explained\n\nThe ```invokeAll()``` method of  ```ExecutorService``` allows for a list of ```Callable``` tasks to be launched in the thread pool. Also, a ```List``` of ```Future``` objects can be used to hold return values, one for each such ```Callable``` thread.\n\nThe list of return values can be accessed only after **all** the threads are done, and have returned their results. \n\nThis can be verified from the console output. all the planned welcome messages are printed in one go, but only after a wait of at least ```3000``` milliseconds has been completed.\n\nLet's now see what scenario would pan out with a larger thread pool size. \n\n##### Snippet-02 : List of Callable tasks with larger thread pool\n\n```java\n\n\tpublic class MultipleCallableRunner {\n\t\tpublic static void main(String[] args) throws InterruptedException, ExecutionException {\n\t\t\tExecutorService executorService = Executors.newFixedThreadPool(3);\n\t\t\tList\u003cCallableTask\u003e tasks = List.of(new CallableTask(\"in28Minutes\"),\n\t\t\t\t\t\t\t\t\t\t\t\tnew CallableTask(\"Ranga\"),\n\t\t\t\t\t\t\t\t\t\t\t\tnew CallableTask(\"Adam\"));\n\t\t\tList\u003cFuture\u003cString\u003e\u003e welcomeAll = executorService.invokeAll(tasks);\n\t\t\tfor(Future\u003cString\u003e welcomeFuture : welcomeAll) {\n\t\t\t\tSystem.out.println(welcomeFuture.get());\n\t\t\t}\n\t\t\texecutorService.shutdown();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Hello in28Minutes_\n\n_Hello Ranga_\n\n_Hello Adam_\n\n##### Snippet-02 Explained\n\nThe welcome messages all get printed in a batch again, but their collective wait gets shorter. This is because:\n* The thread pool size is now ```3```, not ```2``` as earlier. This means all the three tasks can be put in the **RUNNABLE** state at once. \n* Then, they go into their **BLOCKED** state also almost simultaneously, which means their collective wait time is much less than ```3000``` milliseconds. That's one advantage of a larger thread pool!\n\n#### Summary \n\nIn this step, we:\n\n* Learned that it's possible to collect the return values of a pool of ```Callable``` threads, at one go.\n* This is done using the ```invokeAll()``` method for their launch, and specifying a ```List``` of ```Future``` objects to hold these results\n* Changing the thread pool size for such scenarios can change response time dramatically\n\n### Step 12:  Executor - Wait Only For The Fastest Task\n\nLet's look at how you can wait for any of the three tasks to complete.\n\n##### Snippet-01 : Wait only for fastest\n\n```java\n\n\tpublic class MultipleAnyCallableRunner {\n\t\tpublic static void main(String[] args) throws InterruptedException, ExecutionException {\n\t\t\tExecutorService executorService = Executors.newFixedThreadPool(3);\n\t\t\tList\u003cCallableTask\u003e tasks = List.of(new CallableTask(\"in28Minutes\"),\n\t\t\t\t\t\t\t\t\t\t\t\tnew CallableTask(\"Ranga\"),\n\t\t\t\t\t\t\t\t\t\t\t\tnew CallableTask(\"Adam\"));\n\t\t\tString welcomeMessage = executorService.invokeAny(tasks);\n\t\t\tSystem.out.println(welcomeMessage);\n\t\t\texecutorService.shutdown();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Hello Ranga_\n\n**_Console Output_**\n\n_Hello in28Minutes_\n\n**_Console Output_**\n\n_Hello Ranga_\n\n**_Console Output_**\n\n_Hello Adam_\n\n##### Snippet-01 Explained\n\nThe method ```invokeAny()``` returns when the first of the sub-tasks is done. Also, the returned value is not a ```Future``` object. It's the return value of the ```call()``` method.\n\nWe can see that over different executions, the order of console output changes. This is because: \n* All three tasks are created together, in a thread pool of size ```3```. \n* Therefore, these are independent threads, going into their **RUNNABLE** states almost at once. \n\n#### Summary\n\nIn this step, we:\n\n* Learned that ```ExecutorService``` has a way to return the first result, from a poll of ```Callable``` threads\n\n## Introduction To Exception handling\n\n\nRecommended Exception handling Videos\n- https://www.youtube.com/watch?v=34ttwuxHtAE\n\nThere are two kinds of errors a programmer faces:\n\n* **Compile-time** Errors: Flagged by the compiler when it detects syntax or semantic errors.\n* **Run-time** Errors: Detected by the run-time environment when executing code\n\nExample runtime errors include:\n* Running out of *heap-memory* for objects, or space for the method *call stack*\n* Dividing a number by ```0```\n* Trying to *read* from an *unopened* file\n\nExceptions are *unexpected* conditions; their occurrence does not make a programmer bad (or good, for that matter). It is a programmer's responsibility to be *aware* of potential exceptional conditions in her program, and use a mechanism to *handle* them effectively.\n\nHandling an exception generally involves two important aims:\n1. Provide a useful message to the end user.\n2. Log enough information to help a programmer identify root cause.\n\n### Step 01: Introducing Exceptions\n\nIn the previous step, we gave you a few instances of exceptions, such as your program running out of memory, or your code trying to divide a number by ```0```. \n\nWant to see a live example of the Java run-time throwing an exception? The next example will satisfy your thirst.\n\n##### Snippet-1 : Exception Condition\n\n**_ExceptionHandlingRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.exceptionhandling;\n\t\n\tpublic class ExceptionHandlingRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tcallMethod();\n\t\t\tSystem.out.println(\"callMethod Done\");\t\t\n\t\t}\n\n\t\tstatic void callMethod() {\n\t\t\tString str = null;\n\t\t\tint len = str.length();\n\t\t\tSystem.out.println(\"String Length Done\");\n\t\t}\t\t\n\t}\t\n\n```\n\n**_Console Output_**\n\n**_java.lang.NullPointerException_**\n\n_Exception in thread \"main\" java.lang.NullPointerException_\n\n_at com.in28minutes.exceptionhandling.ExceptionHandlingRunner.callMethod (ExceptionHandlingRunner.java:8)_\n\n_at com.in28minutes.exceptionhandling.ExceptionHandlingRunner.main (ExceptionHandlingRunner.java:4)_\n\n\n##### Snippet-01 Explained\n\nA ```java.lang.NullPointerException``` is **thrown** by the Java run-time when we called ```length()``` on the `null` reference.\n\nIf an exception is not handled in the entire call chain, including `main`, the exception is thrown out and the program terminates. ```System.out.println()``` statements after the exception are never executed. \n\nThe runtime prints the **call stack trace** onto the console. \n\nFor instance, consider this simple ```class``` ```Test```:\n\n```java\n\n\tpublic class Test {\n\t\tpublic static void main(String[] args) {\n\t\t\tcallOne();\n\t\t}\n\n\t\tpublic static void callOne() {\n\t\t\tcallTwo();\n\t\t}\n\n\t\tpublic static void callTwo() {\n\t\t\tcallThree();\n\t\t}\n\n\t\tpublic static void callThree() {\n\t\t\tString name;\n\t\t\tSystem.out.println(\"This name is %d characters long\", name.length());\n\t\t}\n\t}\n\n``` \n\nHowever, the code name.length() used in ```callThree()``` caused a ```NullPointerException``` to be thrown. However, this is  not handled, and the console coughs up the following display:\n\t\t\n_Exception in thread \"main\" java.lang.NullPointerException_\n\n_at Test.callThree(Test.java:13)_\n\n_at Test.callTwo(Test.java:9)_\n\n_at Test.callOne(Test.java:6)_\n\n_at Test.main(Test.java:3)_\n\nThis is nothing but a call trace of the stack, *frozen in time*.\n\n#### Summary\n\nIn this step, we:\n\n* Saw a live example of an exception being thrown\n* Understood how a call trace on the stack appears when a exception occurs\n* Reinforced this understanding with another example\n\n### Step 02: Handling An Exception\n\nIn Java, exception handling is achieved through a **```try```-```catch```** *block*. \n\n##### Snippet-01 : Handling An Exception\n\n**_ExceptionHandlingRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.exceptionhandling;\n\t\n\tpublic class ExceptionHandlingRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tmethod1();\n\t\t\tSystem.out.println(\"main() Done\");\n\t\t}\n\t\t\n\t\tstatic void method1() {\n\t\t\tmethod2();\n\t\t\tSystem.out.println(\"method1() done\");\n\t\t}\n\n\t\tstatic void method2() {\n\t\t\ttry {\n\t\t\t\tString str = null;\n\t\t\t\tint len = str.length();\n\t\t\t\tSystem.out.println(\"method2() Done\");\n\t\t\t} catch (Exception ex) {\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_method1() Done_\n\n_main() Done_\n\n##### Snippet-01 Explained\n\nWe have handled an exception here with a ```try```-```catch``` block. Its syntax resembles this:\n\n```java\n\n\ttry {\n\t\t//\u003c program-logic code block \u003e\n\t} catch (Exception e) {\t\t\n\t\t//\u003c exception-handling code block \u003e\n\t}\n\n```\n\nThe exception (the ```NullPointerException```) still occurs after adding this block, but now it's actually **caught**. Although we did nothing with the caught exception, we did avoid a sudden end of the program.\n\nThe statements following  ```int len = str.length()``` in `method2` are not executed. \n\nHowever, all of ```method1()```'s code was run (with the ```\"method1 Done\"``` message getting printed). ```main()``` method also completed execution successfully.\n\nThe program thus terminated gracefully. ```method1()``` and ```main()``` are both unaware of the ```NullPointerException``` occurring within ```method2()```.\n\n##### Snippet-02: Print Debug Information\n\nLet's add `ex.printStackTrace();`.\n\n**_ExceptionHandlingRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.exceptionhandling;\n\n\tpublic class ExceptionHandlingRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tmethod1();\n\t\t\tSystem.out.println(\"main() Done\");\n\t\t}\n\n\t\tstatic void method1() {\n\t\t\tmethod2();\n\t\t\tSystem.out.println(\"method1() done\");\n\t\t}\n\n\t\tstatic void method2() {\n\t\t\ttry {\n\t\t\t\tString str = null;\n\t\t\t\tint len = str.length();\n\t\t\t\tSystem.out.println(\"method2() Done\");\n\t\t\t} catch (Exception ex) {\n\t\t\t\tex.printStackTrace();\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n**_java.lang.NullPointerException_**\n\n_Exception in thread \"main\" java.lang.NullPointerException_\n\n_at com.in28minutes.exceptionhandling.ExceptionHandlingRunner.method2 (ExceptionHandlingRunner.java:14)_\n\n_at com.in28minutes.exceptionhandling.ExceptionHandlingRunner.method1 (ExceptionHandlingRunner.java:8)_\n\n_at com.in28minutes.exceptionhandling.ExceptionHandlingRunner.main (ExceptionHandlingRunner.java:4)_\n\n_method1() Done_\n\n_main() Done_\n\n\n```printStackTrace()``` is provided by the ```Exception``` ```class```, which every exception inherits from. This method prints the frozen call trace of the program when the exception occurred, but without terminating the program. The code next continues to run.\n\nThe stack trace provides useful information to you, the programmer,to debug the exception scenario.\n\n#### Summary\n\nIn this step, we:\n\n* Were introduced to Java's basic mechanism to handle exceptions, the ```try```-```catch``` block\n* Saw how a program runs and ends gracefully, when an exception is handled\n* Observed how the ```printStackTrace``` method gives debug information to the programmer\n\n### Step 03: The ```Exception``` Hierarchy \n\nThe code in the ```try```-```catch``` block above does not work by black magic. From the call trace, it's clear that this program encounters a ```NullPointerException``` in ```method1()```. What's surprising, is that it was caught by a ```catch``` clause meant for an ```Exception```! The reason this worked is because ```NullPointerException``` **is-a** ```Exception```.\n\nYou heard right! Java has a hierarchy of exception types, rooted at ```class``` ```Exception```. For instance, \n\n* ```NullPointerException``` **is-a** ```RuntimeException```, and \n* ```RuntimeException``` **is-a** ```Exception```. \n* So effectively, ```NullPointerException``` **is-a** ```Exception```!\n\nDifferent branches of this inheritance-tree actually denote different exception categories. We'll dwell on this topic a little later.  \n\n\n##### Snippet-01 : Catching NullPointerException\n\nLet's add an additional catch for `NullPointerException` in method2.\n\n**_ExceptionHandlingRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.exceptionhandling;\n\t\n\tpublic class ExceptionHandlingRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tmethod1();\n\t\t\tSystem.out.println(\"main() Done\");\n\t\t}\n\n\t\tstatic void method1() {\n\t\t\tmethod2();\n\t\t\tSystem.out.println(\"method1() done\");\t\t\n\t\t}\n\n\t\tstatic void method2() {\n\t\t\ttry {\n\t\t\t\tString str = null;\n\t\t\t\tint len = str.length();\n\t\t\t\tSystem.out.println(\"method2() Done\");\n\t\t\t} catch (NullPointerException e) {\n\t\t\t\tSystem.out.println(\"NullPointerException\");\n\t\t\t} catch (Exception ex) {\n\t\t\t\tex.printStackTrace();\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n**_NullPointerException_**\n\n_method1() Done_\n\n_main() Done_\n\n##### Snippet-01 Explained\n\n_Among all the ```catch``` clauses following the ```try```, **one and only one** of them, may get executed. The **first** ```catch``` clause to **match**, **in serial order** after the ```try```, always gets executed. If **none** match, the exception is **not handled**._\n\nWe placed an additional ```catch``` block within ```method2()```, to handle ```NullPointerException``` . Typically, the most specific exception class is matched. Hence the catch block for `NullPointerException` matches.\n\n\nYou need to order the ```catch``` blocks after a ```try```, from more-specific to less-specific matches.   \n\n##### Snippet-02 : Catching another exception\n\n```java\n\n\tpackage com.in28minutes.exceptionhandling;\n\n\tpublic class ExceptionHandlingRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tmethod1();\n\t\t\tSystem.out.println(\"main() Done\");\n\t\t}\n\n\t\tstatic void method1() {\n\t\t\tmethod2();\n\t\t\tSystem.out.println(\"method1() done\");\n\t\t}\n\n\t\tstatic void method2() {\n\t\t\ttry {\n\t\t\t\tint[] numbers = {1, 2};\n\t\t\t\tint num = numbers[3];\n\t\t\t\tSystem.out.println(\"method2() Done\");\n\t\t\t} catch (NullPointerException e) {\n\t\t\t\tSystem.out.println(\"NullPointerException\");\n\t\t\t} catch (Exception ex) {\n\t\t\t\tex.printStackTrace();\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n**_ArrayIndexOutOfBoundsException : 3_**\n\n_Exception in thread \"main\" java.lang.ArrayIndexOutOfBoundsException_\n\n_at com.in28minutes.exceptionhandling.ExceptionHandlingRunner.method2 (ExceptionHandlingRunner.java:14)_\n\n_at com.in28minutes.exceptionhandling.ExceptionHandlingRunner.method1 (ExceptionHandlingRunner.java:8)_\n\n_at com.in28minutes.exceptionhandling.ExceptionHandlingRunner.main (ExceptionHandlingRunner.java:4)_\n\n_method1() Done_\n\n_main() Done_\n\n##### Snippet-02 Explained\n\n```ArrayIndexOutOfBoundsException``` **is-a** ```IndexOutOfBoundsException```, which **is-a** ```RuntimeException```, which in turn **is-a** ```Exception```.  \n\n```ArrayIndexOutOfBoundsException``` is not a sub class of ```NullPointerException```. Hence, it does not match with the first catch block. ```ArrayIndexOutOfBoundsException``` is a sub class of  ```Exception```. Hence, that ```catch``` block matched, and the statement ```ex.printStackTrace();``` within it ran.\n\nIf we omit the handler for ```Exception```, the ```ArrayIndexOutOfBoundsException``` is not caught by this ```try```-```catch``` block. Since it is not handled in ```method1()```, or even later in ```main()```, our program would have to stop suddenly. \n \n#### Summary\n\nIn this step, we:\n\n* Learned that there is an exception hierarchy in Java, rooted at ```Exception```\n* Looked at an example that could cause multiple exceptions to occur\n* Observed how a handler for ```Exception``` could match any exception\n\n- - - \n### Step 04:  The Need For ```finally```\n\nWhen an exception occurs, the programmer's world can turn upside-down in a matter of moments. If not handled, the program terminates all of a sudden, with no light at the end of the tunnel.\n\n##### Snippet-01 : Unreleased Resources\n\n**_FinallyRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.exceptionhandling;\n\timport java.util.Scanner;\n\n\tpublic class FinallyRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tScanner scanner = new Scanner(System.in);\n\t\t\t// ... Program logic, probably using scanner input\n\t\t\tint num = numbers[5];\n\t\t\tSystem.out.println(\"Before scanner close\");\n\t\t\tscanner.close();\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Exception in thread \"main\" java.lang.ArrayIndexOutOfBoundsException_\n\n_at com.in28minutes.exceptionhandling.FinallyRunner.main (FinallyRunner.java:8)_\n\n##### Snippet-01 Explained\n\nThis example makes use of `Scanner` object to read from console. Ideally a `Scanner` object should be closed using ```scanner.close();```. \n\nHowever, in our example, it is not called because a line before it threw an exception. (```int num = numbers[5];``` tries to access the 5th element of a 4-element array). \n\nWhat this means, is a system resource that has been acquired, is never released. \n\nIt's important to ensure that any acquired resource is always released; whether on normal or abrupt termination. Let's see how you do this while handling an exception.\n\n##### Snippet-02 : Releasing Resources\n\n**_FinallyRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.exceptionhandling;\n\timport java.util.Scanner;\n\n\tpublic class FinallyRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tScanner scanner = null;\n\t\t\ttry {\n\t\t\t\tscanner = new Scanner(System.in);\n\t\t\t\t// ... Program logic, probably using scanner input\n\t\t\t\tint[] numbers = {1, 2, 3, 4};\n\t\t\t\tint num = numbers[5];\n\t\t\t} catch (Exception e) {\n\t\t\t\te.printStackTrace();\n\t\t\t} finally {\n\t\t\t\tif(scanner != null) {\n\t\t\t\t\tSystem.out.println(\"Before scanner close\");\n\t\t\t\t\tscanner.close();\n\t\t\t\t}\t\t\n\t\t\t}\n\t\t\tSystem.out.println(\"Before exiting main\");\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n**_ArrayIndexOutOfBoundsException_**\n\n_Exception in thread \"main\" java.lang.ArrayIndexOutOfBoundsException_\n\n_at com.in28minutes.exceptionhandling.FinallyRunner.main (FinallyRunner.java:10)_\n\n_Before scanner close_\n\n_Before exiting main_\n\n##### Snippet-02 Explained\n\nCode in ```finally``` is almost always executed - even when there are exceptions. \n\nWe added a null check on `scanner` since ```scanner = new Scanner(System.in);``` could also result in an exception.\n\n```java\n\n\t} finally {\n\t\tif(scanner != null) {\n\t\t\tSystem.out.println(\"Before scanner close\");\n\t\t\tscanner.close();\n\t\t}\n\t}\n\n```\n\n#### Summary\n\nIn this step, we:\n\n* Observed how exceptional conditions could result in resource leaks\n* Learned about the ```finally``` clause in a ```try```-```catch``` block\n\n### Step 05: Programming Puzzles -  PP-01\n\n#### Puzzle-01\n\n* Would the ```finally``` clause be executed if\n\t* The statement ```//str = \"Hello\";``` remains as-is\n\t* The statement ```//str = \"Hello\";``` has its comments removed? \n\n```java\n \n\tpublic static void method3() {\n\t\tConnection connection = new Connection();\n\t\tconnection.open();\n\t\ttry {\n\t\t\tString str = null;\n\t\t\t//str = \"Hello\";\n\t\t\tstr.toString();\n\t\t\treturn;\t\t\n\t\t} catch(Exception e) {\t\t\n\t\t} finally {\n\t\t\tconnection.close();\n\t\t}\n\t}\n\n```\n\n* **_Answer_**\n\t* Yes\n\t* Yes\n\n#### Puzzle-02\n\n* When will code in a ```finally``` clause not get executed?\n\n* **_Answer_**\n\t* In case of statements within the same ```finally``` clause, preceding this code, throwing an exception \n\t* In case of a JVM crash. This can be simulated in some scenarios by calling ```System.exit``` with an appropriate ```int``` argument, within an appropriate ```catch``` clause of the same ```try```-```catch```-```finally``` clause.\n \n#### Puzzle-03\n\n* Will the following code, a ```try```-```finally``` without a ```catch```?\n\n```java\n\n\tpublic static void method4() {\n\t\tConnection connection = new Connection();\n\t\tconnection.open();\n\t\ttry {\n\t\t\tString str = null;\n\t\t\t//str = \"Hello\";\n\t\t\tstr.toString();\n\t\t\treturn;\n\t\t} finally {\n\t\t\tconnection.close();\n\t\t}\t\n\t}\n\n```\n\n* **_Answer_** : Yes\n\n#### Puzzle-04\n\n* Will the following code, a ```try``` without a ```catch``` or a ```finally```?\n\n```java\n\n\tpublic static void method5() {\n\t\tConnection connection = new Connection();\n\t\tconnection.open();\n\t\ttry {\n\t\t\tString str = null;\n\t\t\t//str = \"Hello\";\n\t\t\tstr.toString();\n\t\t\treturn;\n\t\t}\n\t}\n\n```\n\n* **_Answer_** : No\n\n### Step 06: Handling Exceptions: Do We Have A Choice?\n\nSometimes, in Java you are forced to handle exceptions.\n\n##### Snippet-02: Checked Exceptions - v1\n\n**_CheckedExceptionRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.exceptionhandling;\n\t\n\tpublic class CheckedExceptionRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tThread.sleep(2000);\n\t\t}\n\t}\n\n```\n\n##### Snippet-02 Explained \n\n**_This program will not compile!_**\n\nThe reason we get flagged by a compiler error, lies in the signature of the ```sleep()``` method. Here is its definition within the ```Thread``` ```class```:\n\n```java\n\n\tpublic static native void sleep(long millis) throws InterruptedException {\n\t\t//...\n\t}\n\n```\n\nThis declaration is a bit different from what you normally expect for a method, isn't it!  It contains a **```throws``` specification**. \n\nWhen a method `throws` an Exception, the calling method should:\n* Handle it using ```try```-```catch``` block\n* Or declare `throws` in its signature\n\nLet's use ```try```-```catch``` block to start off.\n\n##### Snippet-03: Checked Exceptions - v2\n\n**_CheckedExceptionRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.exceptionhandling;\n\n\tpublic class CheckedExceptionRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\ttry {\n\t\t\t\tThread.sleep(2000);\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n##### Snippet-03 Explained\n\n* ```main()```, which is the caller of ```sleep()```, chooses the option of handling ```InterruptedException``` with a ```try```-```catch``` block.\n\n#### The ```throws``` keyword\n\n```throws``` is used to declare that a method might throw exceptions. This involves a ```throws``` keyword, followed by a list of exception types. \n\n##### Snippet-04 : Method with risky code #1\n\n```java\n\n\tpackage com.in28minutes.exceptionhandling;\n\n\tpublic class CheckedExceptionRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\ttry {\n\t\t\t\triskyMethod();\n\t\t\t\tThread.sleep(2000);\n\t\t\t} catch (InterruptedException e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\n\t\tpublic static void riskyMethod() throws InterruptedException {\n\t\t\tThread.sleep(5000);\n\t\t}\n\t}\n\n```\n\n##### Snippet-04 Explained\n\nHere, we have removed the ```try```-```catch``` block within ```riskyMethod()```, because we want to follow another way of managing the exception. As an alternative, we added a ```throws``` specification to ```riskyMethod()``` to make the code compile. \n\nWe made `main` method handle the exception.\n\n#### Summary\n\nIn this step, we:\n\n* Discovered that certain exceptions in Java do not force you to handle them\n* Learned that all the rest must be managed/handled\n* Observed that there are two ways to manage those \"Checked\" exceptions:\n\t* Handling with a ```try```-```catch``` block\n\t* Using a ```throws``` specification \n\n### Step 08: The Java Exception Hierarchy\n\nRight at the root (top, we mean), the Java exception hierarchy looks like this:\n\n```java\n\n\tclass Error extends Throwable{}\n\tclass Exception extends Throwable{}\t\n\tclass InterruptedException extends Exception{}\n\tclass RuntimeException extends Exception{}\n\tclass NullPointerException extends RuntimeException{}\n\t...\n\n```\n\nOnce an ```Error``` occurs, there is nothing a programmer could do. Examples include: \n*  The JVM running out of heap memory space\n\nAn `Exception` can be handled. There are two types of Exceptions.\n* ```RuntimeException``` and its sub-classes. These come under the category of **unchecked exceptions**. Another example we've seen is ```NullPointerException```, which inherits from ```RuntimeException```.\n* All other sub-classes of ```Exception```, excluding the sub-tree rooted at ```RuntimeException```, are called **checked exceptions**. An instance we've encountered is ```InterruptedException```.\n\n\nIf a method throws a **checked exception** is called, then either:\n* The method call must be enclosed in a ```try```-```catch``` block for proper handling, or \n* The caller must throw this exception out, to its own caller. Its signature must also be enhanced using a ```throws``` specification. \n\nIf an **unchecked exception** is involved, then:\n*  You have the options of handling with  ```try```-```catch``` block.\n*  It is not mandatory to handle it.\n\nA **checked** exception **must** be handled, whereas as **unchecked** exception **may or may not** be handled.\n\n#### Summary\n\nIn this step, we:\n\n* Discovered that within the Java exception hierarchy, there are two categories:\n\t* Checked exceptions\n\t* Unchecked exceptions\n* There are different strategies to manage these two categories\n\n### Step 09: Throwing an Exception\n\nSo far, we have seen how to handle an exception, that is thrown by a built-in Java method. Now, let's explore how we can alert a user about exceptional conditions in our own code, by **throwing** exceptions. \n\n##### Snippet-01 : Throwing An Exception\n\n**_ThrowingExceptionRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.exceptionhandling;\n\n\tclass Amounts {\n\t\tprivate String currency;\n\t\tprivate int amount;\n\n\t\tpublic Amounts(String currency, int amount) {\n\t\t\tsuper();\n\t\t\tthis.currency = currency;\n\t\t\tthis.amount = amount;\n\t\t}\n\n\t\tpublic void add(Amount that) {\n\t\t\tif(!this.currency.equals(that.currency)) {\n\t\t\t\tthrow new RuntimeException(\"Currencies Don't Match\");\n\t\t\t}\n\t\t\tthis.amount += that.amount;\n\t\t}\n\n\t\tpublic Sring toString() {\n\t\t\treturn amount + \" \" + currency;\n\t\t}\n\t}\n\n\tpublic class ThrowingExceptionRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tAmount amount1 = new Amount(\"USD\", 10);\n\t\t\t//Amount amount2 = new Amount(\"USD\", 20);\n\t\t\tAmount amount2 = new Amount(\"EUR\", 20);\n\t\t\tamount1.add(amount2);\n\t\t\tSystem.out.println(amount1);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_Exception in thread \"main\" java.lang.RuntimeException:Currencies Don't Match_\n\n_at com.in28minutes.exceptionhandling.ThrowingExceptionRunner.main (ThrowingExceptionRunner.java:26)_\n\n##### Snippet-01 Explained\n\nSince adding ```10 USD``` and ```20 EUR``` does not make sense in the real world, it's important to tell the user that ```add()``` won't work for different currencies. The most direct way is to throw an exception, which the code ```throw new RuntimeException(\"Currencies Don't Match\");``` does. \n\nThis thrown exception object can be handled inside ```main()```. By calling ```printStackTrace()``` on the caught exception reference,  you get debug information like before.\n\n##### Snippet-02 : Throwing a Checked Exception\n\n`Exception` is a Checked Exception. If a method throws an instance of `Exception` class, it needs to declare it -  `public void add(Amount that) throws Exception {`.\n\n**_ThrowingExceptionRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.exceptionhandling;\n\t\n\tclass Amounts {\n\t\tprivate String currency;\n\t\tprivate int amount;\n\n\t\tpublic Amounts(String currency, int amount) {\n\t\t\tsuper();\n\t\t\tthis.currency = currency;\n\t\t\tthis.amount = amount;\n\t\t}\n\n\t\tpublic void add(Amount that) throws Exception {\n\t\t\tif(!this.currency.equals(that.currency)) {\n\t\t\t\tthrow new Exception(\"Currencies Don't Match : \" + this.currency + \" \u0026  that.currency);\n\t\t\t}\n\t\t\t\tthis.amount += that.amount;\n\t\t}\n\n\t\tpublic String toString() {\n\t\t\treturn amount + \" \" + currency;\n\t\t}\n\t}\n\n\tpublic class ThrowingExceptionRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tAmount amount1 = new Amount(\"USD\", 10);\n\t\t\t//Amount amount2 = new Amount(\"USD\", 20);\n\t\t\tAmount amount2 = new Amount(\"EUR\", 20);\n\t\ttry {\n\t\t\t\tamount1.add(amount2);\n\t\t\t\tSystem.out.println(amount1);\n\t\t\t} catch(Exception e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n**_java.lang.RuntimeException:Currencies Don't Match : USD \u0026 EUR_**\n\n_Exception in thread \"main\" java.lang.RuntimeException:Currencies Don't Match_\n\n_at com.in28minutes.exceptionhandling.ThrowingExceptionRunner.main (ThrowingExceptionRunner.java:26)_\n\n```Exception``` is not a ```RuntimeException``` or one of its sub-classes, it is a checked exception. So, it needs to be declared when it is thrown - `public void add(Amount that) throws Exception`. \n\n#### Summary\n\nIn this step, we:\n\n* Learned that it is possible to throw an exception from code inside any method we write\n* When a method throws checked exception, it should declare it.\n\n### Step 10: Throwing A Custom Exception\nIt is also possible for you to throw a custom exception. You can do this by defining your own exception ```class```, only that it must inherit from one of the built-in exception classes. Note that:\n\n* If you sub-class a checked exception, your exception also becomes checked.\n* If you sub-class an unchecked exception, your exception would be unchecked. \n\n##### Snippet-01 : Throw a custom exception\n\n**_ThrowingExceptionRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.exceptionhandling;\n\n\tclass CurrenciesDoNotMatchException extends Exception {\n\t\tpublic CurrenciesDoNotMatchException(String msg) {\n\t\t\tsuper(msg);\n\t\t}\n\t}\n\n\tclass Amounts {\n\t\tprivate String currency;\n\t\tprivate int amount;\n\n\t\tpublic Amounts(String currency, int amount) {\n\t\t\tsuper();\n\t\t\tthis.currency = currency;\n\t\t\tthis.amount = amount;\n\t\t}\n\n\t\tpublic void add(Amount that) throws Exception {\n\t\t\tif(!this.currency.equals(that.currency)) {\n\t\t\t\tthrow new CurrenciesDoNotMatchException(\"Currencies Don't Match : \" + this.currency + \" \u0026 \" + that.currency);\n\t\t\t}\n\t\t\tthis.amount += that.amount;\n\t\t}\n\n\t\tpublic String toString() {\n\t\t\treturn amount + \" \" + currency;\n\t\t}\n\t}\n\n\tpublic class ThrowingExceptionRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tAmount amount1 = new Amount(\"USD\", 10);\n\t\t\t//Amount amount2 = new Amount(\"USD\", 20);\n\t\t\tAmount amount2 = new Amount(\"EUR\", 20);\n\t\t\ttry {\n\t\t\t\tamount1.add(amount2);\n\t\t\t\tSystem.out.println(amount1);\n\t\t\t} catch(Exception e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n**_com.in28minutes.exceptionhandling.CurrenciesDoNotMatchException : Currencies Don't Match : USD \u0026 EUR_**\n\n_Exception in thread \"main\" com.in28minutes.exceptionhandling.CurrenciesDoNotMatchException : Currencies Don't Match : USD \u0026 EUR_\n\n_at com.in28minutes.exceptionhandling.ThrowingExceptionRunner.main (ThrowingExceptionRunner.java:26)_\n\n##### Snippet-01 Explained\n\nThe class ```CurrenciesDoNotMatchException``` clearly is a checked exception. Hence, rules that apply for throwing and handling checked applications, apply to it as well.\n\nIf instead, ```CurrenciesDoNotMatchException``` were to sub-class ```RuntimeException```, it would be an unchecked exception. Adding the ```throws``` specification to the ```add()``` definition would not be needed. Also, no method in the call sequence of ```add()``` is required to handle it.\n\n#### Summary\n\nIn this step, we:\n\n* Discovered that Java allows you to define your own custom exception classes\n* Whether a custom exception is checked or unchecked, depends on which exception it sub-classes.\n* Saw an example of how to raise and handle a custom exception\n\n### Step 11: Introducing ```try```-With-Resources \n\n```try```-with-resources makes managing resource in a ```try```-```catch```-```finally``` block. Let's look at an example.\n\n##### Snippet-01: try-with-resources\n\n```java\n\n\tpackage com.in28minutes.exceptionhandling;\n\timport java.util.Scanner;\n\n\tpublic class TryWithResourcesRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\ttry (Scanner scanner = new Scanner(System.in)) {\n\t\t\t\t// ... Program logic, probably using scanner input\n\t\t\t\tint[] numbers = {1, 2, 3, 4};\n\t\t\t\tint num = numbers[5];\n\t\t\t}\n\t\t\t//scanner.close();\n\t\t}\n\t}\n\n```\n\n##### Snippet-01 Explained\n\nThe ```try```-with-resources version was introduced in Java SE 7. It encloses the resource to be managed within parentheses, along with the ```try``` keyword. \n\nIn this case, ```Scanner``` is compatible with such resource management, because it's defined to implement the ```Closeable``` ```interface```. This interface in turn, is a sub-class of the ```abstract class``` ```AutoCloseable```.\n\n```Closeable extends AutoCloseable{};```\n\n```Scanner implements Closeable{};```\n \n\nFor ```try```-with-resources, a ```catch``` and/or a ```finally``` clause are not mandatory.\n\nAlso, the call to ```scanner.close``` is no longer required.\n\n#### Summary\n\nIn this step, we:\n\n* Discovered a veriant of the ```try```-```catch```-```finally``` block, called ```try```-with-resources\n* Saw that it can be used to manage resource cleanly, provided the resource implements the ```AutoCloseable``` ```interface```.\n\n### Step 12: Programming Puzzle Set PP_02 \n\n#### Puzzle-01\n\n* Does the following program handle the exception thrown?\n\n```java\n\n\ttry {\t\n\t\t\tAmountAdder.addAmounts(new Amount(\"RUPEE\", 5), new Amount(\"RUPEE\", 5);\n\t\t\tString str = null;\n\t\t\tstr.toString();\n\t\t} catch(CurrenciesDoNotMatchException ex) {\n\t\t\tex.printStackTrace();\n\t\t}\n\n```\n\n* **_Answer : No_**\n\n#### Puzzle-01 Explained\n\nThe exception thrown is a ```NullPointerException```, whereas the one we are trying to catch is a ```CurrenciesDoNotMatchException```. \n\n\n#### Puzzle-02\n\n* Does the following code compile?\n\n```java\n\n\ttry {\n\t\t\tAmountAdder.addAmounts(new Amount(\"RUPEE\", 5), new Amount(\"RUPEE\", 5);\n\t\t\tString str = null;\n\t\t\tstr.toString();\n\t\t} catch(Exception e) {\n\t\t\te.printStackTrace();\n\t\t} catch(CurrenciesDoNotMatchException ex) {\n\t\t\tex.printStackTrace();\t\t\n\t\t}\n\n```\n\n**_Answer : No_**\n\n#### Puzzle-02 explained\n\nThe order of ```catch``` clauses for exceptions needs to be from less specific to more specific.  ```CurrenciesDoNotMatchException``` is a sub-class of ```Exception```. Hence, error.\n\n#### Puzzle-03\n\n* Does the following code compile?\n\n```java\n\n\ttry {\n\n\t} catch (IOException | SQLException ex) {\n\t\tex.printStackTrace();\n\t}\n\n```\n\n* **_Answer : Yes_**\n\n#### Puzzle-03 Explained\n\nThis feature was added in Java SE 7.\n\n## File Operations\n\nWe would be aware that any computer has a hard disk, on which information is stored. This information is stored in units called **files**. For ease of access, file are grouped together and organized into **directories**. The operating system has a sub-system called the **file-system**, which  has the responsibility of interfacing system and user programs, with files and directories on disk. \n\nThe Java Runtime System also communicates with the native file-system, and makes use of its services to provide a file programming interface to Java programmers. \n\nIn this section, we will explore a few basic ways in which programmers can interact with the native file-system, through the platform independent Java file API. \n\n#### Listing Directory Contents\n\nWhen we develop a Java software project in the Eclipse IDE environment, the root folder of the project has several interesting file and sub-folders contained within it. From now on, we use the terms \"folder\" and \"directory\" interchangeably, as they have equivalent meanings. \n\nLet's write a simple Java program to list the contents of one such project folder. \n\n##### Snippet-1 : Listing Directory Contents\n\nThe ```java.nio.file``` system package has a bunch of utility ```class```es and ```interface```s to help us navigate the native file system.\n\n**_DirectoryScanRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.files;\n\timport java.nio.file.Files;\n\timport java.nio.file.Paths;\n\timport java.io.IOException;\n\n\tpublic class DirectoryScanRunner {\n\t\tpublic static void main(String[] args) throws IOException {\n\t\t\tFiles.list((Paths.get(\".\")).forEach(System.out::println);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_./.classpath_\n\n_./.project_\n\n_./.DS_Store_\n\n_./bin_\n\n_./resources_\n\n_./src_\n\n##### Snippet-1 Explained\n\n\nA ```Path``` ```class``` is the entity used to denote a **pathname** in Java NIO Library. NIO stands for \"New I/O\", which was introduced in Java SE, replacing the earlier, very awkward File I/O Library. It is no longer new though, but that's another issue! \n\n\"```.```\" denotes the current directory in the file-system. \n\nThe ```Paths.get()``` method returns the path-name of the specified directory in a format that the ```Files.get()``` method understands.\n\nThe ```Files.get()``` method does a **lazy traversal** of the directory it is provided with, in the sense that:\n* It lists regular files it encounters.\n* When faced with directory files, it merely lists them, without recursively traversing them.\n\nThe contents of the root directory are listed as path-names, with each path-name being relative to the root directory.\n   \n##### Snippet-2 : Recursive Directory Traversal\n\nWe can specify level 2 in `Files.walk(currentDirectory, 2)`. So, folders until level 2 are scanned.\n\n\n**_DirectoryScanRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.files;\n\timport java.nio.file.Files;\n\timport java.nio.file.Path;\n\timport java.nio.file.Paths;\n\timport java.io.IOException;\n\n\tpublic class DirectoryScanRunner {\n\t\tpublic static void main(String[] args) throws IOException {\n\t\t\tPath currentDirectory = Paths.get(\".\");\n\t\t\t//Files.list(currentDirectory).forEach(System.out::println);\n\t\t\tFiles.walk(currentDirectory, 2).forEach(System.out::println);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_./.classpath_\n\n_./.project_\n\n_./.DS_Store_\n\n_./bin_\n\n_./bin/files_\n\n_./resources_\n\n_./src_\n\n_./src/files_\n\n\n##### Snippet-3 : Level-4 Traversal\n\n**_DirectoryScanRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.files;\n\timport java.nio.file.Files;\t\n\timport java.nio.file.Path;\n\timport java.nio.file.Paths;\n\timport java.io.IOException;\n\n\tpublic class DirectoryScanRunner {\n\t\tpublic static void main(String[] args) throws IOException {\n\t\t\tPath currentDirectory = Paths.get(\".\");\n\t\t\tFiles.walk(currentDirectory, 4).forEach(System.out::println);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_./.classpath_\n\n_./.project_\n\n_./.DS_Store_\n\n_./bin_\n\n_./bin/files_\n\n_./bin/files/DirectoryScanRunner.class_\n\n_./resources_\n\n_./src_\n\n_./src/files_\n\n_./src/files/DirectoryScanRunner.java_\n\n##### Snippet-4 : Only list .java files during traversal\n\nWe use a predicate `Files.walk(currentDirectory, 4).filter(predicate)` to filter only Java files.\n\n**_DirectoryScanRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.files;\n\timport java.nio.file.Files;\n\timport java.nio.file.Path;\n\timport java.nio.file.Paths;\n\timport java.util.function.Predicate;\n\timport java.io.IOException;\n\n\tpublic class DirectoryScanRunner {\n\t\tpublic static void main(String[] args) throws IOException {\n\t\t\tPath currentDirectory = Paths.get(\".\");\n\t\t\tPredicate\u003c? super Path\u003e predicate = path -\u003e String.valueOf(Path).contains(\".java\");\n\n\t\t\t//Files.walk(currentDirectory, 4).forEach(System.out::println);\n\t\t\tFiles.walk(currentDirectory, 4).filter(predicate)\n\t\t\t\t\t\t\t\t\t\t   .forEach(System.out::println);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_./src/files/DirectoryScanRunner.java_\n\n\n\n##### Snippet-5 : Filtered Traversal with find()\n\nWe can use a matcher - `Files.find(currentDirectory, 4, matcher)` which is configured to check the path attribute for .java extension - `(path, attributes) -\u003e String.valueOf(path).contains(\".java\")`\n\n**_DirectoryScanRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.files;\n\timport java.nio.file.Files;\n\timport java.nio.file.Path;\n\timport java.nio.file.Paths;\n\timport java.util.function.Predicate;\n\timport java.nio.file.attribute.BasicFileAttributes;\n\timport java.util.function.BiPredicate;\n\timport java.io.IOException;\n\n\tpublic class DirectoryScanRunner {\n\t\tpublic static void main(String[] args) throws IOException {\n\t\t\tPath currentDirectory = Paths.get(\".\");\n\t\t\t//Predicate\u003c? super Path\u003e predicate = path -\u003e String.valueOf(path).contains(\".java\");\n\t\t\t//Files.walk(currentDirectory, 4).filter(predicate).forEach(System.out::println);\n\t\t\tBiPredicate\u003cPath, BasicFileAttributes\u003e matcher = \n\t\t\t(path, attributes) -\u003e String.valueOf(path).contains(\".java\");\n\t\t\tFiles.find(currentDirectory, 4, matcher);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_./src/files/DirectoryScanRunner.java_\n\n\n\n##### Snippet-6 : Filtering directories\n\n**_DirectoryScanRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.files;\n\timport java.nio.file.Files;\n\timport java.nio.file.Path;\n\timport java.nio.file.Paths;\n\timport java.util.function.Predicate;\n\timport java.nio.file.attribute.BasicFileAttributes;\n\timport java.util.function.BiPredicate;\n\timport java.io.IOException;\n\n\tpublic class DirectoryScanRunner {\n\t\tpublic static void main(String[] args) throws IOException {\n\t\t\tPath currentDirectory = Paths.get(\".\");\n\t\t\t//BiPredicate\u003cPath, BasicFileAttributes\u003e matcher = \n\t\t\t//(path, attributes) -\u003e String.valueOf(path).contains(\".java\");\n\t\t\t\n\t\t\tBiPredicate\u003cPath, BasicFileAttributes\u003e directoryMatcher = \n\t\t\t(path, attributes) -\u003e attributes.isDirectory();\n\t\t\tFiles.find(currentDirectory, 4, directoryMatcher);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_./bin_\n\n_./bin/files_\n\n_./resources/_\n\n_./src/_\n\n_./src/files_\n\n\nWe are making use of a matcher checking `attributes.isDirectory()`.\n\n##### Snippet-7 : Reading a File\n\n**_./resources/data.txt_**\n\n```123.122```\n\n```asdfghjkl```\n\n```Apple```\n\n```Bat```\n\n```Cat```\n\n**_FileReadRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.files;\n\timport java.nio.file.Files;\n\timport java.nio.file.Paths;\n\timport java.io.IOException;\n\n\tpublic class FileReadRunner {\n\t\tpublic static void main(String[] args) throws IOException {\n\t\t\tPath pathFileToRead = Paths.get(\"./resources/data.txt\");\n\t\t\tList\u003cString\u003e lines = Files.readAllLines(pathFileToRead);\n\t\t\tSystem.out.println(lines);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_[123.122, asdfghjkl, Apple, Bat, Cat]_\n\n`Files.readAllLines(pathFileToRead)` makes it easy to read content of a file to list of String values.\n\n##### Snippet-8 : Streamed File Read\n\n`Files.readAllLines(pathFileToRead)` makes it easy to read content of a file. However, streaming is a better options when reading large files or when less memory is available.\n\n**_./resources/data.txt_**\n\n```123.122```\n\n```asdfghjkl```\n\n```Apple```\n\n```Bat```\n\n```Cat```\n\n**_FileReadRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.files;\n\timport java.nio.file.Files;\n\timport java.nio.file.Paths;\n\timport java.io.IOException;\n\n\tpublic class FileReadRunner {\n\t\tpublic static void main(String[] args) throws IOException {\n\t\t\tPath pathFileToRead = Paths.get(\"./resources/data.txt\");\n\t\t\t//List\u003cString\u003e lines = Files.readAllLines(pathFileToRead);\n\t\t\t//System.out.println(lines);\n\t\t\tFiles.lines(pathFileToRead).forEach(System.out::println);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_123.122_\n\n_asdfghjkl_\n\n_Apple_\n\n_Bat_\n\n_Cat_\n\n`Files.lines(pathFileToRead)` returns a stream which can be consumed as needed.\n\n##### Snippet-9 : Printing file contents in lower-case\n\nWe can use `map` function to map to `String::toLowerCase`\n\n**_./resources/data.txt_**\n\n```\n123.122\n\nasdfghjkl\n\nApple\n\nBat\n\nCat\n```\n\n**_FileReadRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.files;\n\timport java.nio.file.Files;\n\timport java.nio.file.Paths;\n\timport java.io.IOException;\n\n\tpublic class FileReadRunner {\n\t\tpublic static void main(String[] args) throws IOException {\n\t\t\tPath pathFileToRead = Paths.get(\"./resources/data.txt\");\n\t\t\t//Files.lines(pathFileToRead).forEach(System.out::println);\n\t\t\tFiles.lines(pathFileToRead)\n\t\t\t\t .map(String::toLowerCase)\n\t\t\t\t .forEach(System.out::println);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_123.122_\n\n_asdfghjkl_\n\n_apple_\n\n_bat_\n\n_cat_\n\n\n##### Snippet-9 : Filtering file contents\n\nYou can also filter file content using the `filter` method.\n\n**_FileReadRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.files;\n\timport java.nio.file.Files;\n\timport java.nio.file.Paths;\n\timport java.io.IOException;\n\n\tpublic class FileReadRunner {\n\t\tpublic static void main(String[] args) throws IOException {\n\t\t\tPath pathFileToRead = Paths.get(\"./resources/data.txt\");\n\t\t\t//Files.lines(pathFileToRead).forEach(System.out::println);\n\t\t\t//Files.lines(pathFileToRead).map(String::toLowerCase).forEach(System.out::println);\n\t\t\tFiles.lines(pathFileToRead)\n\t\t\t\t .map(String::toLowerCase)\n\t\t\t\t .filter(str -\u003e str.contains(\"a\"))\n\t\t\t\t .forEach(System.out::println);\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_asdfghjkl_\n\n_apple_\n\n_bat_\n\n_cat_\n\n\n##### Snippet-10 : Writing to a file\n\n`Files.write` can be used to write to a file.\n\n**_FileWriteScanner.java_**\n\n```java\n\n\tpackage com.in28minutes.files;\n\timport java.nio.file.Files;\n\timport java.nio.file.Paths;\n\timport java.io.IOException;\n\n\tpublic class FileWriteRunner {\n\t\tpublic static void main(String[] args) throws IOException {\n\t\t\tPath pathFileToWrite = Paths.get(\"./resources/file-write.txt\");\n\t\t\tList\u003cString\u003e list = List.of(\"Apple\", \"Boy\", \"Cat\", \"Dog\", \"Elephant\");\n\t\t\tFiles.write(pathFileToWrite, list);\n\t\t}\t\n\t}\n\n```\n\n**_./resources/file-write.txt_**\n\n```\nApple\n\nBoy\n\nCat\n\nDog\n\nElephant\n```\n\n## Concurrency : Advanced Topics\n\nLet's create a simple counter.\n\n##### Snippet-1: Atomic Operations : Counter\n\n**_Counter.java_**\n\n```java\n\n\tpackage com.in28minutes.concurrency;\n\n\tpublic class Counter {\n\t\tprivate int i = 0;\n\n\t\tpublic void increment() {\n\t\t\ti++;\n\t\t}\n\n\t\tpublic int getI() {\n\t\t\treturn i;\n\t\t}\n\t}\n\n```\n\n**_ConcurrencyRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.concurrency;\n\n\tpublic class ConcurrencyRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tCounter counter = new Counter();\n\t\t\tcounter.increment();\n\t\t\tcounter.increment();\n\t\t\tcounter.increment();\t\t\t\n\t\t\tSystem.out.println(counter.get());\n\t\t}\n\t}\n\n```\n\n##### Snippet-1 Explained\n\nQuite straightforward!\n\n#### Counter ```increment()``` method is NOT Atomic!\n\nLet's look at the code. It seemingly involves just one operation.\n\n```java\n\n\tpublic void increment() {\n\t\ti++;\n\t}\n\n```\n\nThe operation ```i++``` actually involves the following steps:\n- Step 1. Read the value of ```i``` from memory into the CPU registers\n- Step 2. Increment the value in the CPU registers\n- Step 3. Store the incremented value back into the memory location of ```i```\n\n```i++``` is not an atomic operation. \n\n##### What if `increment` is not atomic?\n\nLet's take an example of two Threads, ```T1``` and ```T2``` running in ```ConcurrencyRunner``` access a single ```Counter``` object instance. \n\nLet's say the threads concurrently invoke the `increment` and `getI`.\n\nAssume the initial value of ```i``` is ```15```. Let's take a closer look at a possible scenario:\n-  ```T1``` calls ```increment()``` first, and successfully completes Step 1 of ```i++```. Gets a value of 15.\n-  The scheduler switches threads to ```T2```.\n-  ```T2``` calls ```increment()``` first, and successfully completes Step 1 of ```i++```.Gets a value of 15.\n- The scheduler switches to ```T1```.  ```T1``` resumes execution of ```increment()```, and completes steps 2 and 3 of ```i++```. Completes execution of ```increment()```. Value of ```i``` is over-written with ```16```.\n- The scheduler switches to ```T2```. In it's CPU register context, i is ```15```, not ```16```. ```T2``` resumes execution of ```increment()```, and completes steps 2 and 3 of ```i++```. Completes execution of ```increment()```.Value of ```i``` in the ```Counter``` instance is over-written with ```16```.\n\nIdeally, the final value of ```i``` after two ```increment```s should have been ```17```. This would result when the operations run serially one after the other.\n\nThis scenario, where the result of a concurrent computation (involving a sequence of operations) depends on the relative order of execution of those operations by the threads involved, is called a **race condition**.\n\nThere is a popular English saying: \"There is many a slip, between the cup and the lip\". This refers to the fact that anything can happen between the time when we hold a cup of tea in our hands, and the time when we actually get to take a sip of the tea.\n\nThis definitely rings true here. \n\nThe increment operation is not actually not as smooth as it seems. because it is not atomic, slip-ups can and will often occur. This brings us to the concept of **Thread-Safety**. \n\nA method is said to be thread-safe, if it can be run in a concurrent environment (involving several concurrent invocations by independent threads) without *race-conditions*. \n\n#### Revisited : The ```synchronized``` Keyword\nAdding the keyword ```synchronized``` to the signature of a ```class``` method makes it thread safe.\n\n##### Snippet-2\n\n**_Counter.java_**\n\n```java\n\n\tpackage com.in28minutes.concurrency;\n\n\tpublic class Counter {\n\t\tprivate int i = 0;\n\n\t\tsynchronized public void increment() {\n\t\t\ti++;\n\t\t}\n\n\t\tpublic int getI() {\n\t\t\treturn i;\n\t\t}\n\t}\n\n```\n\n##### Snippet-2 Explained\n\nAfter adding `synchronized` keyword to the method `increment`, only one thread will be able to execute the method, at a time. Hence, race condition is avoided.\n\n##### Snippet-3 : less concurrency\n\n`synchronized` keyword make the code thread safe. However, it causes all other threads to wait. This can result in performance issues. Let's look at an example:\n\n**_BiCounter.java_**\n\n```java\n\n\tpackage com.in28minutes.concurrency;\n\n\tpublic class BiCounter {\n\t\tprivate int i = 0;\n\t\tprivate int j = 0;\n\n\t\tsynchronized public void incrementI() {\n\t\t\ti++;\n\t\t}\n\n\t\tsynchronized public void incrementJ() {\n\t\t\tj++;\n\t\t}\n\n\t\tpublic int getI() {\n\t\t\treturn i;\n\t\t}\n\n\t\tpublic int getJ() {\n\t\t\treturn j;\n\t\t}\n\t}\n\n```\n\n**_ConcurrencyRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.concurrency;\n\n\tpublic class ConcurrencyRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tBiCounter counter = new BiCounter();\n\t\t\tcounter.incrementI();\n\t\t\tcounter.incrementJ();\n\t\t\tcounter.incrementI();\n\t\t\tSystem.out.println(counter.get());\n\t\t}\n\t}\n\n```\n\n##### Snippet-3 Explained\n\nBoth ```incrementI()``` and ```incrementJ()``` of ```class``` ```BiCounter``` are ```synchronized```. Therefore, at any given time, at most one thread can execute either of these methods! Which means that, while a thread  ```T1``` is executing ```counter.incrementI()``` within ```ConcurrencyRunner.main()```, another thread ```T2``` **is not allowed to execute** ```counter.incrementJ()```!\n\nJust imagine, if there are a total of ```12``` threads wanting to increment ```counter```. When one thread is running, the other ```11``` have to wait! \n\n#### Synchronization With Locks\n\nLet's look at another synchronization option - `Locks`\n\n\n##### Snippet-4: BiCounter With Locks\n\n**_BiCounterWithLocks.java_**\n\n```java\n\n\tpackage com.in28minutes.concurrency;\n\timport java.util.concurrent.locks.ReentrantLock;\n\n\tpublic class BiCounterWithLocks {\n\t\tprivate int i = 0;\n\t\tprivate int j = 0;\n\t\tprivate Lock LockForI = new ReentrantLock();\n\t\tprivate Lock LockForJ = new ReentrantLock();\n\n\t\tpublic void incrementI() {\n\t\t\tlockForI.lock();\n\t\t\ti++;\n\t\t\tlockForI.unlock();\n\t\t}\n\n\t\tpublic void incrementJ() {\n\t\t\tlockForJ.lock();\n\t\t\tj++;\n\t\t\tlockForJ.unlock();\n\t\t}\n\n\t\tpublic int getI() {\n\t\t\treturn i;\n\t\t}\n\n\t\tpublic int getJ() {\n\t\t\treturn j;\n\t\t}\n\t}\n\n```\n\n##### Snippet-4 Explained\n\n`i++` and `j++` are the pieces of code to protect. We use two locks lockForI and lockForJ. If a thread wants to execute `i++`, it needs to first get a lock to it - implemented using `lockForI.lock()`. Once it performs the operation, it can release the lock `lockForI.unlock()`. \n\nThe ```Lock```s ```lockForI``` and ```lockForJ``` are totally independent of each other. Therefore, a thread ```T2``` can execute ```j++``` within ```incrementJ()```, at the same time that thread ```T1``` is executing ```i++``` within ```incrementI()```.\n  \n#### Atomic Classes\n\nThe operation ```i++```, small though it might seem, gave us quite a bit headache! \n\nIf a seemingly minute operation might need so much worrying about, imagine writing concurrent data structures that manipulate linked lists with multiple link operations! \n\nIt would be really nice if someone could take care of these tiny operations for us, otherwise we would have  hard time finding out what code to definitely lock, and what code need not be!\n\nJava addresses this issue for basic data types, by providing a few classes that are inherently thread-safe. A good example is ```AtomicInteger```, which is a wrapper around the ```int``` primitive type.\n\n##### Snippet-5 : AtomicInteger\n\n**_BiCounterWithAtomicInteger.java_**\n\n```java\n\n\tpackage com.in28minutes.concurrency;\n\timport java.util.concurrent.atomic.AtomicInteger;\n\n\tpublic class BiCounterWithAtomicInteger {\n\t\tprivate AtomicInteger i = new AtomicInteger();\n\t\tprivate int AtomicInteger = new AtomicInteger();\n\n\t\tpublic void incrementI() {\n\t\t\ti.incrementAndGet();\n\t\t}\n\n\t\tpublic void incrementJ() {\n\t\t\tj.incrementAndGet();\n\t\t}\n\n\t\tpublic int getI() {\n\t\t\treturn i.get();\n\t\t}\n\n\t\tpublic int getJ() {\n\t\t\treturn j.get();\n\t\t}\n\t}\n\n```\n\n##### Snippet-5 Explained\n\n`incrementAndGet` is atomic. So, `BiCounterWithAtomicInteger` does not need to worry about synchronization.\n\n#### Concurrent Collections\n\nJava gave us a ready-made solution for thread-safe primitive data, with wrappers such as ```AtomicInteger```. The reasons this approach worked for ```int``` were:\n\n* Simple, small-sized underlying type\n* Wide-spread potential usage\n\nHow about collections? \n\nJava provides classes like `Vector` (synchronized version of `ArrayList`) which can provide thread safety. But, these inherit the problems with using synchronized. \n\nWhat are other options?\n\n##### Snippet-6 : Need For ConcurrentMap\n\nThe code within the ```for``` loop does a `get` and then a `put`. It is not thread safe.\n\n**_MapRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.collections;\n\timport java.util.HashMap;\n\n\tpublic class MapRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tString str = \"Hello World\";\n\t\t\tMap\u003cCharacter, Integer\u003e occurrences = new HashMap\u003c\u003e();\n\t\t\tchar[] characters = str.toCharArray();\n\t\t\tfor(char character:characters) {\n\t\t\t\tInteger count = occurrences.get(character);\n\t\t\t\tif(count == null) {\n\t\t\t\t\toccurrences.put(character, 1);\n\t\t\t\t} else {\n\t\t\t\t\toccurrences.put(character, count + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n```\n\nConcurrent Collections provide atomic versions of operations such as those encountered above:\n* If entry does not exist, then create and initialize\n* If entry exists, then update\n\n#### The ```ConcurrentMap``` ```interface```\n\nThe ```interface``` ```ConcurrentMap``` has methods to implement compound operations. Such operations include:\n\n```\nV putIfAbsent(K key, V value);\n\nV computeIfPresent(K key,\n            BiFunction\u003c? super K, ? super V, ? extends V\u003e remappingFunction)\n```\n\n##### Snippet-7 : ConcurrentHashMap Logic - Stage 1\n\n```LongAdder``` provides an atomic `increment` method, which we are making use of to make the code a little more thread safe. However, different threads could be executing ```occurrences.get()``` and ```occurrences.put()``` in parallel. A race condition can still occur.\n\n\n**_ConcurrentMapRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.concurrency;\n\timport java.util.Map;\n\timport java.util.HashTable;\n\timport java.util.concurrent.atomic.LongAdder;\n\n\tpublic class ConcurrentMapRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\t    String str = \"ABCD ABCD ABCD\";\n\t\t\t    for(char character:str.toCharArray()) {\n\t\t\t      LongAdder longAdder = occurances.get(character);\n\t\t\t      if(longAdder == null) {\n\t\t\t        longAdder = new LongAdder();\n\t\t\t      }\n\t\t\t      longAdder.increment();\n\t\t\t      occurances.put(character, longAdder);\n\t\t\t    }\n\t\t}\n\t}\n\n```\n\n**_Console Output_**\n\n_[ =2, A=3, B=3, C=3, D=2]_\n\n\n##### Snippet-8 : ConcurrentHashMap Logic - Stage 2\n\nWe can use the method ```computeIfAbsent()``` from the ```collection``` ```ConcurrentHashMap``` to reduce the code to a single, atomic operation.\n\n\n**_ConcurrentMapRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.concurrency;\n\timport java.util.concurrent.ConcurrentMap;\n\timport java.util.concurrent.ConcurrentHashMap;\n\timport java.util.concurrent.atomic.LongAdder;\n\n\tpublic class ConcurrentMapRunner {\n\t\tpublic static void main(String[] args) {\n\t\t    ConcurrentMap\u003cCharacter, LongAdder\u003e occurances = new ConcurrentHashMap\u003c\u003e();\n\t\t    \n\t\t    String str = \"ABCD ABCD ABCD\";\n\n\t\t    for(char character:str.toCharArray()) {\n\t\t      occurances.computeIfAbsent(character, ch -\u003e new LongAdder()).increment();\n\t\t    }\n\t\t    \n\t\t    System.out.println(occurances);\n\t  }\n\t}\n\n```\n\n**_Console Output_**\n\n_[ =2, A=3, B=3, C=3, D=2]_\n\n\n#### ```ConcurrentHashMap```\n\nIn ```HashTable```, all methods are synchronized. \n\nIn ```ConcurrentHashMap```, data structure is organized into disjoint regions. Access methods use different ```Locks``` for different regions, reducing performance impact during concurrent access. \n\n#### Concurrent Collections : Copy-On-Write Optimization\n\nAll values in Copy-On-Write collections are stored in an internal immutable (not-changeable) array. A new array is created if there is any modification to the collection.\n\nRead operations are not synchronized. Only write operations are synchronized.\n\nCopy on Write approach is used in scenarios where reads greatly out number write’s on a collection. \n\n`CopyOnWriteArrayList` \u0026 `CopyOnWriteArraySet` are implementations of this approach. \n\nCopy on Write collections are typically used in Subject – Observer scenarios, where the observers very rarely change. Most frequent operations would be iterating around the observers and notifying them.\n\n##### Snippet-9 : CopyOnWriteArrayList\n\n**_CopyOnWriteArrayListRunner.java_**\n\n```java\n\n\tpackage com.in28minutes.concurrency;\n\timport java.util.List;\n\timport java.util.concurrent.CopyOnWriteArrayList;\n\n\tpublic class CopyOnWriteArrayListRunner {\n\t\tpublic static void main(String[] args) {\n\t\t\tList\u003cString\u003e list = new CopyOnWriteArrayList\u003c\u003e();\n\t\t\t// Total of 3 threads doing add()'s, maybe in a separate method\n\t\t\tlist.add(\"Ant\");\n\t\t\tlist.add(\"Bat\");\n\t\t\tlist.add(\"Cat\");\n\n\t\t\t//Total of 10000 threads looping on get(), again, in a separate method\n\t\t\tfor(String element:list) {\n\t\t\t\tSystem.out.println(element);\n\t\t\t}\n\t\t}\n\t}\n\n```\n\n##### Snippet-9 Explained\n\n```CopyOnWriteArrayList.add()``` method is a ```synchronized``` method. And the copy-on-write algorithm ensures that the copying is performed in a thread-safe manner, after which the write is done on a separate copy, while the ```get()```'s continue on the original array. Once the ```add()``` is done, the collection starts using the new array, and discards the old one. This strategy continues for the lifetime of the program.\n\nThe ```CopyOnWriteArrayList.get``` method is NOT ```synchronized```, since on the array that the reads work, there will be no direct write through an ```add()```.\n\nCopy-On-Write collections should only be used for the specific usage scenarios, viz., very large number of data structure traversals (data element reads only), compared to mutations (data element insertions/deletions/modifications). In this way, high concurrency is achieved for traversals.\n","funding_links":[],"categories":["Programming languages"],"sub_categories":["Java"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fin28minutes%2Fjava-tutorial-for-beginners","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fin28minutes%2Fjava-tutorial-for-beginners","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fin28minutes%2Fjava-tutorial-for-beginners/lists"}