{"id":16105458,"url":"https://github.com/lironmiz/computer-science-in-java","last_synced_at":"2025-10-31T09:31:39.005Z","repository":{"id":63366771,"uuid":"561292347","full_name":"lironmiz/Computer-Science-in-Java","owner":"lironmiz","description":"Designed for saving assignments, submission exercises and projects ","archived":false,"fork":false,"pushed_at":"2024-08-17T11:16:20.000Z","size":17419,"stargazers_count":158,"open_issues_count":1,"forks_count":9,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-02-09T14:14:32.279Z","etag":null,"topics":["algrothm","arrays","bluej","computer-science","coursework","data","datastructures","degree","implementation-of-data-structures","java","linked-list","oop","oop-principles","openuniversity","queue","recursion","search-algorithm","sorting-algorithms","stack","trees"],"latest_commit_sha":null,"homepage":"https://www.openu.ac.il/courses/20441.htm","language":"Java","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/lironmiz.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}},"created_at":"2022-11-03T11:32:26.000Z","updated_at":"2025-01-08T12:46:51.000Z","dependencies_parsed_at":"2023-02-13T01:31:26.207Z","dependency_job_id":null,"html_url":"https://github.com/lironmiz/Computer-Science-in-Java","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/lironmiz%2FComputer-Science-in-Java","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lironmiz%2FComputer-Science-in-Java/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lironmiz%2FComputer-Science-in-Java/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lironmiz%2FComputer-Science-in-Java/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lironmiz","download_url":"https://codeload.github.com/lironmiz/Computer-Science-in-Java/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239171863,"owners_count":19594048,"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":["algrothm","arrays","bluej","computer-science","coursework","data","datastructures","degree","implementation-of-data-structures","java","linked-list","oop","oop-principles","openuniversity","queue","recursion","search-algorithm","sorting-algorithms","stack","trees"],"created_at":"2024-10-09T19:09:38.491Z","updated_at":"2025-10-31T09:31:37.668Z","avatar_url":"https://github.com/lironmiz.png","language":"Java","readme":"\u003ch1 align=\"center\"\u003e 💻 Computer-Science-in-Java 💻 \u003c/h1\u003e\n\n\u003cimg src=\"https://i.imgur.com/dBaSKWF.gif\" height=\"50\" width=\"100%\"\u003e\n\nIntended for saving solutions for tests , exercises and assignments as part of an introductory course to computer science in the Java language 😎 \n\n\u003cp align=\"center\"\u003e\n\n  \u003cimg alt=\"GitHub top language\" src=\"https://img.shields.io/github/languages/top/lironmiz/Computer-Science-in-Java?color=04D361\u0026labelColor=000000\"\u003e\n  \n \u003cimg alt=\"Repository size\" src=\"https://img.shields.io/github/repo-size/lironmiz/Computer-Science-in-Java?color=04D361\u0026labelColor=000000\"\u003e\n  \n  \u003ca href=\"https://github.com/lironmiz/Link-Tree/commits/master\"\u003e\n    \u003cimg alt=\"GitHub last commit\" src=\"https://img.shields.io/github/last-commit/lironmiz/Computer-Science-in-Java?color=04D361\u0026labelColor=000000\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n## Useful link\n * Link to [Mega ]( https://mega.nz/folder/0Sg0iD4B#0OPF1JJgFjtYoJuStlsCtA)\n * Lint to [Drive ] ( https://drive.google.com/drive/folders/15saERJfCxzcg_EJF3H0cMsJ9g-HHERY2)\n \n# :star2: Course Material \n\n+ Introduction And Basics Of The Language\n\n+ Object Oriented Programming\n\n+ Flow Control (conditional sentences and loops)\n\n+ Arrays\n\n+ Extending Object-Oriented-Programming - inheritance, static methods and variables, loading of methods, cases, polymorphism and interfaces\n\n+ Complications\n\n+ Search And Sort Algorithms\n\n+ Recursion\n\n+ Linked Lists\n\n+ Stacks And Queues\n \n+ Trees And Binary Trees\n \n+ Computational\n\n\u003c!--🎨CAPSULE / 🌐WEBSITES: https://github.com/kyechan99/capsule-render --\u003e\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://capsule-render.vercel.app/api?type=shark\u0026height=30\u0026section=header\u0026reversal=false\u0026color=0:b579da,100:79da7f\"\u003e\n\n\u003c!--🤖ASCIIART / 🌐WEBSITES: https://asciiart.website/ \u0026 https://github.com/github/markup/issues/1440#issuecomment-803889380 --\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \n```diff\n+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @+\n@@       o o                                           @@\n@@       | |                                           @@\n@@      _L_L_                                          @@\n@@   ❮\\/__-__\\/❯ Programming isn't about what you know @@\n@@   ❮(|~o.o~|)❯  It's about what you can figure out   @@\n@@   ❮/ \\`-'/ \\❯                                       @@\n@@     _/`U'\\_                                         @@\n@@    ( .   . )     .----------------------------.     @@\n@@   / /     \\ \\    | while( ! (succed=try() ) ) |     @@\n@@   \\ |  ,  | /    '----------------------------'     @@\n@@    \\|=====|/                                        @@\n@@     |_.^._|                                         @@\n@@     | |\"| |                                         @@\n@@     ( ) ( )   Testing leads to failure              @@\n@@     |_| |_|   and failure leads to understanding    @@\n@@ _.-' _j L_ '-._                                     @@\n@@(___.'     '.___)                                    @@\n+@ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @+\n```\n  \n\u003c/div\u003e\n  \n\u003c!--🎨CAPSULE / 🌐WEBSITES: https://github.com/kyechan99/capsule-render --\u003e\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://capsule-render.vercel.app/api?type=shark\u0026height=30\u0026section=header\u0026reversal=false\u0026color=0:b579da,100:79da7f\"\u003e\n\n\u003c!--🤖ASCIIART / 🌐WEBSITES: https://asciiart.website/ \u0026 https://github.com/github/markup/issues/1440#issuecomment-803889380 --\u003e\n\n\u003cimg src=\"https://i.imgur.com/dBaSKWF.gif\" height=\"20\" width=\"100%\"\u003e\n\n\u003ch1 align=\"center\"\u003e 🤩 Computer-Science-in-Java-Summary 🤩 \u003c/h1\u003e\n\n## 1. TABLE OF CONTENTS\n- [1. TABLE OF CONTENTS](#1-table-of-contents)\n- [2. PRIMITIVE VARIABLES TYPES](#2-primitive-variables-types)\n- [3. TAKING INPUT](#3-taking-input)\n- [4. ARITHMETIC](#4-arithmetic)\n- [5. CASTING](#5-casting)\n- [6. RELATIONAL AND LOGICAL EXPRESSIONS](#6-relational-and-logical-expressions)\n- [7. CONDITIONAL STATEMENTS](#7-conditional-statements)\n- [8. LOOPS](#8-loops)\n- [9. ARRAYS](#9-arrays)\n- [10. SORTING ALGORITHMS](#10-sorting-algorithms)\n- [11. SEARCHING ALGORITHMS](#11-searching-algorithms)\n- [12. MATH CLASS](#12-math-class)\n- [13. STRING CLASS](#13-string-class)\n- [14. STRING BUFFER CLASS](#14-string-buffer-class)\n- [15. METHODS](#15-methods)\n- [16. RANDOM NUMBERS](#16-random-numbers)\n- [17. RECURSION](#17-recursion)\n- [18. READ AND WRITE TO FILE](#18-read-and-write-to-file)\n- [19. LINKED LIST](#19-linked-list)\n- [20. STACKS](#20-stacks)\n- [21. TREE](#21-tree)\n- [22. ALIASING](#22-aliasing)\n- [23. STATIC KEYWORD](#23-static-keyword)\n- [24. JAVADOC](#24-javadoc) \n- [25. ACCESS MODIFIERS](#25-accesss-modifiers)\n- [26. \tOBJECT-ORIENTED-PROGRAMMING](#26-object-oriented-programming)\n- [27. ENUM](#27-enum)  \n- [28. CONSTANT](#28-constant)\n- [29. EXCEPTION HANDLING](#29-exception-handling)  \n- [30. OBJECT CLASS](#30-object-class)\n- [31. TIME COMPLEXITY](#31-time-complexity) \n- [32. SPCAE COMPLEXITY](#32-space-complexity) \n- [33. QUEUES](#33-queues) \n- [34. GENERICS](#34-generics)\n- [35. UNARY OPERATOR](#35-unary-operator) \n- [36. HASHMAP](#36-hashmap) \n- [37. HASHTABLE](#37-hashtable)\n- [38. HASHSET](#38-hashset)\n- [39. POSTFIX AND PREFIX](#39-postfix-and-prefix)\n- [40. TERNARY OPERATOR](#40-ternary-operator)\n- [41. ABSTRACT CLASS](#41-abstract-class)\n- [42. INTERFACE](#42-interface)\n- [43. ANONYMOUS INNER CLASS](#43-anonymous-inner-class)\n- [44. OPTIONAL](#44-optional)\n- [45. LAMBDA EXPRESSION](#45-lambda-expression)\n\n\u003cimg src=\"https://media.giphy.com/media/bpEH21sHkWQQ8/giphy.gif\"\u003e\n\n```java\n// headers\n//*******************************************************\n// Exam in July 2022B (91)\n// Semester 2022B\n// Solutions to the test\n// Author: liron mizrahi\n//*******************************************************\n\n//*******************************************************\n// IntList.java\n// the class reprsents IntList\n// Author: liron mizrahi\n//*******************************************************\n\n// API\n/**\n * method return true if the arr values shift by 1 \n * @param: intp[ arr1, int[] arr2\n * @return: boolean \n */\n```\n\n## 2. PRIMITIVE VARIABLES TYPES\nIn Java, variables are used to store and manipulate data. There are several types of variables, each with its own characteristics and uses. \n\n| Definition | Example | Size | Range |\n| --- | --- | --- | --- |\n| char | 'b', 'B', '9', '\u0026' | 1 byte | -2^7...2^7-1 (-128...127) |\n| int | -5, 9, 8214 | 4 bytes | -2^31...2^31-1 |\n| long | -3, 77, 8234 | 8 bytes | -2^63...2^63-1 |\n| short | -1, 3, 1456 | 2 bytes | -2^15...2^15-1 |\n| byte | -2, 8, 42 | 1 byte | -2^7...2^7-1 |\n| double | 5.22, -89, 1.65 | 8 bytes | -1.7*10^308 to 1.7*10^308 |\n| float | 44.22, -89, 8.6 | 4 bytes | -3.4*10^38 to 3.4*10^38 |\n| boolean | true / false | 1 byte | true / false |\n\n### 2.1 Example \n```java\n  public class ExamplesOfBasicVariablesTypes\n  {\n    public static void main(String[] args)\n    {\n\t\t  // define char\n      char c = 'k';\n      // define int \n      int num = 5;\n      // define long\n      long num1 = 765;\n      // define sort\n      sort num2 = 6;\n      // define byte\n      byte num3 = 32;\n      // define double\n      double num4 = 326;\n      // define float\n      float num5 = 89;\n      // define boolean\n      boolean bool = true;\n\t }// end of method main \n  }// end of class ExamplesOfBasicVariablesTypes\n```\n\u003cimg src=\"https://media.giphy.com/media/RkclJYmYQmCrOPQFZn/giphy.gif\"\u003e\n\n## 3. TAKING INPUT\n\n\u003cimg src=\"https://media.giphy.com/media/ZBEMh8FGeNANCeBaEd/giphy.gif\"\u003e\n\nin this table we use: \nScanner scan = new Scanner(System.in) \u003cbr\u003e\nIn Java, there are several ways to take input from a user. \n\n**Here the Scanner method**:\n\n(Remember to use the Scanner class you need to import it using import java.util.Scanner;\nIt should be used at the very beginning of your java file before any other code written.\nSo, you can use the methods in the table below after importing the class.)\n\n| Data Type | Format |\n| --- | --- |\n| int | in.nextInt() |\n| short | in.nextShort() |\n| long | in.nextLong() |\n| char | in.next().charAt(0) |\n| float | in.nextFloat() |\n| double | in.nextDouble() |\n| byte | in.nextByte() |\n| boolean | in.nextBoolean() |\n| String | in.next() |\n| A string across an entire line including spaces | in.nextLine() |\n\n### 3.1 Example \n```java\nimport java.util.Scanner;\n\npublic class InputExample \n{\n    public static void main(String[] args) \n    {\n        // make a Scanner object\n        Scanner scan = new Scanner(System.in);\n\n        // Prompt user to enter an integer\n        System.out.print(\"Enter an integer: \");\n        int num1 = scan.nextInt();\n\n        // Prompt user to enter a short\n        System.out.print(\"Enter a short: \");\n        short num2 = scan.nextShort();\n\n        // Prompt user to enter a long\n        System.out.print(\"Enter a long: \");\n        long num3 = scan.nextLong();\n\n        // Prompt user to enter a character\n        System.out.print(\"Enter a character: \");\n        char ch = scan.next().charAt(0);\n\n        // Prompt user to enter a float\n        System.out.print(\"Enter a float: \");\n        float num4 = scan.nextFloat();\n\n        // Prompt user to enter a double\n        System.out.print(\"Enter a double: \");\n        double num5 = scan.nextDouble();\n\n        // Prompt user to enter a byte\n        System.out.print(\"Enter a byte: \");\n        byte num6 = scan.nextByte();\n\n        // Prompt user to enter a boolean\n        System.out.print(\"Enter a boolean: \");\n        boolean bool = scan.nextBoolean();\n\n        System.out.println(\"You entered: \" + num1 + \", \" + num2 + \", \" + num3 + \", \" + ch + \", \" + num4 + \", \" + num5 + \", \" + num6 + \", \" + bool);\n    }// end of method main\n}// end of class InputExample\n```\n\n## 4. ARITHMETIC\nIn Java, arithmetic operations are used to perform mathematical calculations on variables.\n\n\u003cimg src=\"https://media.giphy.com/media/5UCpmbzvZKQCfuF2P2/giphy.gif\"\u003e\n\n| Operations | Symbol |\n| --- | --- |\n| Addition | + |\n| Subtraction | - |\n| Multiplication | * |\n| Division | / |\n| Modulus | % |\n\n### 4.1 Example \n\n```java\npublic class Arithmetic\n{\n    public static void main(String[] args)\n    {\n        int a = 5;\n        int b = 2;\n\n        // addition\n        int c = a + b;\n        System.out.println(\"Addition: \" + a + \" + \" + b + \" = \" + c);\n\n        // subtraction\n        c = a - b;\n        System.out.println(\"Subtraction: \" + a + \" - \" + b + \" = \" + c);\n\n        // multiplication\n        c = a * b;\n        System.out.println(\"Multiplication: \" + a + \" * \" + b + \" = \" + c);\n\n        // division\n        c = a / b;\n        System.out.println(\"Division: \" + a + \" / \" + b + \" = \" + c);\n\n        // modulus\n        c = a % b;\n        System.out.println(\"Modulus: \" + a + \" % \" + b + \" = \" + c);\n    }// end of method main\n    \n}// end of class Arithmetic\n```\n### 4.2 Shorthand Experssions \n\n| Shorthand Expressions | Symbol |\n| --- | --- |\n| Addition Assignment | += |\n| Subtraction Assignment | -= |\n| Multiplication Assignment | *= |\n| Division Assignment | /= |\n| Modulus Assignment | %= |\n\n### 4.3 Shorthand Experssions Example\n```java\npublic class ShorthandExpressions \n{\n    public static void main(String[] args) \n    {\n        int x = 10;\n        int y = 5;\n\n        // addition assignment\n        x += y;\n        System.out.println(\"Addition Assignment: x += y : \" + x);\n\n        // subtraction assignment\n        x -= y;\n        System.out.println(\"Subtraction Assignment: x -= y : \" + x);\n\n        // multiplication assignment\n        x *= y;\n        System.out.println(\"Multiplication Assignment: x *= y : \" + x);\n\n        // division assignment\n        x /= y;\n        System.out.println(\"Division Assignment: x /= y : \" + x);\n\n        // modulus assignment\n        x %= y;\n        System.out.println(\"Modulus Assignment: x %= y : \" + x);\n    }// end of method main \n}// end of class ShorthandExpressions \n```\n## 5. CASTING\nIn Java, casting is the process of converting one data type to another.\n\n\u003cimg src=\"https://media.giphy.com/media/C9iYoljYrwIISmWBWg/giphy.gif\"\u003e\n\n| Type | Description |\n| --- | --- |\n| Implicit casting | Also known as automatic casting, it occurs when a smaller type is converted to a larger type without the need for explicit casting. |\n| Explicit casting | Also known as manual casting, it occurs when a larger type is converted to a smaller type. |\n\n### 5.1 Example\n\n```java\npublic class Casting \n{\n    public static void main(String[] args) \n    {\n        // Implicit casting\n        int a = 10;\n        long b = a; // automatic casting from int to long\n\n        // Explicit casting\n        double c = 2.12;\n        int d = (int)c; // explicit casting from double to int\n\n        System.out.println(\"Implicit casting: int to long : \" + b);\n        System.out.println(\"Explicit casting: double to int : \" + d);\n    }// end of method main \n}// end of class Casting\n```\n\n## 6. RELATIONAL AND LOGICAL EXPRESSIONS\n\nIn Java, relational and logical expressions are used to make comparisons and control the flow of a program.\n\n\u003cimg src=\"https://media.giphy.com/media/2aWxyHllMdWS07RCnU/giphy.gif\"\u003e\n\n| Logical And Relational Expressions | Symbol | Description |\n| --- | --- | --- |\n| AND | \u0026\u0026 | Returns true if both operands are true |\n| OR | \\|\\| | Returns true if one or both operands are true |\n| NOT | ! | Returns true if the operand is false and false if the operand is true |\n| Less than | \u003c | Returns true if the left operand is less than the right operand |\n| Less than or equal to | \u003c= | Returns true if the left operand is less than or equal to the right operand |\n| Greater than | \u003e | Returns true if the left operand is greater than the right operand |\n| Greater than or equal to | \u003e= | Returns true if the left operand is greater than or equal to the right operand |\n| Not equal to | != | Returns true if the operands are not equal |\n| Equal to | == | Returns true if the operands are equal |\n\n### 6.1 Example \n\n```java\npublic class RelationalAndLogicalExpressions\n{\n    public static void main(String[] args)\n    {\n        int a = 13;\n        int b = 5;\n\n        // relational greater than\n        if (a \u003e b)\n        {\n            System.out.println(\"a is greater than b\");\n        }\n\n        // relational less than\n        if (a \u003c b)\n        {\n            System.out.println(\"a is less than b\");\n        }\n\n        // relational greater than or equal to\n        if (a \u003e= b)\n        {\n            System.out.println(\"a is greater than or equal to b\");\n        }\n\n        // relational less than or equal to\n        if (a \u003c= b)\n        {\n            System.out.println(\"a is less than or equal to b\");\n        }\n\n        // relational equal to\n        if (a == b)\n        {\n            System.out.println(\"a is equal to b\");\n        }\n\n        // relational not equal to\n        if (a != b)\n        {\n            System.out.println(\"a is not equal to b\");\n        }\n\n        // logical AND\n        if (a \u003e b \u0026\u0026 a \u003c 20)\n        {\n            System.out.println(\"a is greater than b and less than 20\");\n        }\n\n        // logical OR\n        if (a \u003e b || a \u003c 20)\n        {\n            System.out.println(\"a is either greater than b or less than 20\");\n        }\n\n        // logical NOT\n        if (!(a == b))\n        {\n            System.out.println(\"a is not equal to b\");\n        }\n    }// end of method main\n}// end of class RelationalAndLogicalExpressions\n```\n\n## 7. CONDITIONAL STATEMENTS\nIn Java, conditional statements are used to control the flow of a program based on certain conditions. The most basic and commonly used conditional statement is the if statement.\n\n\u003cimg src=\"https://media.giphy.com/media/mDN2PrgD9VuQJG0LY2/giphy-downsized.gif\"\u003e\n\n### 7.1 If Statement\n\nThe if statement allows you to execute a block of code only if a certain condition is true. The basic syntax for an if statement is as follows:\n\n| Syntax | Description |\n| --- | --- |\n| `if (condition) ` \u003cbr\u003e ` {` \u003cbr\u003e `// code to be executed if the condition is true` \u003cbr\u003e `}` | Executes a block of code if the specified condition is true |\n| `if (condition) ` \u003cbr\u003e ` {` \u003cbr\u003e `// code to be executed if the condition is true` \u003cbr\u003e `} ` \u003cbr\u003e ` else ` \u003cbr\u003e ` {` \u003cbr\u003e `// code to be executed if the condition is false` \u003cbr\u003e `}` | Executes a block of code if the specified condition is true, and another block of code if the condition is false |\n| `if (condition1) ` \u003cbr\u003e ` {` \u003cbr\u003e `// code to be executed if condition1 is true` \u003cbr\u003e `} ` \u003cbr\u003e ` else if ` \u003cbr\u003e ` (condition2) {` \u003cbr\u003e `// code to be executed if condition2 is true` \u003cbr\u003e `} ` \u003cbr\u003e ` else ` \u003cbr\u003e ` {` \u003cbr\u003e `// code to be executed if both conditions are false` \u003cbr\u003e `}` | Executes a block of code for the first true condition, and another block of code if none of the conditions are true |\n\n### 7.2 Example \n\n```java\npublic class IfElseExample\n{\n    public static void main(String[] args)\n    {\n\n        int age = 40;\n\n        // if statement\n        if (age \u003e= 18)\n        {\n            System.out.println(\"You are an adult.\");\n        }\n\n        // if-else statement\n        if (age \u003e= 21)\n        {\n            System.out.println(\"You can drink alcohol.\");\n        } \n        else\n        {\n            System.out.println(\"You cannot drink alcohol.\");\n        }\n\n        // if-if-else-else statement\n        if (age \u003e= 65)\n        {\n            System.out.println(\"You are a senior citizen.\");\n        } \n        else if (age \u003e= 18)\n        {\n            System.out.println(\"You are an adult.\");\n        }\n        else\n        {\n            System.out.println(\"You are a minor.\");\n        }\n    }// end of method main \n}// end of class IfElseExample\n```\n\n### 7.3 Switch Statement\n\nA switch statement in Java is used to execute different code based on the value of an expression. The expression is evaluated, and the corresponding branch of the switch statement is executed. \n\n### 7.4 Example\n\n```java\npublic class WeekDayChecker \n{\n    public static void main(String[] args)\n    {\n        int day = 2;\n        // switch statement to check the day of the week\n        switch(day)\n\t{\n            case 1:\n                System.out.println(\"Monday\");\n                break;\n            case 2:\n                System.out.println(\"Tuesday\");\n                break;\n            case 3:\n                System.out.println(\"Wednesday\");\n                break;\n            case 4:\n                System.out.println(\"Thursday\");\n                break;\n            case 5:\n                System.out.println(\"Friday\");\n                break;\n            case 6:\n                System.out.println(\"Saturday\");\n                break;\n            case 7:\n                System.out.println(\"Sunday\");\n                break;\n            default:\n                System.out.println(\"Invalid day of the week\");\n                break;\n        }\n    }// end of method main\n}// end of class WeekDayChecker \n```\n## 8. LOOPS\n\n\u003cimg src=\"https://media.giphy.com/media/ieaUdBJJC19uw/giphy-downsized-large.gif\"\u003e\n\nJava provides several types of loops for different use cases:\n\n| Loop Type | Description | Best use |\n| --- | --- | --- |\n| for | Iterating through a range of values or an array | Counting loops |\n| while | Executing a block of code as long as a certain condition is true | Conditional loops |\n| do-while | Executing a block of code at least once before the condition is checked | Loop should always execute at least one time |\n\nAdditionally, Java provides two keywords for controlling the flow of loops:\n\n| Keyword | Description |\n| --- | --- |\n| break | Break out of a loop early |\n| continue | Skip an iteration of a loop |\n\n### 8.1 For Loop\n\nA for loop is used for iterating through a range of values or an array. It consists of three parts:\n\n1. initialization\n2. termination condition\n3. increment/decrement.\n\n### 8.2 For Loop Example\n\n```java\npublic class ForLoopExample\n{\n    public static void main(String[] args) \n    {\n        // for loop to print the numbers from 0 to 10\n        for (int i = 0; i \u003c 11; i++)\n\t{\n            System.out.println(i);\n     \t}// end of for loop\n    }// end of method main\n}// end of class ForLoopExample\n```\n### 8.3 While Loop\nWhile loop in Java consists of two parts: initialization and termination condition\n\nInitialization : set the initial value for the loop variable before the start of the loop.\n\nTermination condition: the condition that must be met for the loop to continue, if the condition is true the code inside the loop is executed, otherwise the loop is terminated.\n\nIt is important to be sure that the termination condition will be false at some point, otherwise the loop will keep running forever, this is called an infinite loop.\n### 8.4 While Loop Example\n```java\npublic class WhileLoopExample\n{\n    public static void main(String[] args)\n    {\n        int i = 0; // initialization\n        // while loop to iterate through numbers 0 to 10\n        while (i \u003c 11) // termination condition\n\t{ \n            System.out.println(i);\n            i++; // increment\n        }// end of while loop\n    }// end of method main\n}// end of class WhileLoopExample\n```\n### 8.5 Do While Loop\nDo-while loop in Java consists of two parts: initialization and termination condition\n\nInitialization : set the initial value for the loop variable before the start of the loop.\n\nTermination condition: the condition that must be met for the loop to continue, if the condition is true the code inside the loop is executed, otherwise the loop is terminated.\n\nThe main difference between a while loop and a do-while loop is that the code inside a do-while loop is executed at least once before the termination condition is checked.\n\nIt's important to be sure that the termination condition will be false at some point, otherwise the loop will keep running forever, this is called an infinite loop.\n\n### 8.6 Do While Loop Example\n```java\npublic class DoWhileLoopExample\n{\n    public static void main(String[] args)\n    {\n        int counter = 0;\n        do \n\t{\n            System.out.println(counter);\n            counter++;\n        } while (counter \u003c 10);\n    }// end of method main\n}// end of class DoWhileLoopExample\n```\n## 9. ARRAYS\n\n\u003cimg src=\"https://media.giphy.com/media/LYBHgc2yiO07G3dkkQ/giphy.gif\"\u003e\n\n| Concept | Description |\n|----------|-------------|\n| Array | A container object that holds a fixed number of values of a single type. |\n| Creating an Array | Use the keyword \"new\" followed by the data type of the array and the size of the array in brackets.  |\n| Accessing Array Elements | Elements can be accessed using their index, which starts at 0. |\n| Modifying Array Elements | Elements can be modified by assigning a new value to a specific index. |\n| Array Methods | Java provides various methods in the Arrays class for sorting, searching, and manipulating arrays. |\n\n### 9.1 One Dimensional Array Example\n```java\nclass OneDimensionalArrayExample\n{\n    public static void main(String[] args)\n    {\n        // Declare a one-dimensional array of integers\n        int[] myArray = new int[5];\n\n        // Assign values to the elements of the array\n        myArray[0] = 1;\n        myArray[1] = 2;\n        myArray[2] = 3;\n        myArray[3] = 4;\n        myArray[4] = 5;\n\t// the array\n\t//  - - - - -\n\t// |1|2|3|4|5|\n\t//  - - - - -\n        // Print out the third element of the array\n        System.out.println(\"The third element of the array is: \" + myArray[2]);\n    }// end of method main \n}// end of method OneDimensionalArrayExample\n```\n### 9.2 Two Dimensional Array \n| Key Point  | Description |\n| ---------- | ----------- |\n| Size       | The size of a two-dimensional array is the number of rows multiplied by the number of columns |\n| Usage       | Two-dimensional arrays are typically used to store and manipulate data in a tabular format |\n| Creation    | They can be created using the `new` keyword and specifying the number of rows and columns |\n| Accessing Elements | Elements in a two-dimensional array can be accessed using the `array[row][column]` notation |\n| Iteration | They can be iterated using nested loops to access each element individually |\n| Pass as a parameter | They can be passed as a parameter to a method just like a one-dimensional array |\n| Applications | Two-dimensional arrays are commonly used in many applications such as image processing, game development, and scientific computing.\n\n### 9.3 Two Dimensional Array Example\n```java\npublic class TwoDimensionalArrayExample\n{\n    public static void main(String[] args)\n    {\n    \t// create a 2D array with 3 rows and 3 columns\n        // and initialize it with values\n        int[][] arr = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };\n\n        System.out.println(\"The original array:\");\n        //printing the original array using two for loops\n        for (int i = 0; i \u003c arr.length; i++)\n\t{\n            for (int j = 0; j \u003c arr[i].length; j++)\n\t    {\n                System.out.print(arr[i][j] + \" \");\n            }// end of nested loop\n            System.out.println();\n        }// end of first loop\n\n        //modifying the array\n        arr[1][2] = 8;\n\n        System.out.println(\"\\nThe modified array:\");\n        //printing the modified array\n        for (int i = 0; i \u003c arr.length; i++)\n\t{\n            for (int j = 0; j \u003c arr[i].length; j++)\n\t    {\n                System.out.print(arr[i][j] + \" \");\n            }// end of nested loop\n            System.out.println();\n        }// end of first loop\n    }// end of method main\n}// TwoDimensionalArrayExample\n```\n### the table after the code: \n\n| 1 | 2 | 3 |\n|:-:|---|---|\n| 4 | 5 | 8 |\n| 7 | 8 | 9 |\n\n## 10. SORTING ALGORITHMS\n\n\u003cimg src=\"https://media.giphy.com/media/ezjd4NlY4w3io/giphy-downsized.gif\"\u003e\n\nSorting algorithms are used to order a collection of items in a specific way. \n\nsummary of some common sorting algorithms:\n\n| Algorithm | Best Case | Worst Case | Average Case | Space Complexity |\n|-----------|-----------|------------|--------------|------------------|\n| bubble sort|  O(n)     | O(n^2)     |   O(n^2)     |       O(1)       |\n| insertion sort| O(n)    | O(n^2)     |   O(n^2)     |       O(1)       |\n| selection sort| O(n^2)  | O(n^2)     |   O(n^2)     |       O(1)       |\n| merge sort | O(n log n)| O(n log n) | O(n log n)   |       O(n)       |\n| quick sort  | O(n log n)| O(n^2)     | O(n log n)   |       O(log n)   |\n| heap sort   | O(n log n)| O(n log n) | O(n log n)   |       O(1)       |\n\n### 10.1 Bubble Sort\n\nBubble sort is a simple sorting algorithm that repeatedly compares adjacent elements and swaps them if they are in the wrong order. It repeatedly passes through the list, comparing elements and swapping them as needed, until the list is sorted.\n\n**Time Complexity**:\n\n**Best Case:** O(n) when the list is already sorted, no swapping will be done.\n\n**Worst Case:** O(n^2) when the list is reverse sorted, each element will be compared n times before getting to its correct position.\n\n**Average Case:** O(n^2)\n\n**Space Complexity:** O(1) as it only uses a single additional memory space to keep track of the last swap.\n\n**Stability:** Stable, it preserves the relative order of elements with equal values.\n\n**In-Place:** Yes, it doesn't require extra memory to perform the sort.\n```java\nclass BubbleSort\n{\n    public static void main(String[] args)\n    {\n    \t// the array before sorting \n        int[] arr = {5, 3, 8, 6, 2, 1, 9, 4, 7};\n\t// print the array before sorting \n        System.out.println(\"Original Array: \" + Arrays.toString(arr));\n\t// sort the array\n        bubbleSort(arr);\n\t// print the array after sorting \n        System.out.println(\"Sorted Array: \" + Arrays.toString(arr));\n    }// end of method main\n    /**\n    * sort the array using bubble sort method \n    * @param array - the original array\n    * @return None\n    */\n    public static void bubbleSort(int[] arr)\n    {\n        int temp;\n        for (int i = 0; i \u003c arr.length - 1; i++)\n\t{\n            for (int j = 1; j \u003c arr.length - i; j++)\n\t    {\n                if (arr[j - 1] \u003e arr[j])\n\t\t{\n                    temp = arr[j - 1];\n                    arr[j - 1] = arr[j];\n                    arr[j] = temp;\n                }// end of if \n            }// end of nested for loops \n        }// end of for loop\n    }// end of method bubbleSort\n}// end of class BubbleSort\n```\n### 10.2 Insertion Sort\nInsertion sort is a simple sorting algorithm that builds up the final sorted list one item at a time, by inserting each new item into its correct position in the already sorted portion of the list.\n\n**Time Complexity**:\n\n**Best Case:** O(n) when the list is already sorted, each element will be inserted in the first position.\n\n**Worst Case:** O(n^2) when the list is reverse sorted, each element will be compared n times before \ngetting to its correct position.\n\n**Average Case:** O(n^2)\n\n**Space Complexity:** O(1) as it only uses a single additional memory space to keep track of the current element and its position.\n\n**Stability:** Stable, it preserves the relative order of elements with equal values.\n\n**In-Place:** Yes, it doesn't require extra memory to perform the sort.\n\n```java\nclass InsertionSort\n{\n    public static void main(String[] args)\n    {\n    \t// the array before sorting \n        int[] arr = {5, 3, 8, 6, 2, 1, 9, 4, 7};\n\t// print the array before sorting \n        System.out.println(\"Original Array: \" + Arrays.toString(arr));\n\t// sort the array\n        insertionSort(arr);\n\t// print the array after sorting \n        System.out.println(\"Sorted Array: \" + Arrays.toString(arr));\n    }// end of method main \n    /**\n    * sort the array using insertion sort sort method \n    * @param array - the original array\n    * @return None\n    */\n    public static void insertionSort(int[] arr)\n    {\n        int key, j;\n        for (int i = 1; i \u003c arr.length; i++)\n\t{\n            key = arr[i];\n            j = i - 1;\n            while (j \u003e= 0 \u0026\u0026 arr[j] \u003e key)\n\t    {\n                arr[j + 1] = arr[j];\n                j = j - 1;\n            }// end of while loop\n            arr[j + 1] = key;\n        }// end of foor loop \n    }// end of method insertionSort\n}// end of class InsertionSort\n```\n### 10.3 Selection Sort \n\nelection sort is a simple sorting algorithm that repeatedly selects the smallest (or largest) element from the unsorted portion of the list and moves it to the sorted portion.\n\nIt repeatedly finds the minimum element from the unsorted part and moves it to the end of the sorted array.\n\n**Time Complexity**:\n\n**Best Case:** O(n^2) when the list is already sorted or reverse sorted.\n\n**Worst Case:** O(n^2) when the list is reverse sorted.\n\n**Average Case:** O(n^2)\n\n**Space Complexity:** O(1) as it only uses a single additional memory space to keep track of the current minimum element and its position.\n\n**Stability:** Unstable, it doesn't preserves the relative order of elements with equal values.\n\n**In-Place:** Yes, it doesn't require extra memory to perform the sort.\n\n```java\npublic class SelectionSort\n{\n\n    public static void main(String[] args)\n    {\n        int[] arr = {5, 3, 6, 2, 10};\n\t\n        // Print the original array\n        System.out.print(\"Original Array: \");\n        for (int i : arr)\n\t{\n            System.out.print(i + \" \");\n        }// end of for loop \n\n        // Sort the array using selection sort\n        selectionSort(arr);\n\n        // Print the sorted array\n        System.out.print(\"\\nSorted Array: \");\n        for (int i : arr)\n\t{\n            System.out.print(i + \" \");\n        }// end of for loop \n    }// end of method main\n    /**\n    * sort the array using selection sort method \n    * @param array - the original array\n    * @return None\n    */\n    public static void selectionSort(int[] arr)\n    {\n        // Loop through the array\n        for (int i = 0; i \u003c arr.length - 1; i++)\n\t{\n            // Find the index of the minimum element\n            int minIndex = i;\n            for (int j = i + 1; j \u003c arr.length; j++)\n\t    {\n                if (arr[j] \u003c arr[minIndex])\n\t\t{\n                    minIndex = j;\n                }// end of if\n            }// end of for loop\n            // Swap the minimum element with the current element\n            int temp = arr[minIndex];\n            arr[minIndex] = arr[i];\n            arr[i] = temp;\n        }// end of for loop\n    }// end of method selectionSort\n}// end of class SelectionSort\n```\n\n### 10.4 Merge Sort \nMerge sort is a divide-and-conquer sorting algorithm that repeatedly divides an array or list into two halves until each half contains only one element, and then combines them back together in a sorted order.\n\nThe algorithm begins by dividing the array into two equal halves.\n\nIt then recursively sorts each half by calling the merge sort function on each half.\n\nOnce both halves are sorted, the merge function is called to merge the two sorted halves back together, in a sorted order.\n\nThe merge function compares the first element of each half and adds the smaller element to a new array. It then continues this process until one half is exhausted and adds the remaining elements of the other half.\n\nThe new array is then returned as the sorted version of the original array.\n\nThe merge sort algorithm has a time complexity of O(n log n), making it more efficient than other sorting algorithms such as bubble sort or insertion sort. It is a stable sort, meaning that it preserves the relative order of elements with equal keys. It also requires O(n) extra space to perform the sorting.\n\n```java\npublic class MergeSort \n{\n    public static void main(String[] args) \n    {\n        int[] array = {5, 1, 9, 3, 7, 6, 8, 2, 4};\n        mergeSort(array);\n        for (int i : array) \n\t{\n            System.out.print(i + \" \");\n        }// end of for \n    }// end of main method \n\t\n    /**\n    * Sorts an array using the merge sort algorithm\n    * @param: array - the array to be sorted\n    * @return: None\n    */\n    public static void mergeSort(int[] array) \n    {\n        if (array.length \u003e 1) \n\t{\n\t    // Split the array into left and right halves\n            int[] left = leftHalf(array);\n            int[] right = rightHalf(array);\n\t    \n\t    // Recursively sort the left and right halves\n            mergeSort(left);\n            mergeSort(right);\n            // Merge the sorted left and right halves back together\n            merge(array, left, right);\n        }\n    }// end of mergeSort method \n    /**\n    * Returns the left half of an array\n    * @param array - the original array\n    * @return array - the left half of the array\n    */\n    public static int[] leftHalf(int[] array) \n    {\n        int size1 = array.length / 2;\n        int[] left = new int[size1];\n        for (int i = 0; i \u003c size1; i++)\n\t{\n            left[i] = array[i];\n        }\n        return left;\n    }// end of leftHalf method \n    /**\n    * Returns the right half of an array\n    * @param array - the original array\n    * @return array - the right half of the array\n    */\n    public static int[] rightHalf(int[] array)\n    {\n        int size1 = array.length / 2;\n        int size2 = array.length - size1;\n        int[] right = new int[size2];\n        for (int i = 0; i \u003c size2; i++) {\n            right[i] = array[i + size1];\n        }\n        return right;\n    }// end of method rightHalf\n    /**\n    * Merges two sorted arrays into a single sorted array\n    * @param result - the final sorted array, left - the left half of the array, right - the right half of the array\n    @ @return None\n    */\n    public static void merge(int[] result, int[] left, int[] right)\n    {\n        int i1 = 0;\n        int i2 = 0;\n\n        for (int i = 0; i \u003c result.length; i++)\n\t{\n            if (i2 \u003e= right.length || (i1 \u003c left.length \u0026\u0026 left[i1] \u003c= right[i2]))\n\t    {\n                result[i] = left[i1];\n                i1++;\n            }\n\t    else\n\t    {\n                result[i] = right[i2];\n                i2++;\n            }\n        }// end of for loop \n    }// end of merge method \n}// end of class  MergeSort\n```\n### 10.5 Quick Sort \nQuick Sort is a sorting algorithm that uses the divide-and-conquer strategy to sort an array or a list of elements.\n\nThe basic idea behind the algorithm is to partition the array into two sub-arrays, one containing elements that are less than a chosen pivot element, and the other containing elements that are greater than the pivot.\n\nThe pivot element can be chosen in different ways, but a common approach is to select the last element of the array as the pivot.\n\nOnce the array is partitioned, the pivot element is in its final position in the sorted array. The algorithm then recursively sorts the left and right sub-arrays.\n```java\npublic class QuickSort\n{\n\n    public static void main(String[] args)\n    {\n        int[] array = {5, 1, 9, 3, 7, 6, 8, 2, 4};\n        sort(array);\n        for (int i : array)\n\t{\n            System.out.print(i + \" \");\n        }\n    }// end of main method \n\n    /**\n    * Sorts an array using the quick sort algorithm\n    * @param array - the array to be sorted\n    * @return none\n    */\n    public static void sort(int[] array)\n    {\n        sort(array, 0, array.length - 1);\n    }// end of sort method \n\n    /**\n    * Sorts an array within a given range using the quick sort algorithm\n    * @param array - the array to be sorted, int - low - the lower bound of the range to be sorted int - high - the upper bound of the range to be sorted\n    * @return None\n    */\n    private static void sort(int[] array, int low, int high)\n    {\n        if (low \u003c high)\n\t{\n            // Choose pivot and partition the array\n            int pivotIndex = partition(array, low, high);\n            // Recursively sort the left and right partitions\n            sort(array, low, pivotIndex);\n            sort(array, pivotIndex + 1, high);\n        }\n    }// end of sort method \n\n    /**\n    * Partitions an array within a given range and returns the pivot index\n    * @param array - the array to be partitioned, int - low - the lower bound of the range to be partitioned, int high - the upper bound of the range to be partitioned\n    * @return the pivot index\n    */\n    private static int partition(int[] array, int low, int high)\n    {\n        int pivot = array[high];\n        int i = low - 1;\n        for (int j = low; j \u003c high; j++)\n\t{\n            if (array[j] \u003c= pivot)\n\t    {\n                i++;\n                // Swap array[i] and array[j]\n                int temp = array[i];\n                array[i] = array[j];\n                array[j] = temp;\n            }\n        }\n        // Swap array[i + 1] and array[high]\n        int temp = array[i + 1];\n        array[i + 1] = array[high];\n        array[high] = temp;\n        return i + 1;\n    }// end of partition method \n}// end of QuickSort class \n```\n### 10.6 Heap Sort \nHeap sort is a comparison-based sorting algorithm that is based on the binary heap data structure.\n\nIn Java, it can be implemented by first creating a max heap out of the input array, and then repeatedly extracting the maximum element from the heap and placing it at the end of the sorted array. \n\nThe process continues until the heap is empty, resulting in a sorted array in ascending order. It has a time complexity of O(n log n) and requires O(1) extra space.\n```java\nclass HeapSort\n{\n\n    // Heap sort method\n    public static void heapSort(int[] arr)\n    {\n        int n = arr.length;\n\n        // Build heap (rearrange array)\n        for (int i = n / 2 - 1; i \u003e= 0; i--)\n\t{\n\t   heapify(arr, n, i);\n\t}\n        // One by one extract an element from heap\n        for (int i=n-1; i\u003e=0; i--)\n\t{\n            // Move current root to end\n            int temp = arr[0];\n            arr[0] = arr[i];\n            arr[i] = temp;\n\n            // call max heapify on the reduced heap\n            heapify(arr, i, 0);\n        }\n    }// end of method heapSort\n\n    // To heapify a subtree rooted with node i which is\n    // an index in arr[]. n is size of heap\n    static void heapify(int[] arr, int n, int i) \n    {\n        int largest = i;  // Initialize largest as root\n        int l = 2*i + 1;  // left = 2*i + 1\n        int r = 2*i + 2;  // right = 2*i + 2\n\n        // If left child is larger than root\n        if (l \u003c n \u0026\u0026 arr[l] \u003e arr[largest])\n\t{\n\t   largest = l;\n\t}\n            \n        // If right child is larger than largest so far\n        if (r \u003c n \u0026\u0026 arr[r] \u003e arr[largest])\n\t{\n\t     largest = r;\n\t}\n\t\n        // If largest is not root\n        if (largest != i)\n\t{\n            int swap = arr[i];\n            arr[i] = arr[largest];\n            arr[largest] = swap;\n\n            // Recursively heapify the affected sub-tree\n            heapify(arr, n, largest);\n        }\n    }// end of heapify method \n\n    public static void main(String args[])\n    {\n        int[] arr = {12, 11, 13, 5, 6, 7};\n        heapSort(arr);\n\n        System.out.println(\"Sorted array is:\");\n        for (int i=0; i\u003carr.length; ++i)\n\t{\n\t    System.out.print(arr[i]+\" \");\n\t}      \n    }// end of main method \n}// end of class HeapSort\n```\n## 11. SEARCHING ALGORITHMS\n\n\u003cimg src=\"https://media.giphy.com/media/HdkzWcDvoRmLmkrWOt/giphy.gif\" \u003e\n\nSearching algorithms are a set of methods used to locate specific data within a larger data set. \n\nThe most common types of searching algorithms include linear search, binary search, jump search, interpolation search, depth-first search, and breadth-first search.\n\n| Algorithm        | Time Complexity           | Space Complexity |\n| ------------------|--------------------------|------------------|\n| Linear Search     | O(n)                      | O(1)             |\n| Binary Search     | O(log n)                  | O(1)             |\n| Jump Search       | O(√n)                     | O(1)             |\n| Interpolation Search | O(log log n)             | O(1)             |\n| Depth First Search| O(V + E)                   | O(V)             |\n| Breadth First Search| O(V + E)                  | O(V)    \n\n### 11.1 Linear Search\ninear search is the simplest search algorithm and involves iterating through each element of the data set until the desired element is found.\n\nThe time complexity for this algorithm is O(n), where n is the number of elements in the data set.\n\n```java\npublic class LinearSearch\n{\n    /**\n    * Method to implement Linear Search algorithm to find a specific element in an array. \n    * If the element doesn't exist in the array, the method returns -1.\n    * @param array - array, int x - the number we want to find  \n    * @return int \n    */\n    public static int linearSearch(int[] arr, int x)\n    {\n        for (int i = 0; i \u003c arr.length; i++)\n\t{\n            if (arr[i] == x)\n\t    {\n                return i;\n            }\n        }\n        return -1;\n    }// end of linearSearch method \n\n    public static void main(String[] args)\n    {\n        int[] arr = {2, 3, 4, 10, 40};\n        int x = 10;\n\n        int result = linearSearch(arr, x);\n        if (result == -1)\n\t{\n            System.out.println(\"Element not present in array.\");\n        } \n\telse\n\t{\n            System.out.println(\"Element found at index: \" + result);\n        }\n    }// end of main method \n}// end of class LinearSearch\n```\n\n### 11.1 Binary Search \nBinary search is a more efficient search algorithm that works by repeatedly dividing the search interval in half.\n\nThe time complexity for this algorithm is O(log n), which makes it more efficient than linear search for large data sets.\n```java\npublic class BinarySearch\n{\n    /**\n    * Method to implement Binary Search algorithm to find a specific element in an array. \n    * If the element doesn't exist in the array, the method returns -1.\n    * @param array, int x\n    * @return int \n    */\n    public static int binarySearch(int[] arr, int x)\n    {\n        int left = 0;\n        int right = arr.length - 1;\n        while (left \u003c= right)\n\t{\n            int mid = left + (right - left) / 2;\n            if (arr[mid] == x)\n\t    {\n                return mid;\n            } \n\t    else if (arr[mid] \u003c x)\n\t    {\n                left = mid + 1;\n            }\n\t    else\n\t    {\n                right = mid - 1;\n            }\n        }\n        return -1;\n    }// end of method binarySearch\n\n    public static void main(String[] args)\n    {\n        int[] arr = {2, 3, 4, 10, 40};\n        int x = 10;\n\n        int result = binarySearch(arr, x);\n        if (result == -1)\n\t{\n            System.out.println(\"Element not present in array.\");\n        }\n\telse\n\t{\n            System.out.println(\"Element found at index: \" + result);\n        }\n    }// end of main method \n}// end of class BinarySearch\n```\n\n### 11.2 Jump Search\nJump search is an algorithm that works by jumping a fixed number of elements at a time instead of iterating through each element. The time complexity for this algorithm is O(√n).\n\n```java\npublic class JumpSearch\n{\n    /**\n    * Method to implement Jump Search algorithm to find a specific element in an array. \n    * If the element doesn't exist in the array, the method returns -1.\n    * @param array - the array to search through, int x - the element to search for\n    * @return int - the index of the element if found, -1 if not found\n    */\n    public static int jumpSearch(int[] array, int x)\n    {\n        int n = array.length;\n        int step = (int) Math.sqrt(n);\n        int prev = 0;\n        while (array[Math.min(step, n) - 1] \u003c x)\n\t{\n            prev = step;\n            step += (int) Math.sqrt(n);\n            if (prev \u003e= n)\n\t    {\n                return -1;\n            }\n        }\n        while (array[prev] \u003c x)\n\t{\n            prev++;\n            if (prev == Math.min(step, n))\n\t    {\n                return -1;\n            }\n        }\n        if (array[prev] == x)\n\t{\n            return prev;\n        }\n        return -1;\n    }// end of method jumpSearch\n\n    public static void main(String[] args)\n    {\n        int[] array = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144};\n        int x = 55;\n        int index = jumpSearch(array, x);\n        if (index != -1)\n\t{\n            System.out.println(\"Element found at index: \" + index);\n        }\n\telse\n\t{\n            System.out.println(\"Element not found in array.\");\n        }\n    }// end of main method \n}// end of class JumpSearch\n```\n### 11.3 Interpolation Search\nInterpolation search is a search algorithm for sorted arrays. \n\nIt works by making an educated guess about the position of the element in the array, based on the value of the element and the range of values in the array. \n\nThe algorithm then repeatedly narrows down the search space by determining if the guessed position is too high or too low, and then updating the guess based on this information.\n\nThe algorithm terminates when the element is found or when the search space has been narrowed down to a single element that is not the target.\n\nInterpolation search is faster than a typical binary search when the elements in the array are uniformly distributed.\n\n```java\npublic class InterpolationSearch\n{\n    /**\n    * Method to implement Interpolation Search algorithm to find a specific element in an array. \n    * If the element doesn't exist in the array, the method returns -1.\n    * @param array - the array to search through, int x - the element to search for\n    * @return int - the index of the element if found, -1 if not found\n    */\n    public static int interpolationSearch(int[] array, int x)\n    {\n        int low = 0;\n        int high = array.length - 1;\n        while (low \u003c= high \u0026\u0026 x \u003e= array[low] \u0026\u0026 x \u003c= array[high])\n\t{\n            int pos = low + (((high - low) / (array[high] - array[low])) * (x - array[low]));\n            if (array[pos] == x)\n\t    {\n                return pos;\n            }\n            if (array[pos] \u003c x)\n\t    {\n                low = pos + 1;\n            } \n\t    else\n\t    {\n                high = pos - 1;\n            }\n        }\n        return -1;\n    }// end of method interpolationSearch\n\n    public static void main(String[] args)\n    {\n        int[] array = {10, 12, 13, 16, 18, 19, 20, 21, 22, 23, 24, 33, 35, 42, 47};\n        int x = 18;\n        int index = interpolationSearch(array, x);\n        if (index != -1)\n\t{\n            System.out.println(\"Element found at index: \" + index);\n        } \n\telse\n\t{\n            System.out.println(\"Element not found in array.\");\n        }\n    }// end of main method \n}// end of InterpolationSearch class \n```\n### 11.4 Depth First Search\nDepth First Search (DFS) is a graph traversal algorithm that explores as far as possible along each branch before backtracking.\n\nIt starts at a specific vertex (or source node) and visits each vertex in the graph by following each edge as far as possible before backtracking.\n\nDFS can be implemented using a stack data structure, where the vertices that have yet to be visited are pushed onto the stack, and the last vertex added to the stack is the next vertex to be visited.\n\nThe algorithm terminates when all vertices have been visited or when a specific goal vertex is found. DFS can be used to find the connected components of a graph, solve puzzles and games, and find the paths between two vertices in a graph.\n\n```java\nimport java.util.LinkedList;\nimport java.util.Queue;\n\npublic class DepthFirstSearch\n{\n    static class TreeNode\n    {\n        int val;\n        TreeNode left;\n        TreeNode right;\n\n        TreeNode(int val)\n\t{\n            this.val = val;\n            this.left = null;\n            this.right = null;\n        }\n    }// end of class TreeNode\n\n    /**\n     * Method to implement Depth First Search algorithm to find a specific element in a tree.\n     * If the element doesn't exist in the tree, the method returns false.\n     * @param root - the root of the tree, int x - the element to search for\n     * @return boolean - true if the element is found, false if not found\n     */\n      public static boolean dfs(TreeNode root, int x)\n      {\n        if (root == null)\n\t{\n            return false;\n        }\n        if (root.val == x)\n\t{\n            return true;\n        }\n        boolean left = dfs(root.left, x);\n        boolean right = dfs(root.right, x);\n        return left || right;\n      }// end of method dfs\n\n    public static void main(String[] args)\n    {\n        TreeNode root = new TreeNode(1);\n        root.left = new TreeNode(2);\n        root.right = new TreeNode(3);\n        root.left.left = new TreeNode(4);\n        root.left.right = new TreeNode(5);\n        int x = 4;\n        boolean found = dfs(root, x);\n        if (found)\n\t{\n            System.out.println(\"Element found in tree.\");\n        }\n\telse\n\t{\n            System.out.println(\"Element not found in tree.\");\n        }\n    }// end of method main\n}// end of class DepthFirstSearch\n```\n### 11.5 Breadth First Search\nBreadth First Search (BFS) is a graph traversal algorithm that visits all the vertices of a graph in breadth-first order, meaning it visits all the vertices at a given depth level before moving on to the next level. \n\nIt starts at a specific vertex (or source node) and visits all its neighboring vertices first, before visiting the vertices at the next level.\n\nBFS can be implemented using a queue data structure, where the vertices to be visited are added to the queue, and the first vertex in the queue is the next vertex to be visited.\n\nThe algorithm terminates when all vertices have been visited or when a specific goal vertex is found. BFS can be used to find the shortest path between two vertices in a graph, find the connected components of a graph and solve puzzles and games.\n\n```java\nimport java.util.LinkedList;\nimport java.util.Queue;\n\npublic class BreadthFirstSearch\n{\n    /**\n    * method find a specific element in a tree using breadth first search\n    * if the element is not found, the method returns -1\n    * @param Node root - the root of the tree, int x - the element to search for\n    * @return int - the value of the element if found, -1 if not found\n    */\n    public static int bfs(Node root, int x)\n    {\n        Queue\u003cNode\u003e queue = new LinkedList\u003c\u003e();\n        queue.add(root);\n\n        while (!queue.isEmpty())\n\t{\n            Node current = queue.poll();\n            if (current.value == x)\n\t    {\n                return current.value;\n            }\n            if (current.left != null)\n\t    {\n                queue.add(current.left);\n            }\n            if (current.right != null)\n\t    {\n                queue.add(current.right);\n            }\n        }\n\n        return -1;\n      }// end of method bfs\n\n    public static void main(String[] args)\n    {\n        // create a sample tree for demonstration\n        Node root = new Node(1);\n        root.left = new Node(2);\n        root.right = new Node(3);\n        root.left.left = new Node(4);\n        root.left.right = new Node(5);\n\n        int elementToFind = 4;\n        int result = bfs(root, elementToFind);\n        System.out.println(\"Value of element \" + elementToFind + \": \" + result);\n    }// end of main method \n}// end of class BreadthFirstSearch\n\nclass Node\n{\n    int value;\n    Node left;\n    Node right;\n\n    public Node(int value)\n    {\n        this.value = value;\n        left = null;\n        right = null;\n    }// end of method Node \n}// end of class Node\n```\n## 12. MATH CLASS\n\n\u003cimg src=\"https://media.giphy.com/media/gEvab1ilmJjA82FaSV/giphy-downsized.gif\"\u003e\n\nThe java.lang.Math class contains a variety of mathematical functions and constants. Some of the most commonly used methods include:\n\nFunction | Description\n--------- | -----------\nMath.abs(x) | Returns the absolute value of a given number.\nMath.ceil(x) | Returns the smallest integer greater than or equal to a given number.\nMath.floor(x) | Returns the largest integer less than or equal to a given number.\nMath.max(x, y) | Returns the larger of two given numbers.\nMath.min(x, y) | Returns the smaller of two given numbers.\nMath.pow(x, y) | Returns x raised to the power of y.\nMath.sqrt(x) | Returns the square root of a given number.\nMath.random() | Returns a random number between 0 and 1.\nMath.round(x) | Returns the closest integer to a given number.\nMath.sin(x) | Returns the sine of a given angle in radians.\nMath.cos(x) | Returns the cosine of a given angle in radians.\nMath.tan(x) | Returns the tangent of a given angle in radians.\nMath.asin(x) | Returns the arcsine of a given value in radians.\nMath.acos(x) | Returns the arccosine of a given value in radians.\nMath.atan(x) | Returns the arctangent of a given value in radians.\nMath.log(x) | Returns the natural logarithm of a given number.\nMath.log10(x) | Returns the base-10 logarithm of a given number.\nMath.E | The base of the natural logarithms (approximately 2.718).\nMath.PI | The ratio of the circumference of a circle to its diameter (approximately 3.14159).\n\nAll of these functions are static, which means that you can call them directly on the Math class, without needing to create an instance of the class.\n\n### 12.1 Math Class Example\n\n```java\nclass MathClassExample\n{\n    public static void main(String[] args)\n    {\n\n        // Using Math.abs()\n        int number = -5;\n        int absoluteValue = Math.abs(number);\n        System.out.println(\"Absolute value of \" + number + \" is \" + absoluteValue);\n        \n        // Using Math.ceil()\n        double decimal = 4.3;\n        double ceilValue = Math.ceil(decimal);\n        System.out.println(\"Smallest integer greater than or equal to \" + decimal + \" is \" + ceilValue);\n        \n        // Using Math.floor()\n        decimal = 5.8;\n        double floorValue = Math.floor(decimal);\n        System.out.println(\"Largest integer less than or equal to \" + decimal + \" is \" + floorValue);\n        \n        // Using Math.max()\n        int x = 10;\n        int y = 15;\n        int maxValue = Math.max(x, y);\n        System.out.println(\"Larger of \" + x + \" and \" + y + \" is \" + maxValue);\n        \n        // Using Math.min()\n        x = 20;\n        y = 25;\n        int minValue = Math.min(x, y);\n        System.out.println(\"Smaller of \" + x + \" and \" + y + \" is \" + minValue);\n        \n        // Using Math.pow()\n        x = 2;\n        y = 3;\n        double powerValue = Math.pow(x, y);\n        System.out.println(x + \" raised to the power of \" + y + \" is \" + powerValue);\n    }// end of main method \n}// end of class MathClassExample\n```\n## 13. STRING CLASS\n\n\u003cimg src=\"https://media.giphy.com/media/xT5LMLKAxV7XswLQsw/giphy.gif\"\u003e\n\nThe String class in Java is a built-in class that represents a sequence of characters. It is one of the most widely used classes in Java, and it is used to represent text. Some of the key features of the String class include:\n\nImmutable: Once a String object is created, its value cannot be changed. Any operation that modifies the value of a String will create a new String object.\n\nConcatenation: The + operator can be used to concatenate two String objects. The concat() method can also be used to concatenate String objects.\n\nComparison: The equals() method can be used to compare the values of two String objects. The compareTo() method can be used to compare the lexicographic order of two String objects.\n\nSearching: The indexOf() method can be used to find the index of a specific character or substring within a String. The lastIndexOf() method can be used to find the last occurrence of a specific character or substring within a String.\n\nSubstring: The substring() method can be used to extract a portion of a String.\n\nManipulation: The toLowerCase(), toUpperCase(), trim() method can be used to manipulate the string.\n\nSplit: The split() method can be used to split a String into an array of substrings based on a specified delimiter.\n\nFormatting: The format() method can be used to format String in a specific way.\n\nRegular expression: String class has matches() method that can be used to check if the string matches a specific regular expression.\n\nThese are some of the most common and useful methods of the String class. It also has many other methods that provide additional functionality.\n\n\nMethod | Description\n--------- | -----------\nchar charAt(int index) | Returns the char value at the specified index\nint compareTo(String anotherString) | Compares two strings lexicographically\nint compareToIgnoreCase(String str) | Compares two strings lexicographically, ignoring case differences\nString concat(String str) | Concatenates the specified string to the end of this string\nboolean contains(CharSequence s) | Returns true if and only if this string contains the specified sequence of char values\nstatic String copyValueOf(char[] data) | Equivalent to valueOf(char[])\nstatic String copyValueOf(char[] data, int offset, int count) | Equivalent to valueOf(char[], int, int)\nboolean endsWith(String suffix) | Tests if this string ends with the specified suffix\nboolean equals(Object anObject) | Compares this string to the specified object\nboolean equalsIgnoreCase(String anotherString) | Compares this String to another String, ignoring case considerations\nvoid getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) | Copies characters from this string into the destination character array\nint indexOf(int ch) | Returns the index within this string of the first occurrence of the specified character\nint indexOf(int ch, int fromIndex) | Returns the index within this string of the first occurrence of the specified character, starting the search at the specified index\nint indexOf(String str) | Returns the index within this string of the first occurrence of the specified substring\nint indexOf(String str, int fromIndex) | Returns the index within this string of the first occurrence of the specified substring, starting at the specified index\nboolean isEmpty() | Returns true if, and only if, length() is 0\nint lastIndexOf(int ch) | Returns the index within this string of the last occurrence of the specified character\nint lastIndexOf(int ch, int fromIndex) | Returns the index within this string of the last occurrence of the specified character, searching backward starting at the specified index\nint lastIndexOf(String str) | Returns the index within this string of the last occurrence of the specified substring\nint lastIndexOf(String str, int fromIndex) | Returns the index within this string of the last occurrence of the specified substring, searching backward starting at the specified index\nint length() | Returns the length of this string\nString replace(char oldChar, char newChar) | Returns a string resulting from replacing all occurrences of oldChar in this string with newChar\nString replace(CharSequence target, CharSequence replacement) | Replaces each substring of this string that matches the literal target sequence with the specified literal replacement sequence\nString replaceAll(String regex, String replacement) | Replaces each substring of this string that matches the given regular expression with the given replacement\nString replaceFirst(String regex, String replacement) | Replaces the first substring of this string that matches the given regular expression with the given replacement\nString[] split(String regex) | Splits this string around matches of the given regular expression\nString[] split(String regex, int limit) | Splits this string around matches of the given regular expression\nboolean startsWith(String prefix) | Tests if this string starts with the specified prefix.\nboolean startsWith(String prefix, int toffset) | Tests if the substring of this string beginning at the specified index starts with the specified prefix\nCharSequence subSequence(int beginIndex, int endIndex) | Returns a character sequence that is a subsequence of this sequenc\nString substring(int beginIndex) | Returns a string that is a substring of this string\nchar[] toCharArray() | Converts this string to a new character array\nString toLowerCase() | Converts all of the characters in this String to lower case using the rules of the default locale\nString toLowerCase(Locale locale) | Converts all of the characters in this String to lower case using the rules of the given Locale\nString toUpperCase() | Converts all of the characters in this String to upper case using the rules of the default locale\nString toUpperCase(Locale locale) | Converts all of the characters in this String to upper case using the rules of the given Locale\nString trim() | Returns a string whose value is this string, with any leading and trailing whitespace removed\n\n## 14. STRING BUFFER CLASS\n\n\u003cimg src=\"https://media.giphy.com/media/uurtMtTKqkJda4dk8Y/giphy-downsized.gif\"\u003e\n\nStringBuffer is a class in Java that provides a mutable sequence of characters.\n\nIt is similar to the String class, but it can be modified after it is created. StringBuffer is thread-safe, meaning that multiple threads can access a single StringBuffer object without causing any problems.\n\nSome common methods of the StringBuffer class include append, insert, and reverse. Additionally, StringBuffer has a capacity that can be increased if necessary to prevent reallocation of memory while concatenation.\n\n| Method | Description |\n| --- | --- |\n| `append(Object obj)` | Appends the string representation of the Object argument. |\n| `charAt(int index)` | Returns the char value in this sequence at the specified index. |\n| `delete(int start,int end)` | Removes the characters in a substring of this sequence. |\n| `deleteCharAt(int index)` | Removes the char at the specified position in this sequence. |\n| `getChars(int srcBegin,int srcEnd,char[] dst,int dstBegin)` | Characters are copied from this sequence into the destination character array dst. |\n| `equals(StringBuffer sb)` | Compares this object against the specified object. |\n| `indexOf(String str)` | Returns the index within this string of the first occurrence of the specified substring. |\n| `indexOf(String str,int fromIndex)` | Returns the index within this string of the first occurrence of the specified substring, starting at the specified index. |\n| `insert(int offset,String str)` | Inserts the string into this character sequence. |\n| `lastIndexOf(String str,int fromIndex)` | Returns the index within this string of the last occurrence of the specified substring. |\n| `length()` | Returns the length (character count). |\n| `replace(int start,int end,String str)` | Replaces the characters in a substring of this sequence with characters in the specified String. |\n| `reverse()` | Causes this character sequence to be replaced by the reverse of the sequence. |\n| `setCharAt(int index,char ch)` | The character at the specified index is set to ch. |\n| `subSequence(int start,int end)` | Returns a new character sequence that is a subsequence of this sequence. |\n| `substring(int start,int end)` | Returns a new String that contains a subsequence of characters currently contained in this sequence. |\n| `trimToSize()` | Attempts to reduce storage used for the character sequence. |\n\n## 15. METHODS\n\n\u003cimg src=\"https://media.giphy.com/media/lS0uY9t6lCi69FcWRA/giphy-downsized.gif\"\u003e\n\nIn Java, methods are blocks of code that perform a specific task. They are used to encapsulate functionality and can be called multiple times within a program.\n\nA method that has a return type of void, which means it does not return any value.\n\nA method that has a return type and a method name, which means it returns a value of the specified type.\n\nA method can be marked as static, which means it can be called without creating an instance of the class.\n\nA method can take in parameters of different types and names, for example methodName(parameterType parameterName, parameterType parameterName)\nA method can be marked as final, which means it cannot be overridden by subclasses.\nA method can be marked as abstract, which means it has no implementation and must be implemented by subclasses.\n\nIt's worth noting that the return type can be any valid Java data type, including primitives, objects, and arrays. Also, the naming convention of methods are camelCase and the first letter is lowercase.\n\n| Method | Description |\n| --- | --- |\n| `void returnType()` |  A method that has a return type of void, which means it does not return any value. |\n| `returnType methodName()` | A method that has a return type and a method name, which means it returns a value of the specified type. |\n| `static returnType methodName()` | A method that is marked as static, which means it can be called without creating an instance of the class. |\n| `methodName(parameterType parameterName)` | A method that takes in a parameter of the specified type and name. |\n| `methodName(parameterType parameterName, parameterType parameterName)` | A method that takes in multiple parameters of different types and names. |\n| `final returnType methodName()` | A method that is marked as final, which means it cannot be overridden by subclasses. |\n| `abstract returnType methodName()` | A method that is marked as abstract, which means it has no implementation and must be implemented by subclasses. |\n\n```java\npublic class MethodExample\n{\n    public static void main(String[] args)\n    {\n        printMessage();\n        int result = add(5, 10);\n        System.out.println(\"Result of addition: \" + result);\n        double quotient = divide(20, 10);\n        System.out.println(\"Result of division: \" + quotient);\n        int product = multiply(5, 10);\n        System.out.println(\"Result of multiplication: \" + product);\n    }// end of main method \n    /**\n    * method print message \n    * @param None\n    * @return None\n    */\n    public static void printMessage()\n    {\n        System.out.println(\"Hello, this is a message from the print method.\");\n    }// end of method printMessage \n    /**\n    * method add two numbers \n    * @param int a, int b\n    * @return int\n    */\n    public static int add(int a, int b)\n    {\n        return a + b;\n    }// end of method add\n    /**\n    * method divide two numbers \n    * @param double a, double b\n    * @return double\n    */\n    public static double divide(double a, double b)\n    {\n        return a / b;\n    }// end of method divide\n    /**\n    * method multiply two numbers \n    * @param int a, int b\n    * @return int \n    */\n    public static int multiply(int a, int b)\n    {\n        return a * b;\n    }// end of method multiply\n}// end of class MethodExample\n```\n## 16. RANDOM NUMBERS\n\nIn Java, there are several ways to generate random numbers.\n\nThe most commonly used method is through the use of the \"Random\" class, which is part of the Java standard library.\n\nThis class provides methods for generating various types of random numbers, such as integers, doubles, and booleans. Additionally, the class also provides methods for generating random numbers within a specified range.\n\n![SuperRandomJohnnyWeissGIF](https://user-images.githubusercontent.com/91504420/213818160-5087f1ff-3a16-4d25-b450-589e1ce85d6d.gif)\n\n```java\nimport java.util.Random;\n\npublic class RandomNumbers\n{\n    public static void main(String[] args)\n    {\n        // Creating an object of the Random class\n        Random rand = new Random();\n        \n        // Generating a random integer between 0 and 9 (inclusive)\n        int randomInt = rand.nextInt(10);\n        System.out.println(\"Random Integer: \" + randomInt);\n\n        // Generating a random float between 0 and 1 (inclusive)\n        float randomFloat = rand.nextFloat();\n        System.out.println(\"Random Float: \" + randomFloat);\n\n        // Generating a random double between 0 and 1 (inclusive)\n        double randomDouble = rand.nextDouble();\n        System.out.println(\"Random Double: \" + randomDouble);\n    }// end of method main \n}// end of class RandomNumbers \n```\n\n## 17. RECURSION\n\n![CatsGIF](https://user-images.githubusercontent.com/91504420/213818272-6a195ca3-2252-4b7f-8255-02ba2a514ee4.gif)\n\nRecursion in Java is a programming technique where a method calls itself in order to solve a problem. The method has a base case, which is a simple and straightforward problem that can be solved without recursion, and a recursive case, which breaks down the problem into simpler subproblems that can be solved using the same method.\n\nIn order for a recursive method to terminate, it must have a base case that is reached at some point. If the base case is not reached, the method will continue calling itself indefinitely, resulting in a stack overflow error.\n\nA common example of recursion is the factorial function, which calculates the factorial of a given number. This can be computed using a loop, but it can also be computed using recursion.\n\nRecursive methods can also be more efficient than their iterative counterparts, as they can take advantage of the computer's stack memory to store temporary data.\n\nHowever, recursion can also consume more memory and processing power, so it's important to use it judiciously and be mindful of the problem's complexities.\n\nIt's also important to be mindful of the problem's complexities when using recursion and that some problems can be solved more efficiently with an iterative approach.\n\n```java\npublic class Recursion \n{\n    public static void main(String[] args)\n    {\n        // Call the recursive method\n        int result = factorial(5);\n        System.out.println(\"Factorial of 5: \" + result);\n    }// end of method main \n\n    // Recursive method to calculate the factorial of a given number\n    public static int factorial(int n)\n    {\n        // Base case: if n is 0 or 1, return 1\n        if (n == 0 || n == 1)\n\t{\n            return 1;\n        }\n        // Recursive case: return n * factorial(n-1)\n        else \n\t{\n            return n * factorial(n-1);\n        }\n    }// end of method factorial\n}// end of class Recursion \n```\n## 18. READ AND WRITE TO FILE\n\n![INeedThoseFilesAssistantSpecialAgentInChargeJubalValentineGIF](https://user-images.githubusercontent.com/91504420/213818305-5e1e57df-ac01-446c-85ca-511c5c7d7b1a.gif)\n\nReading and writing to a file in Java can be done using the File and Scanner classes for reading, and the FileWriter and PrintWriter classes for writing.\n\nTo read a file, you can first create a File object that represents the file you want to read, and then create a Scanner object that reads the contents of the file. You can then use the nextLine() method of the Scanner class to read each line of the file.\n\nTo write a file, you can first create a FileWriter object that represents the file you want to write to, and then create a PrintWriter object that writes to the file. You can then use the println() method of the PrintWriter class to write to the file.\n\nIt's important to handle the exception when reading and writing to a file in case the file doesn't exist or there's a problem with the file path.\n\nWhen reading and writing to a file, it's also important to close the file when you're finished. This can be done by calling the close() method on the Scanner, FileWriter, and PrintWriter objects.\n\nIt's also worth noting that java.nio package offers another set of classes to perform file reading and writing operations such as Files, Paths and BufferedReader which offer better performance and flexibility over the traditional IO package.\n\n```java\nimport java.io.*;\n\npublic class WorkWithFile\n{\n    public static void main(String[] args)\n    {\n        // File to read from\n        File file = new File(\"example.txt\");\n        // File to write to\n        File outputFile = new File(\"output.txt\");\n        \n        try \n\t{\n            // Reading from file\n            BufferedReader br = new BufferedReader(new FileReader(file));\n            String line;\n            while ((line = br.readLine()) != null) \n\t    {\n                System.out.println(line);\n            }\n            br.close();\n            \n            // Writing to file\n            PrintWriter writer = new PrintWriter(new FileWriter(outputFile));\n            writer.println(\"Writing to file example\");\n            writer.close();\n            \n        } \n\tcatch (IOException e\n\t{\n            System.out.println(\"An error occurred.\");\n            e.printStackTrace();\n        }\n    }// end of main method \n}// end of class WorkWithFile\n```\n\n## 19. LINKED LIST\n\n![EverythingIsConnectedNeilDegrasseTysonGIF](https://user-images.githubusercontent.com/91504420/213820954-910f2d25-a25f-4ab7-98d9-520940c7ac98.gif)\n\nA linked list is a data structure that consists of a sequence of elements, each containing a reference (or \"link\") to its next element. In Java, the LinkedList class is a commonly used implementation of a linked list.\n\nOne of the main advantages of a linked list over an array is that elements can be easily inserted or removed from the middle of the list. With an array, these operations would require shifting all of the elements after the insertion or removal point.\n\nThe LinkedList class in Java provides a variety of methods for working with the list, such as adding and removing elements, retrieving elements at specific positions, and searching for elements. It also implements the List interface, which means it has all the common methods that a list should have like add(), get(), remove(), size(), clear(), etc.\n\nThe LinkedList class uses a doubly-linked list implementation, which means that each element has a reference to both the next and the previous element in the list. This allows for efficient traversal in both directions.\n\nIt's worth noting that LinkedList is less efficient than an ArrayList when it comes to random access of elements (i.e. by index) since it needs to traverse the list from the head to the element's index.\n\nIt's also worth noting that linked lists require more memory than arrays, as each element requires a reference to the next element in addition to the element's value.\n\n```java\nimport java.io.*; \n    \n// Java program to implement \n// a Singly Linked List \npublic class LinkedList \n{ \n    \n    Node head; // head of list \n    \n    // Linked list Node. \n    // This inner class is made static \n    // so that main() can access it \n    static class Node \n    { \n    \n        int data; \n        Node next; \n    \n        // Constructor \n        Node(int d) \n        { \n            data = d; \n            next = null; \n        } // end of method Node\n    } // end of class Node\n    \n    // Method to insert a new node \n    public static LinkedList insert(LinkedList list, int data) \n    { \n        // Create a new node with given data \n        Node new_node = new Node(data); \n          \n    \n        // If the Linked List is empty, \n        // then make the new node as head \n        if (list.head == null)\n\t{ \n            list.head = new_node; \n        } \n        else\n\t{ \n            // Else traverse till the last node \n            // and insert the new_node there \n            Node last = list.head; \n            while (last.next != null)\n\t    { \n                last = last.next; \n            } \n    \n            // Insert the new_node at last node \n            last.next = new_node; \n        } \n    \n        // Return the list by head \n        return list; \n    } // end of method insert\n    \n    // Method to print the LinkedList. \n    public static void printList(LinkedList list) \n    { \n        Node currNode = list.head; \n     \n        System.out.print(\"LinkedList: \"); \n     \n        // Traverse through the LinkedList \n        while (currNode != null)\n\t{ \n            // Print the data at current node \n            System.out.print(currNode.data + \" \"); \n     \n            // Go to next node \n            currNode = currNode.next; \n        } \n    } // end of method printList\n    \n     // Method to delete a node in the LinkedList by KEY\n    public static LinkedList deleteByKey(LinkedList list,int key)\n    {\n        // Store head node\n        Node currNode = list.head, prev = null;\n  \n\n        if (currNode != null \u0026\u0026 currNode.data == key)\n\t{\n            list.head = currNode.next; // Changed head\n  \n            // Display the message\n            System.out.println(key + \" found and deleted\");\n  \n            // Return the updated List\n            return list;\n        }\n\n        while (currNode != null \u0026\u0026 currNode.data != key)\n\t{\n            // If currNode does not hold key\n            // continue to next node\n            prev = currNode;\n            currNode = currNode.next;\n        }\n  \n        // If the key was present, it should be at currNode\n        // Therefore the currNode shall not be null\n        if (currNode != null)\n\t{\n            // Since the key is at currNode\n            // Unlink currNode from linked list\n            prev.next = currNode.next;\n\t    \n            System.out.println(key + \" found and deleted\");\n        }\n  \n        if (currNode == null)\n\t{\n            // Display the message\n            System.out.println(key + \" not found\");\n        }\n  \n        // return the List\n        return list;\n    }// end of method deleteByKey\n    \n    // Method to delete a node in the LinkedList by POSITION\n    public static LinkedList deleteAtPosition(LinkedList list, int index)\n    {\n        // Store head node\n        Node currNode = list.head, prev = null;\n  \n        if (index == 0 \u0026\u0026 currNode != null)\n\t{\n            list.head = currNode.next; // Changed head\n  \n            // Display the message\n            System.out.println(\n                index + \" position element deleted\");\n  \n            // Return the updated List\n            return list;\n        }\n  \n        while (currNode != null)\n\t{\n  \n            if (counter == index)\n\t    {\n                // Since the currNode is the required\n                // position Unlink currNode from linked list\n                prev.next = currNode.next;\n  \n                // Display the message\n                System.out.println(\n                    index + \" position element deleted\");\n                break;\n            }\n            else\n\t    {\n                // If current position is not the index\n                // continue to next node\n                prev = currNode;\n                currNode = currNode.next;\n                counter++;\n            }\n        }\n  \n        // In this case, the currNode should be null\n        if (currNode == null)\n\t{\n            // Display the message\n            System.out.println(index + \" position element not found\");\n        }\n  \n        // return the List\n        return list;\n    }// end of method deleteAtPosition\n    \n    public static void main(String[] args) \n    { \n        /* Start with the empty list. */\n        LinkedList list = new LinkedList(); \n    \n        // Insert the values \n        list = insert(list, 1); \n        list = insert(list, 2); \n        list = insert(list, 3); \n        list = insert(list, 4); \n        list = insert(list, 5); \n        list = insert(list, 6); \n        list = insert(list, 7); \n        list = insert(list, 8); \n    \n        // Print the LinkedList \n        printList(list); \n    } // end of main method \n}// end of class LinkedList\n```\n## 20. STACKS\n\n![StackEmUpStackGIF](https://user-images.githubusercontent.com/91504420/213821631-05812600-ef40-4a6d-9d06-501dda9e1ae4.gif)\n\nA stack is a linear data structure that follows the Last-In-First-Out (LIFO) principle, meaning that the last element added to the stack will be the first one to be removed. In Java, the Stack class is a commonly used implementation of a stack.\n\nThe Stack class provides a variety of methods for working with the stack, such as pushing and popping elements, retrieving the top element, checking if the stack is empty, and determining the current size of the stack. The most important methods of the stack are push(), which adds an element to the top of the stack, pop(), which removes and returns the top element of the stack, and peek(), which returns the top element of the stack without removing it.\n\nIt's worth noting that the Stack class is considered as legacy class and it's not recommended to use it, instead of that it's recommended to use the Deque interface and it's implementations, such as ArrayDeque and LinkedList.\n\nIt's also worth noting that stack can be implemented using an array, a linked list, or any other data structure. The choice of implementation will depend on the specific requirements of the application and the trade-offs in terms of performance, memory usage, and ease of implementation.\n```java\nimport java.util.Deque;\nimport java.util.ArrayDeque;\n\npublic class StackExample\n{\n    public static void main(String[] args)\n    {\n        // Creating a stack using the ArrayDeque class\n        Deque\u003cInteger\u003e stack = new ArrayDeque\u003c\u003e();\n\n        // Adding elements to the stack\n        stack.push(1);\n        stack.push(2);\n        stack.push(3);\n\n        // Retrieving and removing the top element\n        int top = stack.pop();\n        System.out.println(\"Top element: \" + top);\n\n        // Retrieving the top element without removing it\n        top = stack.peek();\n        System.out.println(\"Top element: \" + top);\n\n        // Checking if the stack is empty\n        boolean isEmpty = stack.isEmpty();\n        System.out.println(\"Is the stack empty? \" + isEmpty);\n\n        // Determining the size of the stack\n        int size = stack.size();\n        System.out.println(\"Size of the stack: \" + size);\n    }// end of method main\n}// end of class StackExample\n```\n\n## 21. TREE\n\n![FlowersTreeGIF](https://user-images.githubusercontent.com/91504420/213821878-6cb53244-8db2-4854-af0e-5c0d8cb2bb3e.gif)\n\nA tree is a non-linear data structure that consists of a set of nodes, where each node can have one or more child nodes. In Java, the Tree interface and the DefaultMutableTreeNode class are commonly used to implement a tree.\n\nTrees can be used to represent hierarchical relationships, such as file systems, family trees, or decision-making processes. Each node in the tree represents an element, and the relationship between nodes represents a parent-child relationship.\n\nThe Tree interface provides methods for working with the tree structure, such as adding, removing, and retrieving nodes, as well as traversing the tree in various ways, such as breadth-first or depth-first. The DefaultMutableTreeNode class is a concrete implementation of the Tree interface that can be used to create a tree and add nodes to it.\n\nIn Java, there are different types of tree data structures, such as binary trees, where each node can have at most two children, and binary search trees, where the left child node has a value less than the parent node and the right child node has a value greater than the parent node.\n\n```java\nclass BinaryTree\n{\n    Node root;\n \n    public void add(int data)\n    {\n        root = addRecursive(root, data);\n    }// end of method add\n \n    private Node addRecursive(Node current, int data)\n    {\n        if (current == null)\n\t{\n            return new Node(data);\n        }\n \n        if (data \u003c current.data)\n\t{\n            current.left = addRecursive(current.left, data);\n        } \n\telse if (data \u003e current.data)\n\t{\n            current.right = addRecursive(current.right, data);\n        }\n\telse\n\t{\n            return current;\n        }\n \n        return current;\n    }// end of method addRecursive \n \n    public boolean containsNode(int data)\n    {\n        return containsNodeRecursive(root, data);\n    }// end of method containsNode\n \n    private boolean containsNodeRecursive(Node current, int data)\n    {\n        if (current == null) \n\t{\n            return false;\n        } \n        if (data == current.data) \n\t{\n            return true;\n        } \n        return data \u003c current.data ? containsNodeRecursive(current.left, data) : containsNodeRecursive(current.right, data);\n    }// end of method containsNodeRecursive\n \n    public void delete(int data) \n    {\n        root = deleteRecursive(root, data);\n    }// end of delete method \n \n    private Node deleteRecursive(Node current, int data) \n    {\n        if (current == null) \n\t{\n            return null;\n        }\n \n        if (data == current.data)\n\t{\n            if (current.left == null \u0026\u0026 current.right == null)\n\t    {\n                return null;\n            }\n            if (current.right == null)\n\t    {\n                return current.left;\n            }\n \n            if (current.left == null)\n\t    {\n                return current.right;\n            }\n            int smallestValue = findSmallestValue(current.right);\n            current.data = smallestValue;\n            current.right = deleteRecursive(current.right, smallestValue);\n            return current;\n        }\n        if (data \u003c current.data)\n\t{\n            current.left = deleteRecursive(current.left, data);\n            return current;\n        }\n        current.right = deleteRecursive(current.right, data);\n        return current;\n    }// end of deleteRecursive methdo \n \n    private int findSmallestValue(Node root)\n    {\n        return root.left == null ? root.data : findSmallestValue(root.left);\n    }// end of method findSmallestValue\n    \n    public void traverseInOrder(Node node)\n    {\n        if (node != null)\n\t{\n            traverseInOrder(node.left);\n            System.out.print(\" \" + node.data);\n            traverseInOrder(node.right);\n        }\n    }// end of method traverseInOrder \n}// end of class BinaryTree\n```\n\n## 22. ALIASING\n\n![JavaDevGIF](https://user-images.githubusercontent.com/91504420/213823727-b8867e62-1fe9-4b88-998d-48d147dbbfb3.gif)\n\nIn Java, aliasing occurs when two or more references refer to the same object in memory. This can lead to unexpected behavior, particularly when the object is modified through one reference and the change is not reflected through the other references. To avoid aliasing, it is best practice to use only one reference to an object, and to create new objects when necessary.\n\nOne of the most common ways to avoid aliasing in Java is to use the clone() method. The clone() method creates a new object that is an exact copy of the original object. The new object is completely independent of the original object and any changes made to the new object will not affect the original object.\n\nAnother way to avoid aliasing is to use immutable objects. Immutable objects are objects whose state cannot be modified after they are created. Examples of immutable objects in Java are the String, Integer, and BigDecimal classes.\n\nIn addition, it is important to use proper encapsulation techniques to limit the scope of references and make it clear which objects are being referred to. This can be done through the use of private fields and getter/setter methods.\n\nIn summary, aliasing can be avoided in Java by using the clone() method, immutable objects, and proper encapsulation techniques. These techniques help ensure that changes made to an object through one reference do not affect other references and prevent unexpected behavior.\n\n![image](https://user-images.githubusercontent.com/91504420/213823803-38ce000d-9652-44ba-a3cd-776822cad928.png)\n\n## 23. STATIC KEYWORD\n\n![ProgrammingGIF](https://user-images.githubusercontent.com/91504420/213824446-b93eb392-f6e5-45d1-8dfd-9e7a31bf9594.gif)\n\nThe static keyword in Java is used to indicate that a member (field or method) belongs to a class rather than an instance of the class. This means that the member is shared by all instances of the class and can be accessed without creating an instance of the class.\n\nHere are some key points about the static keyword in Java:\n\nStatic fields and methods can be accessed directly through the class name, without the need to create an instance of the class.\n\nStatic fields and methods are initialized only once, when the class is loaded by the JVM.\n\nStatic methods cannot access non-static fields and methods, as they do not have access to an instance of the class.\n\nStatic fields can be accessed by both static and non-static methods.\n\nStatic block is used to initialize the static variable, it gets executed only once when the class is loaded in the memory.\n\nIt is commonly used for utility classes, factory classes, and for constants.\n\nIn summary, the static keyword in Java is used to indicate that a member belongs to a class rather than an instance of the class. It allows fields and methods to be accessed directly through the class name, without the need to create an instance of the class and allows shared resources across all instances of a class. \n\nIt is commonly used for utility classes, factory classes, and for constants.\n\n```java\nclass StaticKeyword\n{\n    static int staticInt = 0; //static variable\n\n    public static void staticMethod()\n    {  \n        staticInt++;\n        System.out.println(\"This is a static method. staticInt = \" + staticInt);\n    }// end of method staticMethod \n}// end of method StaticKeyword\n```\n\n## 24. JAVADOC\n\n![ItsImportantBruhChrisReddGIF](https://user-images.githubusercontent.com/91504420/213825168-a134493c-df33-484f-af76-27ea344cfc08.gif)\n\nJavaDoc is a tool that is used to generate documentation for Java classes, methods, and fields. It uses special comments in the source code, called Javadoc comments, that begin with /** and end with */, to extract documentation. The documentation is then presented in the form of HTML pages that can be easily viewed in a web browser.\n\nJavaDoc uses a set of tags, such as @param and @return, to specify different types of information about the class, method, or field being documented. The generated documentation includes a summary of the class, method, or field, as well as details about its parameters, return type, and exceptions.\n\nJavaDoc is typically used to document the public API of a Java library or application, so that other developers can understand how to use the library or application.\n\nHere are some key points about JavaDoc:\n\nIt is a documentation tool for generating API documentation in HTML format from Java source code\n\nIt uses special comments starting with /** and ending with */ in the source code\n\nIt uses tags to specify different types of information about the class, method, or field being documented\n\nIt is typically used to document the public API of a Java library or application\n\nIt is integrated with most of the modern IDEs like Eclipse, IntelliJ, Netbeans etc.\n\nIn summary, JavaDoc is a tool that generates documentation for Java classes, methods, and fields using special comments in the source code. It uses tags to specify\n\ndifferent types of information about the class, method, or field being documented and it is typically used to document the public API of a Java library or application.\n\n```java\n/**\n * This class demonstrates the use of JavaDoc\n *\n * @author liron mizrhai\n */\nclass JavaDoc \n{\n\n    /**\n     * The main method that runs the program\n     * @param args Command line arguments\n     * @return None\n     */\n    public static void main(String[] args)\n    {\n        System.out.println(\"Hello, this is a JavaDoc example!\");\n    }// end of method main\n}// end of class JavaDoc\n```\n\n## 25. ACCESS MODIFIERS\n\n![YouCantDoThatOliverGIF](https://user-images.githubusercontent.com/91504420/213826224-bfa4b9b8-258a-4f8b-81d6-a8fcd281b5a0.gif)\n\nIn Java, access modifiers are keywords used to specify the level of access to a class, method, or variable. The four access modifiers in Java are:\n\npublic: A public class, method, or variable can be accessed from anywhere in the program.\n\nprotected: A protected method or variable can be accessed within the same package or by a subclass in a different package.\ndefault (no keyword): A default class, method, or variable can be accessed within the same package.\n\nprivate: A private method or variable can be accessed only within the same class.\nHere are some key points about access modifiers in Java:\n\nAccess modifiers are used to restrict the level of access to a class, method, or variable.\nThe most restrictive access modifier is private, followed by default, protected, and then public.\n\nThe default access level for a class, method, or variable is package-private.\nClasses and interfaces can only be declared public or default.\n\n\nInner classes can be declared with any access modifier.\nIf a class is declared public, it must be saved in a file with the same name as the class and the file should be in the root of the source code directory.\n\nIn summary, Access modifiers in Java are keywords that specify the level of access to a class, method, or variable. There are four access modifiers: public, protected, default (no keyword), and private. Public members have the least restrictions, while private members have the most.\n\nThe default access level for a class, method, or variable is package-private. Access modifiers are used to restrict the level of access to a class, method, or variable and can be used to ensure encapsulation and information hiding.\n\n![image](https://user-images.githubusercontent.com/91504420/213826653-414b97cc-3b34-41a9-b33f-13a31b7bb919.png)\n\n## 26. OBJECT-ORIENTED-PROGRAMMING\n\n![CalmDownBroChillOutGIF](https://user-images.githubusercontent.com/91504420/213862658-8fda7c88-271a-48dc-9f18-742b5336c8c2.gif)\n\nObject-oriented programming (OOP) is a programming paradigm based on the concept of \"objects\", which can contain data and code that manipulates that data. Java is an object-oriented programming language, which means that it supports OOP concepts such as classes, objects, inheritance, and polymorphism.\n\nA class is a blueprint for creating objects (a particular data structure), providing initial values for state (member variables or attributes), and implementations of behavior (member functions or methods). An object is an instance of a class and can be created using the \"new\" keyword.\n\nInheritance is the mechanism of deriving a new class from an existing one. The new class is known as the derived class or the child class and the class from which the new class is derived is known as the base class or the parent class. This allows for code reuse and a hierarchical class structure.\n\nPolymorphism is the ability of an object to take on many forms. In Java, polymorphism is achieved through method overloading and method overriding. Method overloading allows a class to have multiple methods with the same name but different parameters. Method overriding allows a derived class to provide a specific implementation of a method that is already provided by its base class.\n\nOverall, OOP in Java allows for the creation of reusable and modular code, and a clear structure for organizing and manipulating data.\n\n![image](https://user-images.githubusercontent.com/91504420/213862767-1cb9e705-c3c4-48f6-8f13-ea174a897deb.png)\n\n```java\npublic class Opp\n{\n    // state (attributes)\n    private String name;\n    private int age;\n    \n    // constructor\n    public Opp(String name, int age)\n    {\n        this.name = name;\n        this.age = age;\n    }// end of method Opp\n    \n    // behavior (methods) setters and getters\n    public void setName(String name)\n    {\n        this.name = name;\n    }// end of method setName\n    \n    public String getName()\n    {\n        return name;\n    }// end of method getName \n    \n    public void setAge(int age)\n    {\n        this.age = age;\n    }// end of method setAge\n    \n    public int getAge() {\n        return age;\n    }\n    \n    public void displayInfo()\n    {\n        System.out.println(\"Name: \" + name);\n        System.out.println(\"Age: \" + age);\n    }// end of method displayInfo\n    \n    public static void main(String[] args)\n    {\n        Opp obj = new Opp(\"John Doe\", 30); // creating an object\n        obj.displayInfo(); // calling displayInfo() method\n    }// end of main method \n}// end of class Opp\n```\n\nThis is a simple example of a class named Opp that demonstrates the use of object-oriented programming concepts in Java. The class has two private member variables name and age which are the state of the object. The class has a constructor Opp(String name, int age) that allows the user to set the values of the member variables.\n\nThe class also contains several methods, such as setName(), getName(), setAge(), getAge() and displayInfo() that allow the user to manipulate the state of the object, as well as to display the values of the member variables.\n\nIn the main method, an object of the Opp class is created and passed the value of name and age, then the displayInfo() method is called to display the value of name and age.\n\nThis example demonstrates how OOP concepts can be used to create a class that encapsulates the state and behavior of an object, making it easy to create and manipulate objects of that class.\n\n### 26.1 Inheritance \n\nInheritance is a mechanism in object-oriented programming that allows a new class to inherit the properties and methods of an existing class. This allows for code reuse and a hierarchical class structure in which a derived class can inherit the characteristics of a base class.\n\nIn Java, a class can be derived from another class using the extends keyword. The derived class is also known as a subclass or child class, and the class from which it is derived is known as the superclass or parent class.\n\nFor example, imagine that you have a base class called Animal that has properties like name, age, weight, and methods like eat(), sleep() and move(). And you want to create a new class called Cat which have all the properties and methods of Animal class and also some additional properties and methods like color and sound(). You can create a class Cat by using extends keyword like this:\n\n```java\npublic class Cat extends Animals\n{\n    private String color;\n    public void sound()\n    {\n    \tSystem.out.println(\"Meow!\");\n    }// end of method sound\n}// end of class Cat thet extends Animals \n```\nIn summary, inheritance in Java allows for code reuse, a hierarchical class structure, and polymorphism. It enables the creation of new classes that inherit the properties and methods of existing classes, making it easier to create and manipulate objects of those classes.\n\n### 26.1 Polymorphism\n\nPolymorphism is a concept in object-oriented programming that allows an object to take on many forms. It allows objects of different classes to be treated as objects of a common superclass, enabling them to be used interchangeably. In Java, polymorphism is achieved through method overloading and method overriding.\n\nMethod overloading allows a class to have multiple methods with the same name but different parameters. For example, a class might have two methods with the same name, print(), but one takes an int parameter and the other takes a String parameter.\n\nWhen the print() method is called with an int parameter, the version of the method that takes an int parameter will be called, and when it's called with a String parameter, the version that takes a String parameter will be called.\n\nMethod overriding allows a derived class to provide a specific implementation of a method that is already provided by its base class. This allows objects of the derived class to be used in place of objects of the base class, since they have the same interface.\n\nFor example, if a base class Animal has a method sound() that prints \"generic sound\", a derived class Cat can override the sound() method to print \"Meow!\" instead.\n\nIn summary, polymorphism in Java allows objects of different classes to be treated as objects of a common superclass and to be used interchangeably. It is achieved through method overloading, which allows a class to have multiple methods with the same name but different parameters, and method overriding, which allows a derived class to provide a specific implementation of a method from its base class. This enables the creation of more flexible and reusable code.\n\n```java\nclass Shape\n{\n    public void draw()\n    {\n        System.out.println(\"Drawing a shape\");\n    }// end of draw method \n}// end of class Shape \n\nclass Rectangle extends Shape\n{\n    @Override\n    public void draw() \n    {\n        System.out.println(\"Drawing a rectangle\");\n    }// end of draw method \n}// end of class Rectangle extends Shape \n\nclass Circle extends Shape\n{\n    @Override\n    public void draw()\n    {\n        System.out.println(\"Drawing a circle\");\n    }// end of draw method \n}// end of class Circle that extends Shape \n\npublic class PolymorphismExample \n{\n    public static void main(String[] args) \n    {\n        Shape shape1 = new Shape();\n        Shape shape2 = new Rectangle();\n        Shape shape3 = new Circle();\n        \n        shape1.draw(); // \"Drawing a shape\"\n        shape2.draw(); // \"Drawing a rectangle\"\n        shape3.draw(); // \"Drawing a circle\"\n    }// end of method main\n}// end of method PolymorphismExample \n```\n## 27. ENUM\n\n![AwesomeDealWithItGIF](https://user-images.githubusercontent.com/91504420/213864061-b3059414-f60b-4e34-98e4-578c0cd7caca.gif)\n\nAn enumeration is a special type of class in Java that defines a set of predefined values. Enumerations, also known as enums, are used to represent a fixed set of constants, such as the days of the week or the suits in a deck of cards.\n\nAn enum is declared using the enum keyword, followed by the name of the enumeration and a list of enumeration constants enclosed in curly braces. For example:\n```java\nenum Day\n{\n    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY\n}\n```\n\nThe enumeration constants are automatically given a unique integer value, starting from 0, and can be accessed using the name of the enumeration. For example, Day.MONDAY refers to the enumeration constant MONDAY in the Day enumeration.\n\nEnumerations are useful in situations where a variable can only take on a fixed set of values, as they provide type safety and make the code more readable.\n\nThey also have some additional properties such as ordinal() which returns the index of the enumeration constant, name() which returns the name of the enumeration constant, and compareTo() which compares the enumeration constants based on their ordinal values.\n\nIn summary, enums in Java are special types of classes that define a set of predefined constants. They are useful in situations where a variable can only take on a fixed set of values, as they provide type safety and make the code more readable.\n\nThey also have additional properties such as ordinal(), name() and compareTo() which provide more functionality to work with the enumeration constants.\n\n## 28. CONSTANT\n\n![YouveBeenSoConsistentAleshaDixonGIF](https://user-images.githubusercontent.com/91504420/213864545-3f12d47a-ffb8-4e6d-80b4-448c2c8b6936.gif)\n\nIn Java, a constant is a variable whose value cannot be modified after it is assigned. Constants are often used to represent fixed values that are used throughout a program, such as mathematical constants (e.g. pi), physical constants (e.g. the speed of light), or application-specific constants (e.g. the number of pixels in an image).\n\nThere are two ways to create constants in Java:\n\nUsing the final keyword: A variable can be declared as final by using the final \n\n```java\nfinal int DAYS_IN_WEEK = 7;\n```\n\nUsing static final keyword: A variable can be declared as static final by using both static and final keyword. Once a static final variable is assigned a value, it cannot be reassigned. For example:\n\n```java\nstatic final double PI = 3.14159;\n```\n\nIt is also a common convention to use all uppercase letters and underscores to separate words when naming constants, to make them easy to recognize.\n\nIn summary, constants are variables whose value cannot be modified after it is assigned. They are used to represent fixed values that are used throughout a program. Java provides two ways to create constants: using the final keyword and using static final keyword.\n\nConstants are commonly named with all uppercase letters and underscores to separate words, to make them easy to recognize.\n\n```java\npublic class Constant\n{\n    public static final double PI = 3.14159; // constant\n    public static final int DAYS_IN_WEEK = 7; // constant\n    public static final String NAME = \"John Doe\"; // constant\n\n    public static void main(String[] args)\n    {\n        double radius = 5;\n        double area = PI * radius * radius;\n        System.out.println(\"Area of circle with radius \" + radius + \" is \" + area);\n        System.out.println(\"Number of days in a week is \" + DAYS_IN_WEEK);\n        System.out.println(\"Name is \" + NAME);\n    }// end of main method \n}// end of class Constant\n```\n\n## 29. EXCEPTION HANDLING\n\n![ICanHandleItBillFrazierGIF](https://user-images.githubusercontent.com/91504420/213865427-90f51e8a-d38d-4fac-9248-1d1ffe65c3a0.gif)\n\nException handling is a mechanism in Java that allows a program to handle and recover from errors, known as exceptions, that occur during the execution of the program. Exceptions are events that occur during the execution of a program that disrupt the normal flow of instructions.\n\nWhen an exception occurs, the program generates an object of the class Throwable or one of its subclasses, known as an exception object.\n\nJava provides a built-in mechanism for exception handling, which includes the try-catch statement and the throw statement. The try-catch statement is used to enclose a block of code that might throw an exception. The catch block is used to handle the exception and provide an appropriate response. For example:\n\n```java\ntry \n{\n    // code that might throw an exception\n} \ncatch (ExceptionType e) \n{\n    // code to handle the exception\n}\n```\n\nThe throw statement is used to explicitly throw an exception. It can be used to signal that an abnormal condition has occurred and that the program cannot continue. For example:\n\n```java\nif (input \u003c 0)\n{\n    throw new IllegalArgumentException(\"Input cannot be negative\");\n}\n```\nJava also provides a finally block which is used to execute some code regardless of whether an exception is thrown or not. It is typically used to release resources such as file handles or network connections that were acquired in the try block.\n\nIn summary, exception handling in Java is a mechanism that allows a program to handle and recover from errors that occur during the execution of the program. It includes the try-catch statement, the throw statement and the finally block.\n\nThe try-catch statement is used to enclose a block of code that might throw an exception, the catch block is used to handle the exception and provide an appropriate response, the throw statement is used to explicitly throw an exception and the finally block is used to execute some code regardless of whether an exception is thrown or not, typically used to release resources.\n\n### 29.1 Custom Exception \n\nIn Java, a custom exception is a user-defined exception class that inherits from one of the exception classes provided by the Java standard library. Custom exceptions are used to handle specific error conditions that are not covered by the built-in exception classes. They can be used to provide a more informative error message or to handle the error condition in a specific way.\n\nTo create a custom exception, you need to create a new class that inherits from one of the exception classes provided by the Java standard library, such as Exception, RuntimeException, or IOException. For example, you can create a custom exception class called InvalidAgeException that inherits from Exception:\n\n```java\npublic class InvalidAgeException extends Exception \n{\n    public InvalidAgeException(String message)\n    {\n        super(message);\n    }// end of method InvalidAgeException\n}// end of class InvalidAgeException that extends Exception\n```\n\nThen you can throw the custom exception in your code when a specific error condition occurs, such as an invalid age is passed as an argument:\n\n```java\nif (age \u003c 0) \n{\n    throw new InvalidAgeException(\"Age cannot be negative\");\n}\n```\n\nAnd you can catch the custom exception and handle it accordingly:\n\n```java\ntry \n{\n    // code that might throw InvalidAgeException\n} \ncatch (InvalidAgeException e) \n{\n    \n}\n```\n\n## 30. OBJECT CLASS\n\n![ImJustAProudPapaJohnKrasinskiGIF](https://user-images.githubusercontent.com/91504420/213866367-b26e970f-b4e1-483e-af6f-4802112ab52f.gif)\n\nThe Object class is the root class of all classes in Java. It is the superclass of all other classes and provides a basic set of methods and fields that are inherited by all other classes. The Object class is located in the java.lang package, which is automatically imported into all Java programs, so you don't need to import it explicitly.\n\nThe Object class provides several important methods such as:\n\n + equals(): compares the current object with another object for equality.\n + hashCode(): returns a hash code value for the object.\n + toString(): returns a string representation of the object.\n + getClass(): returns the runtime class of an object.\n + finalize() : method that is invoked before an object is garbage collected.\n \nThe Object class also provides a basic implementation of the clone() method, which creates a new object that is a copy of the current object. However, it's a protected method, so it can be overridden by subclasses to provide a more specific implementation.\n\nIn summary, the Object class is the root class of all classes in Java. It provides a basic set of methods and fields that are inherited by all other classes, including the equals(), hashCode(), toString(), getClass() and finalize() methods. It also provides a basic implementation of the clone() method which creates a new object that is a copy of the current object.\n\n```java\nclass ObjectClass \n{\n    public static void main(String[] args) \n    {\n        // creating two objects of ObjectClass\n        ObjectClass obj1 = new ObjectClass();\n        ObjectClass obj2 = new ObjectClass();\n        \n        // using the equals method of Object class to compare the two objects\n        System.out.println(\"obj1 and obj2 are equal: \" + obj1.equals(obj2));\n        \n        // using the toString method of Object class to return a string representation of the object\n        System.out.println(\"String representation of obj1: \" + obj1.toString());\n        \n        // using the getClass method of Object class to return the runtime class of an object\n        System.out.println(\"Class of obj1: \" + obj1.getClass());\n    }// end of main method \n}// end of class ObjectClass\n```\n\n![image](https://user-images.githubusercontent.com/91504420/213866257-4288f286-7616-483e-bc9f-ea5b6d870491.png)\n\n## 31. TIME COMPLEXITY\n\n![ItsComplicatedAndrewGloubermanGIF](https://user-images.githubusercontent.com/91504420/213870908-d65aef99-44d6-4840-8fed-502b8adff4c5.gif)\n\nTime complexity in Java refers to the amount of time it takes for an algorithm or program to run, usually measured in terms of the size of the input. The most common time complexities in Java are:\n\n+ O(1) or constant time, which means the runtime does not depend on the size of the input\n\n+ O(log n) or logarithmic time, which means the runtime increases logarithmically with the size of the input\n\n+ O(n) or linear time, which means the runtime is directly proportional to the size of the input\n\n+ O(n log n) which means the runtime increases by n log n with the size of the input\n\n+ O(n^2) or quadratic time, which means the runtime increases exponentially with the size of the input.\n\nWhen analyzing and comparing algorithms, it's important to consider the time complexity and choose the one that has the best performance for the specific problem and input size.\n\n![image](https://user-images.githubusercontent.com/91504420/213870960-b8af0063-40aa-46d0-af9c-c5dde01ff884.png)\n\n```java \nclass TimeComplexity\n{\n    public static void main(String[] args)\n    {\n        int[] arr = {1, 2, 3, 4, 5};\n        \n        // O(1) example\n        System.out.println(arr[2]); // constant time, no matter how big the array is, it will always take the same time to access the 3rd element\n        \n        // O(n) example\n        for (int i = 0; i \u003c arr.length; i++) {\n            System.out.print(arr[i] + \" \"); // linear time, the amount of time it takes will increase with the size of the input\n        }\n        \n        // O(n^2) example\n        for (int i = 0; i \u003c arr.length; i++) \n\t{\n            for (int j = 0; j \u003c arr.length; j++) \n\t    {\n                System.out.print(arr[i] + \" \" + arr[j] + \" \"); // quadratic time, the amount of time it takes will increase exponentially with the size of the input\n            }\n        }\n    }// end of main method \n}// end of class TimeComplexity\n```\n\n## 32. SPCAE COMPLEXITY\n\n![ImJustGivingYouYourSpacePrestonHoraceGIF](https://user-images.githubusercontent.com/91504420/213871347-035b736e-8920-448d-a676-1d0614538de6.gif)\n\nSpace complexity in Java refers to the amount of memory used by an algorithm or program, usually measured in terms of the size of the input. The most common space complexities in Java are:\n\n+ O(1) or constant space, which means the memory usage does not depend on the size of the input\n\n+ O(n) or linear space, which means the memory usage is directly proportional to the size of the input\n\n+ O(n^2) or quadratic space, which means the memory usage increases exponentially with the size of the input.\n\nWhen analyzing and comparing algorithms, it's important to consider the space complexity and choose the one that has the best performance for the specific problem and input size. In some situations, using less memory may be more important than using less time, and vice versa.\n\nIt's also worth noting that in addition to the memory usage of the algorithm itself, the memory usage of any data structures used by the algorithm, such as arrays and lists, should also be taken into account.\n\nIt's important to be aware of the space complexity of an algorithm to prevent running out of memory or using too much memory, especially when working with large datasets or when using limited resources such as mobile devices.\n\n![image](https://user-images.githubusercontent.com/91504420/213871399-843a661b-c6ae-43c8-aea5-b3812d318f3b.png)\n\n```java\nclass SpaceComplexity \n{\n    public static void main(String[] args) \n    {\n        int[] arr = {1, 2, 3, 4, 5};\n        \n        // O(1) example\n        int constant = 3; // constant space, the amount of memory used does not depend on the size of the input\n        \n        // O(n) example\n        int[] linear = arr.clone(); // linear space, the amount of memory used is directly proportional to the size of the input\n        \n        // O(n^2) example\n        int[][] quadratic = new int[arr.length][arr.length]; // quadratic space, the amount of memory used increases exponentially with the size of the input\n        for (int i = 0; i \u003c arr.length; i++) \n\t{\n            for (int j = 0; j \u003c arr.length; j++) \n\t    {\n                quadratic[i][j] = arr[i] * arr[j];\n            }\n        }\n    }// end of main method \n}// end of class SpaceComplexity\n```\n\n## 33. QUEUES\n\n![YatoHerzogGIF](https://user-images.githubusercontent.com/91504420/213871781-96d4d448-cf91-452e-be54-5ef12086a7bb.gif)\n\nA queue is a linear data structure in Java that follows the First-In-First-Out (FIFO) principle. It is a collection of elements that are added to the back of the queue and removed from the front of the queue.\n\nThe main operations performed on a queue are enqueue (add an element to the back of the queue) and dequeue (remove an element from the front of the queue).\n\nJava provides a built-in implementation of a queue in the form of the Queue interface and several classes that implement it such as LinkedList, PriorityQueue, ArrayDeque which are all part of the Java Collection Framework.\n\nThe LinkedList class, for example, provides a add() method for adding an element to the back of the queue and a remove() method for removing an element from the front of the queue.\nPriorityQueue is a priority queue, elements are dequeued in order of priority.\nArrayDeque is a resizable array implementation of the Deque interface, it's faster than the linked list implementation.\n\nQueues are used in a variety of applications, such as:\n\n+ simulating real-world scenarios where items are added and removed in a first-in-first-out order, such as a line of customers at a store\n\n+ implementing algorithms that require breadth-first traversal, such as breadth-first search\n\n+ coordination between multiple threads or processes, such as a task queue for a worker thread\n\nIt's worth noting that, Queues are not thread-safe, which means they are not safe to use in a multi-threaded environment without additional synchronization. Java provides thread-safe implementations of queues in the form of ConcurrentLinkedQueue and BlockingQueue classes.\n\n![image](https://user-images.githubusercontent.com/91504420/213871849-fcfb69eb-0be4-459e-877d-459195e210a3.png)\n\n```java\nimport java.util.LinkedList;\nimport java.util.Queue;\n\nclass QueuesExample\n{\n    public static void main(String[] args)\n    {\n        Queue\u003cInteger\u003e queue = new LinkedList\u003c\u003e();\n        \n        // Enqueue elements\n        queue.add(1);\n        queue.add(2);\n        queue.add(3);\n        \n        // Dequeue elements\n        System.out.println(queue.remove()); // output: 1\n        System.out.println(queue.remove()); // output: 2\n        \n        // Check the front element without dequeueing it\n        System.out.println(queue.peek()); // output: 3\n        \n        // Check if the queue is empty\n        System.out.println(queue.isEmpty()); // output: false\n        \n        // Dequeue all remaining elements\n        while (!queue.isEmpty())\n\t{\n            System.out.print(queue.remove() + \" \"); // output: 3\n        }\n    }// end of main method \n}// end of class QueuesExample\n```\n\n## 34. GENERICS\n\n![ImDoingEverythingSalCamposGIF](https://user-images.githubusercontent.com/91504420/213872487-84428854-3373-4d05-95b5-9b8725e8e05f.gif)\n\nGenerics in Java is a feature that allows developers to write reusable, type-safe code. With generics, developers can define a class, interface, or method that can work with multiple types of data, rather than being restricted to a single type. This allows for increased code reusability and eliminates the need for explicit type casting.\n\nTo use generics, developers use angle brackets \u003c \u003e to define a type parameter, which is a placeholder for a specific type that will be provided when the class, interface, or method is instantiated or invoked. For example, a generic class for a stack might be defined as Stack\u003cT\u003e, where T is the type parameter.\n\nGenerics are typically used in collection classes such as List, Set, and Queue to specify the type of objects that they can hold. For example, a List\u003cInteger\u003e is a list of integers, and a List\u003cString\u003e is a list of strings.\n\nIn addition to classes and interfaces, generics can also be used in method declarations. A generic method is a method that has a type parameter, which can be used as the type of its return value or as the type of one or more of its parameters.\n\nFor example, a generic method that swaps the positions of two elements in an array could be defined as follows:\n\n```java\npublic static \u003cT\u003e void swap(T[] array, int i, int j)\n{\n    T temp = array[i];\n    array[i] = array[j];\n    array[j] = temp;\n}// end of method swap\n```\n\nHere, the type parameter T is used to specify the type of the elements in the array, and the method can be used with arrays of any type.\n\nIt's worth mentioning that, Generics were introduced in Java SE 5, it provides a way for creating a single class, interface or method that works with multiple types of data. It eliminates the need for explicit type casting and allows for increased code reusability, type-safety and stronger type checking.\n\n## 35. UNARY OPERATOR\n\n![IOnlyHaveOneJobFreddieBensonGIF](https://user-images.githubusercontent.com/91504420/213872915-d3290edb-50b8-4e4c-bc4a-09852c21ad96.gif)\n\nA unary operator in Java is an operator that performs an operation on a single operand. The operand can be a variable, a constant, or an expression. There are several types of unary operators in Java:\n\nArithmetic unary operators: These operators perform arithmetic operations on a single operand. The most common arithmetic unary operators are + and -. For example, -x negates the value of x and +x returns the value of x.\n\nIncrement and decrement operators: These operators increment or decrement the value of a variable by 1. The increment operator (++) adds 1 to the variable, and the decrement operator (--) subtracts 1 from the variable. The increment and decrement operators can be used in both prefix and postfix notation.\n\nLogical unary operators: These operators perform logical operations on a single operand. The most common logical unary operator is the negation operator (!). For example, !true returns false.\n\nBitwise unary operator: These operators perform bitwise operations on a single operand, the most common bitwise unary operator is the bitwise complement operator (~) which inverts all the bits of the operand.\n\n```java\nclass UnaryOperator\n{\n    public static void main(String[] args)\n    {\n        int x = 5;\n        int y = -10;\n        \n        // Arithmetic unary operator\n        System.out.println(-x); // output: -5\n        System.out.println(+y); // output: -10\n        \n        // Increment and decrement operator\n        int z = 0;\n        System.out.println(++z); // output: 1\n        System.out.println(z++); // output: 1\n        System.out.println(z); // output: 2\n        \n        // Logical unary operator\n        boolean flag = true;\n        System.out.println(!flag); // output: false\n        \n        // Bitwise unary operator\n        int a = 10;\n        System.out.println(~a); // output: -11\n        \n        // Typecasting unary operator\n        double pi = 3.14;\n        int intPi = (int) pi;\n        System.out.println(intPi); // output: 3\n    }// end of method main \n}// end of class UnaryOperator\n```\n\nTypecasting unary operator: The unary operator () can be used to cast the operand to a different type.\n\nIt's worth noting that, the unary operator can be used before or after the operand, depending on the operator, the position of the operator can affect the value of the expression. The increment and decrement operators, for example, behave differently when used in prefix notation (++x) versus postfix notation (x++).\n\n## 36. HASHMAP\n\n![MicDropImOutGIF](https://user-images.githubusercontent.com/91504420/214188452-130c542a-db55-46c7-90e8-f9707067dd29.gif)\n\nA HashMap in Java is a data structure that stores key-value pairs and uses a hash function to map keys to their corresponding values.\n\nIt allows for fast lookups, insertions, and deletions of elements by key. It is implemented using an array and a linked list, where each element in the array is a linked list of key-value pairs that share the same hash code. \n\nThe HashMap is part of the Java Collections Framework and is not thread-safe by default, but it can be made thread-safe by using the java.util.Collections.synchronizedMap() method.\n\n![image](https://user-images.githubusercontent.com/91504420/214188096-ca9c97b4-21d1-45f9-8370-5e1d4e200281.png)\n\n```java\nimport java.util.HashMap;\n\npublic class HashMapExample\n{\n    public static void main(String[] args) \n    {\n\n        // Create a new HashMap object\n        HashMap\u003cString, Integer\u003e map = new HashMap\u003c\u003e();\n\n        // Add key-value pairs to the map\n        map.put(\"Apple\", 1);\n        map.put(\"Banana\", 2);\n        map.put(\"Cherry\", 3);\n\n        // Print the entire map\n        System.out.println(\"Original map: \" + map);\n\n        // Get the value for a specific key\n        int value = map.get(\"Banana\");\n        System.out.println(\"Value for key 'Banana': \" + value);\n\n        // Check if a key is in the map\n        boolean containsKey = map.containsKey(\"Apple\");\n        System.out.println(\"Map contains key 'Apple': \" + containsKey);\n\n        // Check if a value is in the map\n        boolean containsValue = map.containsValue(3);\n        System.out.println(\"Map contains value 3: \" + containsValue);\n\n        // Remove a key-value pair from the map\n        map.remove(\"Cherry\");\n        System.out.println(\"Map after removing key 'Cherry': \" + map);\n\n        // Clear the entire map\n        map.clear();\n        System.out.println(\"Map after clear: \" + map);\n    }// end of method main\n}// end of class HashMapExample\n```\n\nthe output:\n\n+ Original map: {Apple=1, Banana=2, Cherry=3}\n\n+ Value for key 'Banana': 2\n\n+ Map contains key 'Apple': true\n\n+ Map contains value 3: true\n\n+ Map after removing key 'Cherry': {Apple=1, Banana=2}\n\n+ Map after clear: {}\n\n## 37. HASHTABLE\n\n![JerbearMehGIF](https://user-images.githubusercontent.com/91504420/214191343-8b16bad6-56ef-4411-969e-36ba77655955.gif)\n\nA Hashtable in Java is a data structure that stores key-value pairs and uses a hash function to map keys to their corresponding values.\n\nIt is similar to a HashMap, but it is synchronized, meaning that only one thread can access the Hashtable at a time. This makes Hashtable a thread-safe alternative to HashMap.\n\nThe Hashtable class is part of the original Java version 1.0, and it does not allow null keys or null values. The method used to access elements in a Hashtable is Enumeration.\n\n![image](https://user-images.githubusercontent.com/91504420/214191224-811b8d63-8938-48ee-b7f6-2af824669643.png)\n\n```java\nimport java.util.Enumeration;\nimport java.util.Hashtable;\n\npublic class HashTableExample\n{\n    public static void main(String[] args)\n    {\n        \n        // Create a new HashTable object\n        Hashtable\u003cString, Integer\u003e table = new Hashtable\u003c\u003e();\n\n        // Add key-value pairs to the table\n        table.put(\"Apple\", 1);\n        table.put(\"Banana\", 2);\n        table.put(\"Cherry\", 3);\n\n        // Print the entire table\n        System.out.println(\"Original table: \" + table);\n\n        // Get the value for a specific key\n        int value = table.get(\"Banana\");\n        System.out.println(\"Value for key 'Banana': \" + value);\n\n        // Check if a key is in the table\n        boolean containsKey = table.containsKey(\"Apple\");\n        System.out.println(\"Table contains key 'Apple': \" + containsKey);\n\n        // Check if a value is in the table\n        boolean containsValue = table.containsValue(3);\n        System.out.println(\"Table contains value 3: \" + containsValue);\n\n        // Remove a key-value pair from the table\n        table.remove(\"Cherry\");\n        System.out.println(\"Table after removing key 'Cherry': \" + table);\n        \n        // Iterating over the key-value pairs\n        Enumeration\u003cString\u003e keys = table.keys();\n        while (keys.hasMoreElements())\n\t{\n            String key = keys.nextElement();\n            Integer val = table.get(key);\n            System.out.println(\"Key: \" + key + \" Value: \" + val);\n        }// end of while\n    }// end of method main\n}// end of class HashTableExample\n```\n\noutput : \n\n+ Original table: {Apple=1, Banana=2, Cherry=3}\n\n+ Value for key 'Banana': 2\n\n+ Table contains key 'Apple': true\n\n+ Table contains value 3: true\n\n+ Table after removing key 'Cherry': {Apple=1, Banana=2}\n\n+ Key: Apple Value: 1\n\n+ Key: Banana Value: 2\n\n## 38. HASHSET\n\n![WhatAreYouTalkingAboutHuhGIF](https://user-images.githubusercontent.com/91504420/214484061-fe6990bc-3d23-4f97-ae3d-d243109e3a47.gif)\n\nA HashSet in Java is a collection that stores unique elements in no particular order. It is implemented using a hash table, which provides fast access to elements for operations such as adding, removing, and checking if an element is contained in the set.\n\nHashSet does not guarantee any specific order of the elements.\n\nIt is useful for cases where you need to quickly check if an element is present in a set, or remove an element from a set. HashSet does not allow duplicate elements.\n\n```java\nimport java.util.HashSet;\n\npublic class HashSetExample\n{\n    public static void main(String[] args)\n    {\n        // Create a new HashSet\n        HashSet\u003cString\u003e set = new HashSet\u003c\u003e();\n        \n        // Add elements to the HashSet\n        set.add(\"Apple\");\n        set.add(\"Banana\");\n        set.add(\"Cherry\");\n        \n        // Attempt to add a duplicate element\n        set.add(\"Apple\");\n        \n        // Check the size of the HashSet\n        System.out.println(\"Size of HashSet: \" + set.size()); // Output: Size of HashSet: 3\n        \n        // Check if an element is present in the HashSet\n        System.out.println(\"Is Orange in HashSet: \" + set.contains(\"Orange\")); // Output: Is Orange in HashSet: false\n        \n        // Remove an element from the HashSet\n        set.remove(\"Banana\");\n        \n        // Iterate through the HashSet and print the elements\n        for (String fruit : set)\n\t{\n            System.out.println(fruit);\n        }\n    }// end of main method \n}// end of class HashSetExample\n```\n\n## 39. POSTFIX AND PREFIX\n\n![ImBetterGIF](https://user-images.githubusercontent.com/91504420/214485704-6f869310-227f-4ca0-a61c-27ee7c89390a.gif)\n\nIn Java, the postfix and prefix operators are used to increment or decrement a variable by a certain amount.\n\nThe postfix operator (e.g. i++) increments the variable after it has been used in the expression, while the prefix operator (e.g. ++i) increments the variable before it has been used in the expression.\n\nFor example, consider the following code:\n\n```java\nint i = 5;\nint j = i++;\n```\n\nIn this case, the value of j will be set to 5, and then the value of i will be incremented to 6.\n\nOn the other hand, consider the following code:\n\n```java\nint i = 5;\nint j = ++i;\n```\n\nIn this case, the value of i will be incremented to 6, and then the value of j will be set to 6.\n\nIn summary, postfix and prefix operators in Java are used to increment or decrement a variable before or after it is used in the expression.\n\nThe prefix operator is more efficient than postfix operator and the choice of which one to use depends on the specific use case and the desired behavior of the program.\n\n## 40. TERNARY OPERATOR\n\n![PrettyCoolTrickHuhCatraGIF](https://user-images.githubusercontent.com/91504420/214486360-d768c930-8700-4aab-a842-4c3e88abd257.gif)\n\nThe ternary operator in Java is a shorthand way of writing an if-else statement. It has the following syntax:\n\n```java\ncondition ? expression1 : expression2\n```\n\nThe ternary operator takes a condition as its first parameter, followed by a question mark (?), and then two expressions separated by a colon (:). If the condition is true, the operator returns the first expression; otherwise, it returns the second expression.\n\nHere's an example:\n\n```java\nint x = 5;\nint y = 10;\nint max = (x \u003e y) ? x : y;\n```\n\nIn this example, the ternary operator compares the values of x and y, and assigns the larger value to the max variable. This is equivalent to the following if-else statement:\n\n```java\nint max;\nif (x \u003e y) \n{\n    max = x;\n} \nelse \n{\n    max = y;\n}\n```\nIn short, the Ternary operator is a shorthand way of writing if-else statements and it's much more concise. It's useful when you have to return a value based on a boolean condition and it's easy to read when the expressions are simple and short.\n\n## 41. ABSTRACT CLASS\n\t\n![BoBurnhamInsideGIF](https://user-images.githubusercontent.com/91504420/214487565-b883fcd1-e609-442b-bbb2-d0455c1a5032.gif)\n\t\nAn abstract class in Java is a class that cannot be instantiated but can have abstract and concrete methods. An abstract method is a method that has a method signature but no implementation. Concrete methods are methods that have a method signature and an implementation.\n\nAn abstract class can also have constructors and fields, but it cannot be used to create objects. It is meant to be subclassed, with the subclasses providing the implementation for the abstract methods.\n\nA class that contains at least one abstract method must be declared as abstract. Subclasses of an abstract class must provide an implementation for all of its abstract methods.\n\nHere's an example of an abstract class:\n\n```java\nabstract class Shape \n{\n    // Fields\n    private String color;\n    \n    // Constructor\n    public Shape(String color)\n    {\n        this.color = color;\n    }\n    \n    // Abstract method\n    public abstract double getArea();\n    \n    // Concrete method\n    public String getColor()\n    {\n        return color;\n    }\n}// end of abstract class Shape\n```\n\nIn this example, the Shape class is an abstract class that cannot be instantiated. It has a constructor, a field, an abstract method (getArea) which does not have implementation and a concrete method (getColor) which have implementation.\n\t\nSubclasses such as Circle and Rectangle would need to provide an implementation for the getArea method.\n\nIn summary, an abstract class is a class that cannot be instantiated and contains abstract and concrete methods, fields and constructors. The abstract methods are meant to be overridden by subclasses and provide a common interface for all subclasses.\n\t\n## 42. INTERFACE\n\n![NextLevelQuoteGIF](https://user-images.githubusercontent.com/91504420/214488973-5cf6ef61-306a-4256-a976-6d6ea51f0f48.gif)\n\nIn Java, an interface is a collection of abstract methods (methods without a body) and constant fields (static final variables). It defines a contract that classes must adhere to, specifying a set of methods that a class must implement.\n\nA class can implement multiple interfaces. When a class implements an interface, it must provide an implementation for all of the interface's methods.\n\nHere is an example of an interface:\n\n```java\ninterface Shape\n{\n    double getArea();\n    double getPerimeter();\n}// end of interface Shape\n```\n\nIn this example, the Shape interface defines two abstract methods, getArea and getPerimeter, that classes implementing this interface must provide an implementation for.\n\nHere's an example of a class that implements the Shape interface:\n\n```java\nclass Circle implements Shape\n{\n    private double radius;\n    public Circle(double radius)\n    {\n        this.radius = radius;\n    }// end of method Circle\n    public double getArea()\n    {\n        return Math.PI * radius * radius;\n    }// end of method getArea\n    public double getPerimeter()\n    {\n        return 2 * Math.PI * radius;\n    }// end of method getPerimeter\n}// end of class Circle\n```\n\n## 43. ANONYMOUS INNER CLASS\n\n![AnonymousThanksGIF](https://user-images.githubusercontent.com/91504420/214593103-48b11367-407d-48a8-87bb-71210a43c81b.gif)\n\nAn anonymous inner class in Java is a class without a name that is defined and instantiated in a single expression. It is typically used as an implementation of a functional interface, such as a listener or callback, and is defined and instantiated at the point of use.\n\nAnonymous inner classes are useful for creating small, one-time-use classes, and can be more concise than defining a named inner class.\n\n```java\npublic class AnonymousInnerClass\n{\n    public static void main(String[] args)\n    {\n        // Create an instance of an anonymous inner class that implements Runnable\n        Runnable runnable = new Runnable()\n\t{\n            @Override\n            public void run()\n\t    {\n                System.out.println(\"Running from anonymous inner class\");\n            }\n        };\n        \n        // Run the anonymous inner class\n        new Thread(runnable).start();\n    }// end of method main\n}// end of class AnonymousInnerClass\n```\n\n## 44. OPTIONAL\n\n![IGotOptionsKassandraLeeGIF](https://user-images.githubusercontent.com/91504420/214593201-8c187305-47b0-4359-a9b6-036ac98b1492.gif)\n\nIn Java, Optional is a container object which is used to contain a value that may be null or non-null. The purpose of the Optional class is to provide a type-level solution for representing optional values instead of using null references.\n\nIt has several methods to check the presence of a value, to retrieve a value, or to perform an action on the value if it's present.\n\n\nIt is introduced in Java 8, and it is a part of the java.util package. Optional class can be used as an alternative to null checks and provide a way to handle null values in a more elegant way.\n\nYou can create an Optional instance by calling the of() or ofNullable() method. Once an Optional instance is created, you can use the isPresent() method to check if it contains a value, and the get() method to retrieve the value.\n\nYou can also use the orElse() method to provide a default value if the Optional is empty or use orElseGet() and orElseThrow() to handle the case where the Optional is empty.\n\n```java\nimport java.util.Optional;\n\npublic class OptionalExample\n{\n    public static void main(String[] args)\n    {\n        // Create an Optional instance that contains a value\n        Optional\u003cString\u003e optionalString = Optional.of(\"Hello, Optional!\");\n\n        // Use the isPresent() method to check if the Optional contains a value\n        if (optionalString.isPresent())\n\t{\n            // Use the get() method to retrieve the value from the Optional\n            System.out.println(optionalString.get());\n        }\n\n        // Create an Optional instance that does not contain a value\n        Optional\u003cString\u003e emptyOptional = Optional.empty();\n\n        // Use the orElse() method to provide a default value if the Optional is empty\n        System.out.println(emptyOptional.orElse(\"Default value\"));\n\n        // Use the orElseGet() method to provide a default value using a Supplier\n        System.out.println(emptyOptional.orElseGet(() -\u003e \"Default value from supplier\"));\n\n        // Use the orElseThrow() method to throw an exception if the Optional is empty\n        try \n\t{\n            emptyOptional.orElseThrow(IllegalArgumentException::new);\n        } \n\tcatch (Exception e) \n\t{\n            System.out.println(\"Caught exception: \" + e.getMessage());\n        }\n\n        // Use the ifPresent() method to perform an action if the Optional contains a value\n        optionalString.ifPresent(System.out::println);\n    }// end of method main\n}// end of class OptionalExample\n```\n\n## 45. LAMBDA EXPRESSION\n\n![Uploading ItsWayMoreAdvancedUnmeshDindaGIF.gif…]()\n\nLambda expressions are a feature introduced in Java 8 that allow for functional programming and more concise code. They are often used to implement functional interfaces, which are interfaces with a single abstract method.\n\nThe basic syntax of a lambda expression is as follows:\n\n```java\n(parameters) -\u003e {body}\n```\n\nFor example: \n\n```java\n(int x, int y) -\u003e x + y\n```\n\n+ Lambda expressions can be used to replace anonymous inner classes in situations where a functional interface is expected.\n+ Lambda expressions can be used to sort collections using the sort() method, by passing a comparator as an argument.\n+ Lambda expressions can be used to pass behavior as an argument to a method, such as with the forEach() method of the Stream API.\n+ Lambda expressions can be used to filter collections using the filter() method of the Stream API.\n+ Lambda expressions can be used to transform collections using the map() method of the Stream API.\n+ Lambda expressions can be used to perform aggregate operations on collections using the reduce() method of the Stream API.\n\nExample: \n\n```java\nList\u003cPerson\u003e people = new ArrayList\u003c\u003e();\npeople.add(new Person(\"Bob\", 25));\npeople.add(new Person(\"Alice\", 30));\npeople.add(new Person(\"Charlie\", 20));\n\npeople.sort((p1, p2) -\u003e p1.name.compareTo(p2.name));\n```\n\nIn the above example, we are using lambda expression to sort the people list based on name of the person.\n\nIn general, lambda expressions provide a more concise and readable way to express behavior in Java and are often used in functional programming.\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flironmiz%2Fcomputer-science-in-java","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flironmiz%2Fcomputer-science-in-java","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flironmiz%2Fcomputer-science-in-java/lists"}