Core Java / Java Theory
Published: 2021-05-27 16:02:23

Theory stuff about Java 

Content here is **not original**. It is my summary of the following resources 
References:
This [medium post by Edureka](https://medium.com/edureka/java-oop-cheat-sheet-9c6ebb5e1175) (along with other articles in the series) are insanely good  

in28Minutes github - this is a great resource for interview prep. (<small> However do double check with other sources. I find their explanation of encapsulation & unchecked VS checked exception strange </small>)

Other good resources:

[javarevisited](https://javarevisited.blogspot.com/2013/08/10-equals-and-hashcode-interview.html) is a very good resource for in-depth questions. It's good for harder / obscure questions and makes your understanding clearer by doing a deep dive. 

https://www.edureka.co/blog/interview-questions/oops-interview-questions/

Quick Summaries of OOP:
https://blog.udemy.com/oops-interview-questions/
https://blog.udemy.com/oop-interview-questions/

#TOC
####Java Stuff
- Language
  - [statically typed](#statically-typed)
  - [class-based](#class-based)
  - [object-oriented programming](#object-oriented-programming-definition)
  - [not pure OOP](#java-not-pure-oop)
- Execution System
  - [platform independence](#java-platform-independent)
  - [JVM, JDK, JRE](#java-jvm-jre-jdk)
  - [Just-In-Time Compilation](#java-jit-compilation)
  - [Memory Management](#memory-management-in-java)
    - [java heap space VS stack memory](#java-heap-space-vs-stack-memory)
    - [garbage collection](#java-garbage-collection)
  - [comparison to Python](#java-comparison-to-python)

####Java syntax
- Basics
  - [Objects & classes](#objects-&-classes)
  - [Variables & methods](#variables-&-methods)
  - [method signature](#method-signature)
  - [Packages](#packages)
- Modifiers (Access & Non-access modifiers)
    - [access modifiers](#access-modifiers)
- Non access modifiers
    - [abstract keyword](#abstract-keyword)
        - [illegal modifiers with abstract](#abstract-illegal-modifier)
  - [final-keyword](#final-keyword)
  - [static-keyword](#static-keyword)

####block
  -[static VS instance block](#static-vs-instance-block)

####Wrapper Class
  - [immutable](#wrapper-class-immutable)
  - [why wrapper classes](#why-wrapper-classes)
  - [constructor VS valueOf](#constructor-vs-valueOf)
  - [Autoboxing & Unboxing](#autoboxing-and-unboxing)
      - [autoboxing unboxing advantages](#autoboxing-advantages)
  - [Typecasting](#typecasting-implicit-explicit)
      - implicit/widening
      - explicit/narrowing

####Strings
  - [Implements CharSequence Interface](https://www.javatpoint.com/java-string#:~:text=interfaces-,CharSequence%20Interface,The,-CharSequence)
  - [immutability](#strings-immutability)
  - [where are strings stored in memory](#string-store-where-in-memory)
      - [String pool](#java-string-pool)
      - heap & stack 
  - [String Interning](#java-string-interning)
  - [how many objects created in new String()](#objects-created-in-String-construction)
  - [String (+) is bad in loop](#never-+-string-in-loop)
  - [String VS StringBuffer](#string-vs-stringbuffer)
  - [StringBuilder VS StringBuffer](#StringBuilder-vs-StringBuffer)

####Objects class / Java Objects basics
- [What is a class](#java-what-is-a-class)
    - state
    - behaviour
- [What is an object](#java-what-is-a-object)
- [== VS equals()](#==-VS-equals)
- [super class of every class](#super-class-of-every-class)
- [toString metho](#java-object-toString-method)
- [equals() method](#java-object-equals()-method)
  - [equals() method critera](#equals()-method-criteria)
- [hashCode() method](#java-object-hashCode()-method)
  - [hashCode() method criteria](#hashCode()-method-criteria)
- [importance of equals() & hashCode()](#equals()-&-hashCode()-importance)
- instanceOf VS getClass
- [Object class Inheritance](#java-objects-inheritance)
- [constructors]

####Data Structure Implementations(<small> knpcode.com has really good tutorials and  write ups for DS implementations </small>)
- HashMap
  - [how hashmap works internally](#how-hashmap-works-internally)
      - 16 initial buckets, 0.75 load factor, threshold of 12
      - hashCode for bucket index calculation
      - LinkedList for collision
      - equals() to compare keys
      - rehashing when meet threshold, buckets are doubled 
  - [null key added](#null-key-added-to-hashmap)
- HashSet
  - [hashset internal implementation in Java](#hashset-internal-implementation-in-java)
      - implemented with hashmap
      - set element are hashmap keys
      - all hashmap values are a dummy object.  
- ArrayList
  - [capacity VS size](#arraylist-capacity-vs-size)
  - [how arraylist works internally](#how-arraylist-works-internally)
      - implemented with array
      - initial capacity of 10 
      - grows 50% when no space
- Vector
  - [Java vector class](#java-vector-class)
      - thread safe arraylist
- Stack
  - [how is stack implemented by java](#how-stack-implemented-by-java)
      - empty on creation
      - dynamic array *NOT linkedlist*
- Queue
  - [queue implementations in Java](#queue-implementations-in-java)
      - interface not a class
      - implemented by PriorityQueue & LinkedList

####Java Implementations / Interfaces / Common Classes (<small> will only go through [general-purpose implementations](https://docs.oracle.com/javase/tutorial/collections/implementations/index.html) coz no time </small>) 
- [Map Implementations](#hashmap-treemap-linkedhashmap)
  - HashMap
  - TreeMap
  - LinkedHashMap
- [Set Implementations](#hashset-treeset-linkedhashset)
  - HashSet
  - TreeSet
  - LinkedHashSet
- [List Implementations](#arraylist-linkedlist-java)
  - ArrayList
  - LinkedList
- Queue Implementations (see above)
  - PriorityQueue
  - LinkedList
- Dequeue Implementations (double-ended queue) (<small> going to skip this </small>)
  - LinkedList
  - ArrayDequeue

####OOP Concepts & OOP in Java(<small> references in this section mainly from educative articles: [OOP](https://www.educative.io/blog/object-oriented-programming#what-is) & [OOP in Java](https://www.educative.io/blog/object-oriented-programming-concepts-java)</small>
- [What is OOP](#what-is-oop)
- 4 Pillars of OOP
  - [inheritance](#oop-inheritance)
      - [Types of Inheritance](#types-of-inheritance)
      - single inheritance
      - multilevel
      - multiple
      - hierarchical
      - hybrid
      - [inheritance-in-java](#inheritance-in-java-oop)
        - [extends VS implements](#extends-vs-implements)
  - [Abstraction](#oop-abstraction)
      - [abstraction in java](#oop-abstraction-in-java)
      - [abstract class VS interface](#oop-abstract-class-vs-interface)
  - [Encapsulation](#oop-encapsulation)
      - [encapsulation in java](#oop-encapsulation-in-java)
          - getters & setters 
          - [tight encapsulation](#java-tight-encapsulation)
  - [Polymorphism](#oop-polymorphism)
      - compile time VS runtime
      - [method overloading](#polymorphism-method-overloading)  
      - [method overloading conditions](#method-overloading-conditions)
      - [method overriding](#polymorphism-method-overriding)
      - [method overriding rules](#method-overriding-rules)
          - [overriding VS hiding (static methods)](#overriding-vs-hiding) 
- Abstraction VS Encapsulation (https://stackoverflow.com/a/51304341)
- Relationships (https://www.c-sharpcorner.com/UploadFile/3614a6/is-a-and-has-a-relationship-in-java/)
  - IS-A relationship (inheritance)
  - HAS-A relationship (composition)
- Other concepts
  - [Association](#oop-association-java)
      - association (2 classes have a link, need to communicate between them)
      - aggregation (weak association, child can exist independently of the parent)
      - composition (strong association, child cannot exist independent of parent)
  - [association VS aggregation VS composition](https://stackoverflow.com/a/10394722)
  - [Coupling](#oop-coupling-java)
  - [Cohesion](#oop-cohesion-java)

####Java Exception Handling (<small>[JournalDev Exception Handling article](https://www.journaldev.com/1696/exception-handling-in-java) primarily used as reference for this section </small>)
- [runtime exceptions](#runtime-exception)
- [exception handling keyword](#exception-handling-keyword)
  - try
  - catch
  - finally
- [Java Exception Hierarchy](#java-exception-hierarchy)
  - [Unchecked VS Runtime Exception](#java-unchecked-vs-runtime-exception)
- [Exception Class Methods](#java-exception-class-methods)
- [Excpetion Handling criteria](#java-exception-handling-criteria)
- [Exception Handling Best Practice](#java-exception-handling-best-practice)

####OOP Concepts 
- SOLID (https://www.baeldung.com/solid-principles)
 - single responsibility
 - openfor extension closed to modfication
 - lishov subsitution (sub subclass for base class)
 - interface segregation (split big interface itno smaller ones)
 - dependency inversion (depend on abstract classes/ interfaces instead of classes)

####UML
- needed to understand different design patterns
- [Class Diagram](#uml-class-diagram)
  - Association
  - inheritance / generalization / abstraction
  - multiplicty
- [Sequence Diagram](#uml-sequence-diagram)



####[Design Patterns](#oop-design-patterns)

- Creational
  - [singleton](#singleton-design-pattern)
  - [factory & abstract factory](#factory-design-pattern)
  - Builder
- Structural
  - [decorator](#decorator-desgin-pattern)
  - [flyweight](#flyweight-design-pattern)
  - [adapter](#adapter-design-pattern)
- Behavioural 
  - [observer](#observer-design-pattern) 
  - [strategy](#strategy-design-pattern)
  - [state](#state-design-pattern)


MultiThreading
- thread VS process
- Threads & Runnable
- Thread VS Runnable
- keywords
  - synchronized
  - volatile
  - wait() 
  - notify()
  - notifyAll()
https://howtodoinjava.com/java/multi-threading/wait-notify-and-notifyall-methods/
https://dzone.com/articles/difference-between-volatile-and-synchronized-keywo
https://stackoverflow.com/a/3519736
https://howtodoinjava.com/java/multi-threading/java-runnable-vs-thread/
https://stackoverflow.com/a/15471504



### <a name="statically-typed">Statically Typed</a>
Reference: [Oracle Documentation](https://docs.oracle.com/cd/E57471_01/bigData.100/extensions_bdd/src/cext_transform_typing.html)

- **perform type checking at compile time**
  - provides *type safety*
  - if Java code contains errors, it will fail to compile until the errors have been fixed
- **declare data types of variables before you use them**
  - `int num; num = 5;` VS `num =5`
  - expects variables to be declared before it can be assigned value. 

   
Opposite of statically typed is **dynamically-typed** (eg. python)

### <a name="class-based">Class based</a>
Reference: [mozilla developer docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model) & [stack overflow](https://stackoverflow.com/a/11620705) & [zendesk](https://li60.zendesk.com/hc/en-us/articles/115002448751-Class-based-vs-prototype-based-languages) & [wikipedia](https://en.wikipedia.org/wiki/Class-based_programming)

> Class based programming / class-orientation is a style of Object-oriented programming (OOP)
<u>Class-based</u>: makes distinction between objects & class.
<u>prototype-based</u>: no distinction. It has objects. start with an instance / object & modify it. 

- Defining class
  - define class in class definition & specify methods (constructors) to create instances of the class.
  - <u> prototype </u>: class definition not separate from constructor. constructor function creates object with initial set of properties & values
- Subclass / inheritance
  - create heirachy via class definition `Manager extends Employee`
  - <u>prototype</u>: associate object with any construtor function. (call another object in the constructor function of subclass)
- Adding & removing properties
  - cannot change type / number of properties after class definition
  - class created at compile time & objects instantiated at compile or run time
  - <u>prototype</u>: ca remove or add properties of any object at run time. 

Opposite of class based is **protoype-based / object-based** (eg. javascript)
###<a name="object-oriented-programming-definition">What is Object-oriented programming</a>

Reference: [wiki](https://en.wikipedia.org/wiki/Object-oriented_programming) & [educative](https://www.educative.io/blog/object-oriented-programming) & [educative - Oop JS](https://www.educative.io/courses/learn-object-oriented-programming-in-javascript/B19oGJg5JWo)

> OOP is a *programming paradigm* based on the concept of "objects".
Program is broken down  into segments of *objects* that communicate with each other.
Each objct is define by:
- its functions (called **methods**)
- its data (called **properties**)


This is a general overview of OOP. as seen in previous section that are also different "styles" of OOP (object-based & class-based).

From some articles we can also see the question "Is <language> a OOP langauge?" is not a straight forward yes or no answer. 

To be OOP language, programming language has to satisfy a list of OOP condition / properties. Depending on whether programming language has satisfied some / all OOP conditions we can then say "yes" or "no". 
Even if the answer is "yes" programming language is OO. There is still the question of "is <language> *purely* object-oriented?"

<u> Alternatives / Opposite </u>
There is no "opposite" of object -oriented proramming. But there are different programming paradigms like: (reference: [SO](https://stackoverflow.com/a/6295260))
- procedural
- fuctional
etc.

###<a name="java-not-pure-oop">Java not pure OOP</a>
Reference: [GeeksforGeeks](https://www.geeksforgeeks.org/java-not-purely-object-oriented-language/) & [dataflair](https://data-flair.training/blogs/is-java-an-object-oriented-language/)

> Java is **not a pure object-oriented language**. Because it has:
1. primitive data type
2. static keyword
3. wrapper class

To fulfill pure OOP, language must satisfy all 7 conditions:
1. Encapsulation / Data Hiding
2. inheritance
3. polymorphism
4. abstraction
5. All predefined types are objects
6. All user defined types are objects
7. All operations performed on objects must be only through methods exposed at objects

> Java fails condition 5(*all predefined types are objects*) & 7(*operations performed on objects must be only through methods exposed at objects*)

- primitive data types
  - primitives are [not objects](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html#:~:text=new%20keyword%20isn't%20used%20when%20initializing%20a%20variable%20of%20a%20primitive%20type.%20primitive%20types%20are%20special%20data%20types%20built%20into%20the%20language%3B%20they%20are%20not%20objects%20created%20from%20a%20class)
- static keyword
  - when class is static, it can be used without objects
  - static function / variables. can be called without creating an object of class.
- Wrapper class
  - unboxing: when using arithemtic operators (% or +=) are performed on wrapper classes. compiler [converts object to primitive datatype](https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html#:~:text=remainder%20(%25)%20and%20unary%20plus%20(%2B%3D)%20operators%20do%20not%20apply%20to%20integer%20objects%2C%20you%20may%20wonder%20why%20the%20java%20compiler%20compiles%20the%20method%20without%20issuing%20any%20errors.%20the%20compiler%20does%20not%20generate%20an%20error%20because%20it%20invokes%20the%20intvalue%20method%20to%20convert%20an%20integer%20to%20an%20int%20at%20runtime%3A) at runtime. Thus violating condition 5 (primitive types are not objects) 
  - arithmetic operations on object `String test = "hello" + " world"` use of arithmetic operations on wrapper class also violate condition 7 (can communicate with objects with calling their methods)


###<a name="java-platform-independent">Java platform Independent</a>
> Java is WORA (Write once Run anywhere). java source code can run on all operating systems. 
byte code (.class) generated by javac compiler can be executed on any OS. Bytecode is understandable is any JVM installed on any OS. 

**JAVA is platform-independent language, the JVM is platform-dependent.**
must install different JVM for different OS.

JVM will convert bytecode (.class) to machine code
Since machine code is run, this makes run time faster. 

<small> Reference: [javatpoint](https://www.javatpoint.com/features-of-java) & [codingningjas](https://www.codingninjas.com/blog/2020/10/26/how-is-java-platform-independent/) & [guru99](https://www.guru99.com/java-platform.html#14) </small>

###<a name="java-jvm-jre-jdk">Java: JVM, JRE, JDK</a>

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2ibjak3ccfhcwfpglabx.png)
> **JDK**: Java development Kit
software development environment used for making applets & Java applications. 
- JRE + compiler + debugger 
**JRE**: Java Runtime Environment
software designed to run other software.  To **run Java** you **need JRE**. It contains class libraries, loader class & JVM. 
- JVM + libraries + other components (to run applets / java applications) 
**JVM**: 
- Virtual machine running java bytecode
- maeks java portable 
- comes with JIT(Just-In-Time) compiler that converts java source code to low-level machine langauge. 

 
<small> Reference: [guru99](https://www.guru99.com/difference-between-jdk-jre-jvm.html#13) & [javatpoint](https://www.javatpoint.com/difference-between-jdk-jre-and-jvm) & [geeksforgeeks](https://www.geeksforgeeks.org/differences-jdk-jre-jvm/) </small>

###<a name="java-jit-compilation">Java JIT Compilation</a>
> Just-In-Time (JIT) Compilation also known as *dynamic compilation*.
Program is compiled to native code during runtime to improve performance. 

In JIT compilation,
- translates bytecode(.class) to machine code instructions of running machines
  - resulting machine code is **optimized for running machine's CPU architecture**
- compilation is done at runtime of program (as opposed to prior to execution)
- since compilation takes place in run time, JIT compiler has access t dynamic runtime information enabling it to mae better optimizations

The hope is that the efficiency of running machine code will overcome inefficiency of recompiling program every time it runs. 

<u>Optimizations</u>
JVM execute bytecode & mantians count of how many times function is executed
If count exceeds pre-defined limit, JIT compiles code into machine lanaguage that can directly be execute by processor. 

Next time, function is calaculated, compiled code is executed again unlike normal interpretatio --> faster execution

<small> Reference: [freeCodeCamp](https://www.freecodecamp.org/news/just-in-time-compilation-explained/) & [GeeksforGeeks](https://www.geeksforgeeks.org/just-in-time-compiler/) & [javatpoint](https://www.javatpoint.com/jit-in-java)</small>

###<a name="memory-management-in-java">Memory Managment in Java</a>
> Memory management is the process of allocation & de-allocation of objects. Java uses automatic memory management system called **garbage collector**.

<small> Reference: [javatpoint](https://www.javatpoint.com/memory-management-in-java) & [oracle docs](https://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/garbage_collect.html) & [peter lee medium](https://medium.com/@peterlee2068/java-memory-management-37f5483b23c1) </small>


###<a name="java-heap-space-vs-stack-memory"> Java: Heap Space VS Stack Memory</a>
> To run application in optiomal way, JVM divide memory into stack & heap memory
<u>Stack</u>: 
- used for execution of thread
- primitive values specific to a method
- references to objects that are in a heap, referred from method.
- *thread-safe*: eahc thread operated in its own stack
<u>Heap</u>: 
- actual objects 
- dynamic memory allocation for Java objects & JRE classes at runtime
- String Pool
- *not thread-safe*: needs to be guarded by properly synchronizing code

New objects are always created in heap space and the references to this objects are stored in stack memory. When the heap becomes full, garbage is collected. So, no longer used are cleared, thus making space for new objects. 


- Heap
  - created when JVM starts up & may increase/decrease in size while application runs
  - when heap is full, **garbage is collected**
  - new objects created in heap space *references to objects stored in stack memory*
  - objects have **global access** and can be accessed from anywhere in the application, not thread safe
  - Broken down to 3 parts
    - **Young Generation**: all new objects are allocated & aged.
    - **Old / Tenured Generation**: long surviving objects stored. object stored in young gen, threshold for its age set. when threshold reached. Object moved to old gen
    - **Permanent Generation**: JVM metatdata for runtime classes & application methods.
  - When heap becomes full garbage is collected
- Stack
  - referenced in LIFO order
  - when new method is called, new block on top of stack is created which contains values specific to that method (eg. primitive variables & references to objets)
  - method finish execution -> corresponding stack frame is flushed, flow goes back to calling method. space available for next method


```
package com.journaldev.test;

public class Memory {

	public static void main(String[] args) { // Line 1
		int i=1; // Line 2
		Object obj = new Object(); // Line 3
		Memory mem = new Memory(); // Line 4
		mem.foo(obj); // Line 5
	} // Line 9

	private void foo(Object param) { // Line 6
		String str = param.toString(); //// Line 7
		System.out.println(str);
	} // Line 8

}

```

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/87mmh1sljdvhamz5yq03.png)

1. Run program -> load runtime classes to Heap space
2. main() method found at line 1, runtime create stack mem to be used by main() method thread.
Whenever new object created,
- object created in heap memory
- stack memory contains the reference for it. 
- when new method called -> new block created **on top** of stack (LIFO)
- String, reference in stack mem -> reference points to String pool in heap space
- when method (foo())terminates, stack becomes free (stack mem created for function destroyed) 
- move to next program below (main())

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/devxpspb94etd10loiem.png)
 
<small> Reference: [stackify](https://stackify.com/java-heap-vs-stack/) & [baledung](https://www.baeldung.com/java-stack-heap) & [JournalDev](https://www.journaldev.com/4098/java-heap-space-vs-stack-memory)</small>

###<a name="java-garbage-collection">Java Garbage Collection</a>
> GC: Process by which Java performs automatic memory management
When Java programs run on JVM, objects are created on the **heap**. When some objects no longer needed. GC will find the, delete them to free up memory.

4 garbage collectors: <small>planning to bomb this if asked </small>
- serial
- parallel
- concurrent mark sweep
- G1 (h=garbage first)

<u> Benefits </u>
- automatically handles deletion of unused objects / objects out of reach to free up virtual memory resources. 

<small> Reference: [stackify](https://stackify.com/what-is-java-garbage-collection/#:~:text=Java%20garbage%20collection%20is%20the,Machine%2C%20or%20JVM%20for%20short.&text=The%20garbage%20collector%20finds%20these,them%20to%20free%20up%20memory.) </small>

###<a name="java-comparison-to-python">Java: Comparison to Python</a>
- Java programs expected to run **faster** than python
  - Python tun time typing, python run time "works harder" than java (more tasks to do
  - python run time must inspect objects and find type then invoke operation

- Java programs take **longer time to develop**
- Java programs are **longer (number of lines of code)** than python
  - java is statically typed

<small>Reference: [python org](https://www.python.org/doc/essays/comparisons/) </small>

###<a name="objects-&-classes">Objects & Classes</a>
> *Class*: user defined blueprint from which object is created
*Object*: basic unit of OOP, instance of a class. 

objects can be created from class via constructor. There are 2 kinds
- Default / non-parameterised
  - 0 arguments
- Parameterised
  - constructors have specific number of arguments to be passed

> constructor cannot be abstract final or static

###<a name="variables-&-methods">Variables & Methods</a>

<u>Types of variables</u>
- local
- instance
- static

> each object has own copy of instance variable however, all objects will share only one copy of static variable 

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lbcosjofnlbb48ipnym0.png)
 ![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/23qr93dcekwyg3mb0n65.png)

<u> Methods </u>
Methods consist of
- modifier
  - eg. private / public
- return type
- method name
- parameters
- method body / logic

> static methods belong to a class, no need to instantiate object to use the method

### <a name="method-signature">Method Signature</a>
> Method signature is `<method name>()<argument types>)` 
Does **NOT include**: access modifier & return type

In java, you **cannot have >=2 methods with same method signature in the same class** (even if methods have different return types)

```
public void display(String info){
  System.out.println(info);
}

// ERROR: duplicate method Signature
public String display(String info){
  // logic
}
```

### <a name="packages">Packages</a>
> Group of classes & interfaces & sub-packages which has similar functionalities. 
Provide folder structure to organise classes 

packages naming style: 
- lower case
- reverse domain

### <a name="access-modifiers">Access Modifiers</a>
> Modifiers set accessibility of classes or methods or any memebers

- public 
- private
- protected
- default (no modifiers)

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/08e90tnpnpy0idpdewjj.png)
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hex8luco8jf70wborw5l.png)
 

<small> Reference: [Jenkov tutorials](http://tutorials.jenkov.com/java/access-modifiers.html) & [GeeksforGeeks](https://www.geeksforgeeks.org/access-modifiers-java/)</small>

### <a name="abstract-keyword">Abstract Keyword</a>
> non-access modifier applicable for classes and methods but **not variables**
Used to achieve abstraction in Java (one of the pillars of OOP)

<u> Abstract class </u>
> cannot create / instantiate object of abstract class
Any subclass of abstract class must either implement all abstract methods or be declared abstract itself. 

```
abstract class class-name{
    //body of class
}
```
Due to partial implementation of classes, object cannot be instantiated. 
Abstract class depend on subclass to provide complete implementation.
Any sub 

<u> Abstract method</u>
> Abstract method dont contain body. sub classes will implement them 

```
abstract type method-name(parameter-list);
```

- any class containing abstract method must be abstarct
- the following combinations of modifiers **cannot** be used with abstract
  - final (class & method)
  - private (method)
  - static (method)
  - synchronized (method)
  - native / strictfp

Further reading of abstract method on [Java Goal](https://javagoal.com/abstract-method-in-java/)

<small> References: [GeeksforGeeks](https://www.geeksforgeeks.org/abstract-keyword-in-java/) & [javatpoint](https://www.javatpoint.com/abstract-keyword-in-java)</small>

### <a name="abstract-illegal-modifier">Abstract Illegal modifiers</a>

<u> Abstract final </u>
- Class: final used to prevent inheritance
  - Abstract classes depend on child classes to complete implementation. 
- Method: final used to prevent overidding
  -abstarct method need to be overidden in sub classes

<u> Abstract private </u>
- Method: private method cannot be accessed outside current class
  - child classes cannot access private abstract methods & cannot implement it. 
- Class: nested class. everything within class can access a nested private class
  - can have a nested private abstract class [SO example](https://stackoverflow.com/questions/23882308/private-abstract-classes-in-java)

<small>Reference: [tutorialspoint](https://www.tutorialspoint.com/can-we-declare-an-abstract-method-private-protected-public-or-default-in-java) & [stackoverflow](https://stackoverflow.com/questions/2874350/cant-declare-an-abstract-method-private)</small>

<u> Abstract static </u>
- Method: static methods can be hidden **but not overidden**
  - abstract method must be overidden to be implemented. Static methods cannot be overidden, so they cannot be abstarct.

<small>Reference: [tutorialspoint](https://www.tutorialspoint.com/Why-can-t-static-method-be-abstract-in-Java#:~:text=A%20static%20method%20belongs%20to,a%20static%20method%20as%20abstract.) & [stackoverflow](https://stackoverflow.com/a/372544)</small>

<u> Abstract synchronized</u>
- Method: synchronised. thread gets lock on object on entering method
  - thread entering synchronized method must get lock of the object in which method is define. cannot instantiate abstract class so no object with lock. 
https://javagoal.com/abstract-method-in-java/
https://stackoverflow.com/a/12805823

<u> Abstract strictfp</u>
> strictgp is a an access-modifier. no modifiers allowed on abstarct methods except public and protected. 

### <a name="final-keyword">Final Keyword</a>
> for **classes, variables & methods** 
used to **finalize implementation** of them

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dsx17rczxlgtzatr42es.png)
 
- Final variable
  - to create constant variable
  - cannot change the value of final variable once it is assigned. It will be constant.
  - can be initialized in constructor. 
- Final method
  - prevent method overriding
  - can be inherited but cannot be overridden.
  - constructor **cannot be made final**. constructor cannot be inherited so it cannot be overriden, will have compile time error. 
- Final class
  - prevent inheritance

<small> references [javatpoint](https://www.javatpoint.com/final-keyword) & [GeeksforGeeks](https://www.geeksforgeeks.org/final-keyword-java/) & [tutorialspoint](https://www.tutorialspoint.com/Can-a-constructor-be-made-final-in-Java)</small>

### <a name="static-keyword">Static Keyword</a>
> for **variables, methods, block, nested class** 
used to define classes members **indepedent from any instances**

- static variable
  - single copy of variable is create & shared among all objects at class level 
- static methods
  - can be accessed before any objects of class created & without reference to any object. 
    - can only directly call other static methods
    - can only directly access static data
    - cannot refer to *this* or *super* 
- static nested / inner class
  - mainly for convinience
  - no need to instantiate outer class to instantiate inner class
  - refer to: https://stackoverflow.com/a/47568544
  - useful for: builder pattern (inner builder class is static)
- static block
  - do computation to initialize static variables
  - is executed exactly once - when class is first loaded. 

```
class Test {
    // static variable
    static int a = 10;
    static int b;
      
    // static block
    static {
        System.out.println("Static block initialized.");
        b = a * 4;
    }
}
```

<small> References: [GeeksforGeeks](https://www.geeksforgeeks.org/static-keyword-java/) & [javatpoint](https://www.javatpoint.com/static-keyword-in-java) & [Baeldung](https://www.baeldung.com/java-static) </small>

### <a name="static-vs-instance-block">Static VS Instance block</a>
static block: 
- runs at time of class loading
- will execute in same order they appear in the class
- static block of parent class execute FIRST because compiler loads parent class BEFORE child class

instance block:
- runs at time of instance creation
- executees during every constructor invocation
- parents instance block will run first BEFORE child's instance block


Order is
Super class - static
Sub class - static
Super class - instance
Super class - constructor
Sub class - instance 
sub class - constructor

Note that by default JVM will insert `super()` ins first line of sub class constructor if developer has not done so. 

<small>ref: https://www.quora.com/In-Java-does-every-object-constructor-automatically-call-super-in-object-before-its-own-constructors</small>
<small>ref: https://www.javamadesoeasy.com/2015/06/differences-between-instance.html</small>

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ce0m5v2ubhw7cfi1b943.png)

<small>ref: https://www.baeldung.com/java-static-instance-initializer-blocks</small>


### <a name="wrapper-class-immutable">Wrapper Classes are immutable</a>

> Wrapper classes are immutable so **operations** like add, subtarct **create new object** and **do not modify the old**

Reference: [GeeksforGeeks](https://www.geeksforgeeks.org/primitive-wrapper-classes-are-immutable-in-java/)
eg. 
```
public static void main(String[] args)  {
        Integer i = new Integer(12);
        System.out.println(i); // 12
        modify(i);
        System.out.println(i); //12
}
  
private static void modify(Integer i) {
        i = i + 1;
}
```
paramete *i* is referenced in modify however it does not change since objects are immutable.

<u> Creating new object </u>
Reference: [SO](https://stackoverflow.com/questions/5560176/is-integer-immutable) & []
```
Integer a=3;
Integer b=3;
a+=b; // a=a+b
System.out.println(a); // 6
```
In this case, `a+=b` actually does `a = new Integer(3+3)`
*a* is a reference, in the line `a+=b`, the code changes the reference *a* to points to a different, equally immutable Integer. 

### <a name="why-wrapper-classes">Why wrapper class</a>
> Wrapper classes  wraps around data type and give it an object appearance, this provides object methods to primitive types. 
Reasons:
- null is possible value
- use it in Collection
- methods that support object (eg. creation from other types `Integer test = new Integer("55");`


<u>Different wrapper classes </u>
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hzrn993q843vona8kxa8.png)

### <a name="constructor-vs-valueOf">Constructor VS valueOf </a>
There are two ways to create wrapper class
- constructor
`Integer test = new Integer("100");`
- valueOf
`Integer test = Integer.valueOf("100");`

> <u>constructor</u>: always **creates new object**
<u>valueOf</u>: may return a cached value if it is within range. (eg. if long is between -128 to 127, valueOf implements a cache). If not in cache gives new object.

valueOf is [generally recommended](https://stackoverflow.com/a/2974852) since it results in better space and time performance by caching frequently requeste values. 

Since wrapper classes are immutable, its important to reuse values.  
 
Under the hood autoboxing also invokes the static valueOf method

<small> Reference: [java docs](https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7) & [SO answer](https://stackoverflow.com/a/408668)</small>

### <a name="autoboxing-and-unboxing">Autoboxing & Unboxing</a>
> automatic conversion Java compiler makes between primitive types & their corresponing object wrapper class.
Conversion the other way is called unboxing. 


```
// autoboxing
Integer test = 9; 

// autounboxing
Integer test1 = Integer.valueOf(10);
test1++;
```

<u> Autoboxing </u>
create Integer object from primitive data type
`Integer test = Integer.valueOf(9);`

<u>Auto Unboxing</u>
airthmetic operations (+, %, +=) do not apply to Integer objects. Java compiler compiles code with no errors since it does autounboxing, invoking `intValue` to convert `Integer` to an `int` at runtime. `test1.intValue()++;`

<small> reference: [java docs](https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html#:~:text=Autoboxing%20is%20the%20automatic%20conversion,a%20Double%2C%20and%20so%20on.&text=List%20li%20%3D%20new,add(i)%3B) </small>

### <a name="autoboxing-unboxing-advantages">Autoboxing Advantages</a>
> lets developers write cleaner code that is easier to read.

Additionally, Autoboxing uses static valueOf method which is more efficient 

<small> Reference: [java docs](https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html)</small>

### <a name="typecasting-implicit-explicit">Typecasting - Implicit & Explicit</a>
> **Typecasting**: converting *primitive/interface/class* in Java into another type. 
If 2 types are compatible java performs conversion *automatically* else they need to be converted *explicitly*. 

- Implicit/widening/automatic
  - happens if both types are compatible & **target type** is **larger** than **source type**

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g3jxxesi84bgzcq92ohq.png)
<small> casting smaller value to a larger variable types </small>
```
byte i = 50; // 50
short j = i; // 50
int k = j; // 50
long l = k; // 50
float m = l; // 50.0
double n = m; // 50.0   
```

- Explicit/narrowing
  - assigning **larger type** to a **smaller type**

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nnff2ef870xkpsxyhsui.png)
<small> casting larger value to a smaller variable types </small>
```
double d = 75.0; // 75.0
float f = (float) d; // 75.0
long l = (long) f; // 75 
int i  = (int) l; // 75
short s = (short) i; // 75
byte b = (byte) s; // 75
```

<small>Reference: [GeeksforGeeks](https://www.geeksforgeeks.org/type-conversion-java-examples/) & [javainterviewpoint](https://www.javainterviewpoint.com/type-casting-java-implicit-explicit-casting/) & [edureka](https://www.edureka.co/blog/type-casting-in-java/)</small>

### <a name="strings-immutability">Strings - immutable</a>
> Value of String object once created **cannot be modified**. 
Any modification creates a String object
String is mainly immutable becuase it *encapsulates a char[]*

```
String test = "hello";
test.concat(" world");
System.out.println(test); // hello
```
value of String object was **not modified**. the `concat()`operator like `toUppercase()` operator *produces a new String*. The **original value remains unchanged**.

```
String str = "hello";
str = str + "world";
System.out.println(str); //hello world
```
In the code snippet, `str` was **not changed**. Rather a new String object "hello world" was instantiated and assigned to the reference `str`.

<small> Reference: [SO](https://stackoverflow.com/a/5560220) </small>

### <a name="string-store-where-in-memory">Where are string values stored i memory?</a>
> depends on how we create them
1. String literal -> String constant pool (in heap)
2. new Object -> heap memory

- String literal
  - value stored in String constant pool  (heap memory)
    - compiler finds String literal -> check if exists in pool, reused. 
- String object constructor
  - new object created on heap, reference in stack.
  - **not reuse of values**

### <a name="java-string-pool">Java String Pool</a>
> String Pool in java is a pool of Strings sorted in Java Heap memory. 
- saves space for Java runtime
- more time to create string. 

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/45uynr0ebnsws4q30ffh.png)

only possible becuase
- String is immutable in Java
- implementation of String interning concept

String pool is an example of Flyweight design pattern. 

<u> String literal </u>
`String test = "hello";`
when create string via String literal,
- java looks for string with same value in string pool
  - found: returns reference
  - else: create new String in pool -> return reference. 

<u> String constructor </u>
force Java to create new String object in heap space

```
String s1 = "Cat";
String s2 = "Cat";
String s3 = new String("Cat");
        
System.out.println(s1==s2); // true
System.out.println(s1==s3); // false
```

<small> Reference: [JournalDev](https://www.journaldev.com/797/what-is-java-string-pool) </small>

### <a name="java-string-interning">Java String Interning</a>
> method of *storing only 1 copy of each distinct String value*, which must be immutable. 

Java String class has public method `intern()`

- invoke `intern()` method on String object. 
- looks for the string contained by object in the pool
- if string is found
  - string from pool is returned
- else: 
  - String object added to pool & reference to String object returned.  

So by applying String.intern() on strings will ensure all strings with same content share same memory. eg. if 'hello' appears 100 times, interning ensures 1 'hello' is actually allocated memory. 

```
String s1 = "Test"; // s1 in SCP
String s2 = "Test"; // s2 in SCP
String s3 = new String("Test"); // s3 in heap
final String s4 = s3.intern(); // s4 in SCP
System.out.println(s1 == s2); // true
System.out.println(s2 == s3); // false
System.out.println(s3 == s4); // false
System.out.println(s1 == s3); // false
System.out.println(s1 == s4); // true
System.out.println(s1.equals(s2)); // true
System.out.println(s2.equals(s3)); // true
System.out.println(s3.equals(s4)); // true
System.out.println(s1.equals(s4)); // true
System.out.println(s1.equals(s3)); // true
```

<small> Reference: [GeeksforGeeks](https://www.geeksforgeeks.org/interning-of-string/) & [DZone](https://dzone.com/articles/string-interning-what-why-and) </small>

### <a name="objects-created-in-String-construction">Number of Objects created in String Construction</a>
```
String str = new String("Cat");
```
Either 1 or 2 objects created
- String literal 
  - "Cat" String created in String pool (if does not exist)
- String `str` object
  - String object created on heap
<small> Reference: [JournalDev](https://www.journaldev.com/797/what-is-java-string-pool) & [SO](https://stackoverflow.com/a/19672578)</small>

### <a name="never-+-string-in-loop">Never + String in loops</a>
> each concatenation creates a new object, since string in immutable
**use String Buffer/Builder**

```
String test = "lup";
String test2 = "dup";
for (int i=0;i<100000;i++){
  test = test + test2;
}
```
Loop creates about 100 000 String objects.

<u> String Buffer </u>
```
StringBuilder test = new StringBuilder("lup");
String test2 = "dup";
for (int i=0;i<100000;i++){
  test.append(test2);
}
String result = test.toString();
```
This would yield better performance. 


### <a name="string-vs-stringbuffer">String VS StringBuffer</a>
- String immutable, StringBuffer used to represent values that can be modifed. 
- both are thread safe


### <a name="StringBuilder-vs-StringBuffer">StringBuilder VS StringBuffer</a>
> String Builder **not thread safe** String Buffer is

### <a name="java-what-is-a-class">Java What is a class</a>
>  template for creating multiple objects.
It defines:
1. state 
2. behaviour
that an object can exhibit

<u> State </u>
Values object has.
In Java, this would be the **instance variables** of the object

<u> Behaviour </u>
**methods** that are part of the class

State of object can **change with time**, can change via **behaviour** / class methods. 

### <a name="java-what-is-a-object">Java: </a>
> instance of class
Can create objects via **constructor**


### <a name="super-class-of-every-class">ParentClass of every class</a>
> Java **Object  class** is the super / parent class of every class in Java

Useful if you want to *refer to any object whose type you dont know*.

Classes will inherit all properties & methods of Java Object class.
eg.
1. toString
2. hashCode
3. equals
4. clone 

### <a name="java-object-toString-method">Java Object toString method</a>
> used to print content of object
It is inherited from the Java objects class. 
<u> Default </u>: print hash code
<u> overridden </u>: content returns by toString overidden implementation is printed. 

The toString() method **MUST**
> 1. be public
2. return type: String
3. not accept any parameteres

Object class default toString method
```
public String toString()
{
      return getClass().getName()+"@"+Integer.toHexString(hashCode());
}

MyClass test = new MyClass();
System.out.println(test);
// com.example.demo.MyClass@f7e66a96
```
<small> Reference: [GeeksforGeeks](https://www.geeksforgeeks.org/object-tostring-method-in-java/) & in28Minutes </small>

### <a name="java-object-equals()-method">Java equals() method</a>
> used to **compare 2 object**
Inhierited from java Objects class
<u>Default</u>: uses `==` operator (check if references point to the same object)
<u>overidden</u>: usually implemented as checking all properties of object have equals value

If making you own custom class, **must override equals method** to check the contents of the object. 

### <a name="equals()-method-criteria">equals() Method Criteria</a>
> All implementation of equals method must meet following criteria
- **Reflexive**
  - For any reference values x, x.equals(x) returns true
- **Symmetric**
  - x.equals(y) == y.equals(x)
- **transitive**
  - if x.equals(y) = true & y.equals(z) = true, thenx.equals(z) == true.
- **Consistent**
  - multiple invocations x.equals(y) will *consistently* return true or *consistently / always* return false. 
  - outcome wont change when operation is repeated.
- **Null comparison**
  - For any non null reference x, x.equals(null) must return false. 

Usually just use IDE to generate

<small> Reference [JournalDev](https://www.journaldev.com/21095/java-equals-hashcode#:~:text=equals()%20method%2C%20any%20implementation%20should%20adhere%20to%20following%20principles.) & in28minutes</small>

### <a name="java-object-hashCode()-method">Java hashCode() method</a>
> used in collections like hashmap. 
<u>Default</u>: [derived from memory address](https://howtodoinjava.com/java/basics/java-hashcode-equals-methods/#:~:text=by%20default%2C%20integer%20value%20is%20mostly%20derived%20from%20memory%20address%20of%20the%20object%20in%20heap%20(but%20it%E2%80%99s%20not%20mandatory%20always).) of object used in heap
Used in **hashing** to *decide which bucket object should be place in*.
Therefore, hashCode() **decides the effectiveness of Hashing**.
Good hashing function will distribute objects **evenly** across different buckets. 

###<a name="hashCode()-method-criteria">hashCode Method Criteria</a>
> Good hashCode should have following proerties
1. obj1.equals(obj2) == true --> obj1.hashCode() == obj2.hashCode()
2. consistent. obj.hashCode() shuould **return same value** when run multiple times *if values used in obj equals() have not changed*
3. if obj1.equals(obj2) == false --> obj1.hashCode **MAY BE** == obj2.hashCode().

Basically.
- two unequal objects 
  - **might** have same hashcode (hash collision)
- two equals objects
  - **must** have same hashcode 
      - if 2 equal objects have same hashcode, they can be placed in different buckets.
      - equals() function will never run on obj1 & obj2. obj2 will never replace obj1
       - hashmap can hold duplicate keys 


### <a name="equals()-&-hashCode()-importance">Importance of equals() & hashCode()</a>
> It is a must to override / implement equals() & hashCode() method if you are **using objects as hashma keys**

Implementtation of equals() & hashCoe() follow these rules / contarct:
1. if o1.equals(o2) --> o1.hashCode() == o2.hashCode()
2. if o1.hashCode() == o2.hashCode() == true, o1.equals(o2) MAY NOT be true

So, if you implement equals method, its good practice to override hashCode so both methods follow contract.

however, this will only really come into play if you use objects as **hashmap keys**.

In hashing
<u>equals()</u>:used to check if key exists in Hashmap
If wrongly implemented,
- hashMap.get(obj) may return null, since wrong equals method cant tell that obj and key are equal
- hashMap.put(obj1) may give "duplicate" keys. Since Java cant tell that obj1.equals(obj) and make obj1 override obj

<u>hashCode()</u>: decide which bucket obj will be placed in
If wrongly implemented:
- equivalent objects can get placed in two different buckets.
  - since equals() only runs on 1 bucket, Java cant tell that obj already exists on HashMap
  - HashMap can store "duplciate" keys. 
  

<small>Reference: [JournalDev](https://www.journaldev.com/21095/java-equals-hashcode#:~:text=%20you%20are%20planning%20to%20use%20a%20class%20as%20hash%20table%20key%2C%20then%20it%E2%80%99s%20must%20to%20override%20both%20equals()%20and%20hashcode()%20methods.)</small>


###<a name="java-objects-inheritance">Java Objects Inheritance</a>
> process where one class aquires properties (methods & field) of another. 
IS-A type of relationship
<u> class </u>: ChildClass **extends** ParentClass
<u> interface </u>: ChildClass **implements** Interfae1, Interface2

<u>Sub Class</u>: child class
<u>Super class</u>: parent class

**<u>Only 1 superClass</u>**
In Java,
- child class can only **extend 1 Parent Class**
- child class can **implement >=1 Interface**

**<u>Inheriting constructors</u>**
subclass inherits all memebers (fields methods, nested classes). but constructos are nont members & are **not inhierted**.
but constructor os superclass can be invoked from subclass `super()`

**<u>Private member inheritance</u>**
subclass does not inherit private members of parent class. 
but subclass can use superclass's public / protected methods (eg. getter, setter) To access superclass's private fields. 

During inheritance, only object of subclass created not super class
```
public class ChildClass extends ParentClass{
}
ChildClass test = new ChildClass()
```
In this case, only 1 ChildClass object created no ParentClass object is created. 

<small> Reference: [GeeksforGeeks](https://www.geeksforgeeks.org/inheritance-in-java/) & [tutorialspoint](https://www.tutorialspoint.com/java/java_inheritance.htm) & [w3schools](https://www.w3schools.com/java/java_inheritance.asp) </small>

### <a name="==-VS-equals">Java == VS equals</a>
> ==: compares if 2 references point to the same object 
can apply `==` for **every primitive type**
equals(): overrides Object equals method. 

<u>String class</u>
- String pool ensures '==' works for string literals  (references will point to same object / address in pool)
- equals(): can check the value of the String object 
(String pool ensures == works for string literals)
For String, can check value of object

<u>Object class</u>
> java Object's **default implemenetation** of equals() is [actually ==](https://www.infoworld.com/article/3305792/comparing-java-objects-with-equals-and-hashcode.html#:~:text=public%20boolean%20equals(object%20obj)%20%7B%20return%20(this%20%3D%3D%20obj)%3B%20%7D)
```
public boolean equals(Object obj) {
  return (this == obj);
}

```

For **custom object** to correctly implement the *equals()* method you **MUST  override the default implementation.** 
```
@Override
public boolean equals(Object o) {
  if (this == o) {
    return true;
  }
  if (o == null || getClass() !=  o.getClass()) {
    return false;
  }
  Simpson simpson = (Simpson) o;
  return age == simpson.age && weight == simpson.weight && name.equals(simpson.name);
}
```

<small> Reference: [GeeksforGeeks](https://www.geeksforgeeks.org/difference-equals-method-java/) & [infoworld](https://www.infoworld.com/article/3305792/comparing-java-objects-with-equals-and-hashcode.html) </small>

### <a name="how-hashmap-works-internally">How hashmap works internally</a>
> Hashamp works on principle of **hashing**- *an algorithm to map object data to some representative integer value*
<u> load factor </u>:  entries / buckets (0.75)
<u> capacity </u>: number of buckets (16)
<u> threshold </u>: capacity * load factor (12)

In Java, threshold (default) is 12. that means after the 12th kay value air is added, capacity of hashmap will increase (double) 


There are two main scenarios in a Java Hashmap
1. constructing & putting items in (`hashMap.put(key,value)`)
2. retrieving items from hashmap via key (`value = hashMap.get(key)`)

####<u>Constructing HashMap</u>

- 16 initial buckets
  - initial capacity = number of buckets = 16 (`new HashMap<>()`)
- default load factor is 0.75
- default threshold = 12
  - default threshold = 16 * 0.75 = 12
  - rehash is performed on 12th key value pair insert
- get hashCode of key
  - on `hashmap.put(key,value)`, Java calculate **hashCode() of key** `key.hashcode()`
- calculate bucket index (eg. 6) 
  - since hashcode may be bigger than number of buckets
  - *bitwise AND*. hashCode AND number of bucket. to determine bucket index to insert key value pair in
- Create Node object with key-value pair
  - Node like LinkeList 

Since hashCodes are not unique, there will be a **collision**

<u>Collision</u>
- get key1.hashCode()
- get bucket index of key1 (eg. 6)
- there is an object at index 6
- check that inserted object and existing one are not equals
  - **key.equals(key1)** to check equality
  - if same: replace
  - else: *collision*
- Connect node of key1 to node of key via **linked list**
  - `keyNode.next = key1Node`
  - both key-value pairs stored at index 6

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ald0adv5g4leu39dnd1a.png)
 

As more and more objects are inserted, load factor increases. An increasing load factor means more complex get() / put() which will defeat the great advantage of hashmap (ie. O(1) gets and puts)

To keep load factor low, once treashold is exceed, **rehashing** occurs

<u> Rehashing </u>
- Threshold (12) exceeded
- after 12th insert -> rehashing
- new Hashmp object created with **double** the old capacity (so 32 buckets)
- repeat `hashMap.put(key,value)` on all elements of old hashMap. 
  - all key-value pairs of old hashmap are placed into new hashMap
  - must recalculate their hashcode, index
  - then insert (linkedlist if collision)

> Rehashing process is both space `O(number of buckets)` and Time consuming `O(number of entries)`.
Therefore, a good balance must be struck between theshold and rehashing.  

- High threshold 
  - rarely rehash 
  - BUT: hashmap load factor is high
  - get and put will be complex
- Low threshold
  - load factor of hashmap is low, will have efficient gets and puts
  - rehash very often -> waste time and space 


####<u>Getting Item from HashMap</u>
> Load factor (& hashing function) will affect the complexity of get()
`value = hashMap.get(key)`

- calculate hashCode of key
- calculate index of key (eg. 6)
- go to bucket of index
- compare first Node with key sing **equals()**
  - `node.equals(key)`
- if both are equal: return value
- else go down linked list and check if node exists. 



<small>Reference: [SO answer](https://stackoverflow.com/a/10901821) &&[javaconceptoftheday](https://javaconceptoftheday.com/initial-capacity-and-load-factor-of-hashmap-in-java/) && [javarevisited](https://javarevisited.blogspot.com/2011/02/how-hashmap-works-in-java.html) && [javacodegeeks](https://examples.javacodegeeks.com/core-java/maphashmap-works-internally-java/) && [geeksforgeeks](https://www.geeksforgeeks.org/internal-working-of-hashmap-java/) && [baeldung](https://www.baeldung.com/java-hashmap-load-factor)</small>

### <a name="null-key-added-to-hashmap">Adding Null key to hashmap</a>
> only one null key is permitted

- hash calculation is **not done**
- (key,value) pair always added to bucket 0

<small> Reference: [knpcode](https://knpcode.com/java/collections/hashmap-internal-implementation-in-java/#:~:text=what%20happens%20when%20the%20null%20key%20is%20added)</small>

### <a name="hashset-internal-implementation-in-java">HashSet internal implementation in Java</a>
> Hashset uses **HashMap internally** a dummy object is always added as value to backing HashMap.
HashSet class used to create collection that uses *hash table for storage*. It contains *unique elements only*.

Like HashMap,
- Capacity = 16
- load factor = 0.75
- threshold = 0.75 * 16 = 12

<u> add values </u>
HashSet implementation, values are stored as hashmap keys. So set only contains unique elements.
In the underlying hashMap data, a **dummy object is always added as value**
`hashSet.add(element);` 
underlying implementation is
`hashMap.put(element,DUMMY)`

<u> get values </u>
there are not values. just use key iterator to get keys
`hashMap.keySet().iterator()`

you can use hashMap to check if key is present in Set

<u> remove values </u>
same as removing items in hashmap

<small>Reference: [knpcode](https://knpcode.com/java/collections/hashset-internal-implementation-in-java/) </small>


### <a name="arraylist-capacity-vs-size">ArrayList: Capacity VS Size</a>
> <u>Capcity</u>: maximum item list can hold before it can be resized
<u>Size</u>: number of itesm in the list. 

```
List<Intger> test = new ArrayList(20);
test.add(1);
test.add(2);
test.add(3);
```
In this case, capacity is 20, size is 3. 

### <a name="how-arraylist-works-internally">How ArrayList works Internally in Java</a>
> Arraylist is *resizeable array* implementation in java.
backed by an array 

- default capacity = 10
- <u>add()</u>: ensure arraylist has required capacity.
  - if capacity exhausted
    - new array created with **50% more capacity**
    - *Arrays.copyOf()* used to copy elements from old array to new array
- <u>remove()</u>: remove element from array
  - elements shift to fill gap created by removed element

<small> Reference: [GeeksforGeeks](https://www.geeksforgeeks.org/internal-working-of-arraylist-in-java/) &  [javatpoint](https://www.javatpoint.com/arraylist-implementation-in-java) & [knpcode](https://knpcode.com/java/collections/arraylist-internal-implementation-in-java/) </small>


### <a name="java-vector-class">Java Vector class</a>
> Vector is basically a **thread safe** arraylist.
Vector is **synchronised**, can use it in multiple threads. 

Vector came first (before arraylist), in jdk since jdk 1.0 

Synchronization has an overhead, so if you are not using multiple threads you can use a class without synchronization overhead. 


### <a name="how-stack-implemented-by-java">How is stack implemented by Java internally?</a>
> Stack is LIFO (last-in-first-out) stack of objects
operations: push, pop, peek, empty, search

No items on stack creation.

implemented with underlying Vector class. Vector is a growable/dynamic array. 

This could be due to backwards compatibility (see Quora source) 

<small> Reference: [SO](https://stackoverflow.com/a/55037772) & [Quora](https://www.quora.com/Do-stack-class-in-Java-is-internally-implemented-using-linked-list) & [java docs](https://docs.oracle.com/javase/8/docs/api/java/util/Stack.html)


### <a name="queue-implementations-in-java">Queue implementations in Java</a>
> Queue is a FIFO (first-in-first-out) data structure
operations: add, remove, element

In java, Queue is an **interface**.
There is no Queue class, it has to be implemented.

Implementations
- LinkedList
- PriorityQueue 
  - based on *heap* data structure.
  - orders elemnts accoridng to order specified at construction time.
  - queue retrieval operations (poll, remove, peek) access element at head of queue. 
  - if mutliple elements are tied for head of queue, *tie is broken arbitarrily*.


### <a name="hashmap-treemap-linkedhashmap">Map Implementation: HashMap, TreeMap, LinkedHashMap</a>
> All offer unique key-> value mappings & implement Map interface .
Difference is **time guarantees & ordering of keys**
<u>HashMap</u>: implemented as hash table &  no ordering on keys or values. 
<u>TreeMap</u>: implemented based on red-black tree structure, & ordered by the key.
<u>LinkedHashMap</u>: preserves the insertion order
<u>Hashtable</u>: synchronized HashMap. 

- HashMap
  - implemented by array of linked lists
  - O(1) look up & insertion
  - key orders -> arbitrary
- TreeMap
  - implemented by Red-Black Tree. 
  - O(logN) lookup & insertion
  - keys orders -> ordered, need to iterate through keys in sorted order
  - **does not use hashing for storing key-pair values**
- Linked Hash
  - implemented doubly linked list between key-value pairs (on top hashmap implementation) that keeps track of insertion order
  - O(1) look up & insertion
  - keys orders -> insertion order

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l41u4mkme836h5gqo2dt.png)
<small> [Source](https://tdkhiem.com/maps-in-java/) </small>

- LinkedHashmap operations
 - on top of hashmap, maintains an additional [doubly-linked list](https://stackoverflow.com/a/2889796) to make it "aware" of ordering of key-value pairs
 
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2e543dhznp1onip83zcb.png)
<small>LinkedHashMap, internal implementation [Medium article by Anmol Sehgal](https://anmolsehgal.medium.com/java-linkedhashmap-internal-implementation-44e2e2893036) provides really good explanation of Linked hashamp</small>


- TreeMap [internal workings](https://www.javatpoint.com/how-treemap-works-internally-in-java)
  - **does not use hashing**
  - sorts object kyes using red-black-tree algorithm
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z67x7u6zawsze19mrwiq.png)
 
<small> Reference: [oracle docs](https://docs.oracle.com/javase/tutorial/collections/implementations/map.html) & [GeeksforGeeks](https://www.geeksforgeeks.org/differences-treemap-hashmap-linkedhashmap-java/) & [DZone](https://dzone.com/articles/hashmap-vs-treemap-vs) </small>

### <a name="hashset-treeset-linkedhashset">Set Implementation: HashSet, TreeSet, LinkedHashSet</a>
HashSet -> HashMap
TreeSet -> TreeMap

<small> Reference: [oracle docs](https://docs.oracle.com/javase/tutorial/collections/implementations/set.html) & [GeeksforGeeks](https://www.geeksforgeeks.org/difference-and-similarities-between-hashset-linkedhashset-and-treeset-in-java/) </small>

### <a name="arraylist-linkedlist-java
">List Implementation: ArrayList VS LinkedList</a>
> both implement List 
<u>Arraylist</u>: dyamically add & remove items, automatically resizes iteself, elemnts stored in contiguous memory
<u>LinkedList</u>: linear data strucutres, every element is seaparate object with data & address part. elements are linked using points & addresses. 

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/63k5xayv9s7hnw79eamg.png)
 
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b21jkgm5rt6kp49i06av.png)
* manipulating data like removing data. (arraylist, underlying array everything must shift). 

<small>Referece: [javatpoint](https://www.javatpoint.com/difference-between-arraylist-and-linkedlist) & [GeeksforGeeks](https://www.geeksforgeeks.org/arraylist-vs-linkedlist-java/) & [Baeldung](https://www.baeldung.com/java-arraylist-linkedlist)</small>

### <a name="what-is-oop">What is OOP</a>
> OOP is a programming prardigm that relies on the concepts of **classes & objects**.
Developer will strcuture code in terms of classes & objects

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fa5ownhdhv4knihze0zt.png)

An alternate paradisn is procedural programming.
- program is divided into samller parts called mathos
- methods are basic entities in this technique
- use methods for code reuability

OOP's benefits are 
- Clear structure for program
- Reusable code, Java code is DRY (dont repeat yourself)
- code easier to maintain modify & debug


### <a name="OOP-inheritance">OOP Pillar: Inheritance</a>
> Allows classes to inherit features of other classes.
- mechanism to create new class by deriving old classs
- **Inheritance supports reusability**
- Represents *IS-A relationship*



![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hnr3gdkc552rs6fbjpb4.png)

Subclasses are IS-A relationship with super class.

```
public class SuperClass{}
public class SubClass **extends** SuperClass{}
```

In Java, object class is super class of all objects.


<small> References: [javatpoint](https://www.javatpoint.com/inheritance-in-java) </small>



### <a name="types-of-inheritance">Types of Inheritance</a>
> 5 types
- **single**
  - class inherit another class
- **multilevel**
  - chain of inheritance 
  - Corgi extends Dog, Dog extends Animal
- **heirarchical**
  - 2 or more classes inherit single class
- **multiple** (interface) 
  - sub class has >1 super class
- **hybrid** (interface)
  - mix of 2 or more of above types. 
  - Since java calsses can't support mutiple inheritance, class cannot support hybrid inheritance. 

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h7rnqumbd3ijviwvuur0.png)
<small> image from [simplesnippets](https://simplesnippets.tech/inheritance-in-java-types-of-inheritance/) </small>

<u> Why Java class cannot support multiple iheritace </u>
- reduce complexity / simplify language
If sub class (C) inherits 2 classes (A,B).
If A & B have same method (`testMethod()`) & method is called from subclass `C.testMethod()`.
Does subclass implement method from A or B?

<small> references: [GeeksforGeeks]() & [javatpoint](https://www.javatpoint.com/inheritance-in-java) </small>

### <a name="inheritance-in-java-oop">Inheritance in Java: OOP</a>
Reference:https://www.geeksforgeeks.org/inheritance-in-java/#:~:text=important%20facts%20about%20inheritance%20in%20java%20 
> Inheritance in Java done via following:
- key words
  - extends
  - implements
- types of classes
  - class
  - interface
  - abstract class

<u>Important facts</u>
- Default super class
  - besides object, every Java class has super class
  - every class is implicty subclass of objet class
- only 1 super class
- inherit construcotrs
  - cannot inherit super class constructors
  - can call super class constructors `super()` in subclass constructor
- private memeber inheritance
  - cannot inherit private memebts (fields, methods, nested classes)
  - can access / modify private methodss via super class getter / setters (`super.getProperty()`)

<u>What can be done</u>
- Inherited fields
  - use them
  - Declare new field in subclass
- inherited methods
  - use them
  - override them (use same method signature as superclass `@Override`)
  - **Hide** *static* methods (use same method signature as superclass static method)
  - declare new methods
  - write new subclass constructor that uses constructor of superclass (`super()`) 
    - Call to `super()` must be **first statement** in subclass

### <a name="extends-vs-implements">Extends VS Implements</a>
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u2sp02tb9o35mhf2cx8t.png)


### <a name="oop-abstraction">OOP Pillar: Abstration</a>
> process of hiding implementation details & only showing functionality to the user

Abstractions lets developer focus on *what* an object does instead of *how* an object is doing it. 

Implementation of function is **hidden from user**.

<small> Reference: [SO](https://stackoverflow.com/a/51304341) </small>


### <a name="oop-abstraction-in-java">OOP Abstraction in Java</a>
> Java has 2 ways to achieve abstraction
1. Abstarct class (0-100%)
2. Interface 100%

- Abstract class
  - class declared as **abstract**
  - can have abstarct & non-abstarct methods
  - needs to be extended 
  - child class must implement **all its abstarct methods**
  - **cannot be instantiated**
  - **can have constructor**, data members, abstract & non-abstarct methods.

```
abstract class Bike{  
  abstract void run();  
}  
class Honda4 extends Bike{  
  void run(){
  System.out.println("running safely");
}  
public static void main(String args[]){  
   Bike obj = new Honda4();  
   obj.run();   // running safely
 }  
}  
```

- Interface
  - can only have abstract methods (no method body)
    - **Java 8 allows default & static methods** in interface
  - allows multiple inheritance
  - class implementing interface must **implement all methods declared in interface**
  - **cannot be instantiated**
  - all fields are public static final
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/plf96jznnkc7zr4k3gkk.png)
  
```
interface Drawable{  
  void draw();  
  default void msg(){
    System.out.println("default method");
  }  
  static int cube(int x){
    return x*x*x;
  }
}  
class Rectangle implements Drawable{  
  public void draw(){
    System.out.println("drawing rectangle");
  }  
}  


Drawable d=new Rectangle();  
d.draw();  // drawing rectangle 
d.msg();  // default method
Drawable.cube(3); // 27
```

<small> Reference: [javatpoint](https://www.javatpoint.com/abstract-class-in-java) & [javatpoint-interface]</small>



### <a name="oop-abstract-class-vs-interface">Abstarct Class VS interface</a>
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nx8lfensojb9efiimusg.png)
 From oracle docs


When to use:
- Abstract Class
  - share code among **closely related classes***
  - expect classes extending abstract class have many common methods / fields / require access modifiers other than public (abstract classes can declare non-public methods & fields)
  - declare static or non-final fields

- Interface
  - **unrelated classes** will implement interface
  - use multiple inheritance
  - expect API to not change for a while (if change 1 interface method all classes must change) 

<small> Reference: [techvidvan]( https://techvidvan.com/tutorials/abstract-class-vs-interface/) </small>

### <a name="oop-encapsulation">OOP Pillar: Encapsulation</a>
> OOP technique of wrapping data & code in to **achieve data hiding**. 
technique is 
<u>Data hiding</u>: Unauthorized users should not have access to / modify data
Benefits:
- **flexibility**: can decide which variables have read/ write priviledges
- **control**: class can control what is stored in fields (is setter is bad input, reject it) 

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/67yt5ts51drczoh00jus.png)

<u>How does it achieve data hiding?</u>
- wrap data (vairables / fields) & code that manipualtes data (methods) together in a single unit
- variables are hidden from other classes
- variables are onlt accessed through methods in their current class
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9t6c7dgnc229kb8ax647.png)
 

Code now becomes like a "protective shield" that prevents data from being acessed by unauthorize users / means. 
 
<small> Reference: [Educative](https://www.educative.io/blog/object-oriented-programming-concepts-java) & [javatpoint](https://www.javatpoint.com/encapsulation) & [GeeksforGeeks](https://www.geeksforgeeks.org/encapsulation-in-java/) & [tutorialspoint](https://www.tutorialspoint.com/java/java_encapsulation.htm)</small>

### <a name="oop-encapsulation-in-java">Encapsulation in Java</a>
> Encapsulation in Java is achieved by
1. declare  fields of class as private
2. provide public setter an getter methods & modify and fields

```
public class EncapTest {
   private int age;

   public int getAge() {
      return age;
   }

   public void setAge( int newAge) {
      age = newAge;
   }
}
```

### <a name="java-tight-encapsulation">Tight Encapsulation</a>
> Class has only private variables / fields

<small> Reference: [SO](https://stackoverflow.com/questions/11653229/tightly-encapsulated-class#:~:text=if%20a%20class%20is%20having%20only%20private%20variables%20and%20no%20other%20public%20variables%20then%20a%20class%20is%20said%20to%20be%20tightly%20encapsulated%20class)</small>

### <a name="oop-polymorphism">OOP Pillar: Polymorphism</a>
> ability of object to take on many forms. 
- Compile-time Polymorphism /  Static polymorphism
  - method overloading 
- Runtime Polymorphism / Dynamic method dispatch
  - method overriding
<small> In Java, inheritance allows for polymorphism (method overriding) </small>

- Compile-time polymorphism (
  - static bining / early binding / overloading
  - object bound with their functionality at compile time
  - call is resolved by the compiler
    - <u> Fast execution</u>: method to be executed known early (at compile time)
    - <u> less flexible/u>: all things execute at compile time
  
- Run-time polymorphism
  - dynamic binding / late binding / overriding
  - object bound with functionality at run time
  - method invocation is determined by JVM not the compiler
    - <u>Slow execution</u>: method to be be executed only known at runtime
    - <u>more flexible</u> all things execute at runtime

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8bbbohi2om1jnppq662d.png)
<small> From: [GeeksforGeeks](https://www.geeksforgeeks.org/difference-between-compile-time-and-run-time-polymorphism-in-java/)</small> 

### <a name="polymorphism-method-overloading">Polymorphism: Method Overloading</a>
> Allows a class to have more than 1 method with:
- same name
- different number & types of argument list
At time of compilation, method calls get resolved by compiler (`javac`).
Also known as: compile-time polymorphism / early binding

There are 2 ways this can be performed
1. changing number of arguments
2. changing the data type

```
public void display(String info){
  System.out.println("String into");
}

// method overloading - change data type
public String display(int info){
  System.out.println(info);
  return "result";
}

public void display(String info1,String info2){
  System.out.println("2 information string");
}
```

When call `display` method compiler display results based on the arugments dev pass. 
- if argument is int
  - call `display(int)`
- argument is string
  - call `display(string)`
- type promotion can be performed (implicitly) if no matching type is found and if there is no ambiguity. 

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ipgzcmb9q6qtxvhs3w5y.png)

<u>Type Promotion Example</u>
if not matching data types found, one type promoted to another. 
```
public void sum(int a long b){
  System.out.println(a+b);
}

// second argment (int literal) will be promoted to long. 
sum(20,20); // 40
```

If there is ambiguity,
- no matching type aguments in metho
- each method promotes simliar number of arguments
```
public void sum(int a,long b){
  System.out.println("a method invoked");
}

public void sum(long a,int b){
  System.out.println("b method invoked");
}

//ambiguity
sum(20,20); // Compile Time Error
```
Now there is amiguity, both methods promote simliar number of arguments.



<u>Benefits</u>:
- increase readability of program
  - no need to create & remember different names for functions doing the same thing. 


<a name="method-overloading-conditions">Method Overloading Conditions</a>
<u>CANNOT</u>
- **not possible** by **changing return type of method only**
  - if only change return type but ethod signature remains same, there is ambiguity, which method should be called?
- **can't  overload** methods that **differ only by static keyword**
  - number of parameters, type of parameters & method name is same
  - same method signature -> not overlaoding
<u>CAN</u>
- can **overload main() method**
  - main() method usually received string array as arguments. 
  - but can overload main()method to receive no arguments / different arugments
- method overloading with **type promotion**
  - one type can be **promoted to another implicitly** if **not matching datatye found**.
  - one type **cannot be de-promoted** implicitly.
- can **overload static method**
  - can have >=2 static method with same name but difference in input parameters. 

<small> reference: [javatpoint](https://www.javatpoint.com/method-overloading-in-java) & [GeeksforGeeks](https://www.geeksforgeeks.org/overloading-in-java/) </small>

### <a name="polymorphism-method-overriding">Polymorphism: Method Overidding</a>
> allows subclass / child class to provide specific implementation of method that is already provided by by one of its super classes or parent classes
Subclass methods must have
- same name
- number & type of parameters
- retur type
JVM does the job of method resolution -->
Runtime polymorphism
Type of referred object determines which version of an overriden method will be executed


```
class Base {
  public void show(){}
}

class Derived extends Base {
  // method overriding
  public void show(){}
}
```

```
Derived der = new Derived();
der.show();
```
JVM first checkls if child class (Derived) has provided any implementation to method (show). 
yes -> call derived overriden method,
no -> call parent method

```
Base obj = new Derived();
obj.show();
```
reference if of Base type, however object is still of Derived type.
Method resolution takes place at runtime.
show method of Derived class is called. 

```
Derived obj = new Base(); // not valid
```
This is not valid. 
<a name="method-overriding-rules">Important</a>
<u>Important</u>
type of referred object etermine which version of overidden method will be executed **NOT typoe of reference variable**.
Runtime object determines which method will be called --> overiding = runtime polymorphism

<u>Rules</u>
- **MUST** have **same retur type** or at least *subtype of parent's return type*
<u>Exception Handling</u>
1. super class overriden method does not throw exception
  - sub class overridding method can only throw unchecked exception (i.e. exceptions that are not checked at ompile time)
2. super class overridding method throws exception
  - sub class overriding metho can only throw same subclass exception. 
<u>CAN</u>
- override access-modifiers
  - can *allow more but not less access* (eg. protected instance method can be made public but not privde in sub class)
- final methods cannot be overidden
  - final keyword prevents overriding
- call parent class method in overridding method
  - `super.method()`
- can override **abstarct method**
  - abstarct methods in interface / abstarct class are menat to be overidden in derived class
- can override synchronied / strictfcp method
<u>CANNOT</u>
- **static** methods cannot be overridden 
  - static method bound to class not object
  - static method with saae method signature in subclass is *method hiding NOT method overidding*.
- cannot override main method
  - main metod is static
- **private** methods cannot be overriden
  - private methods not inherited 
  - private methods bonded during compile time
- cannot override **constructor**
  - parent & child constructor can never have same name
  - constructors are not inhierited

  
<small> Reference: [GeeksforGeeks](https://www.geeksforgeeks.org/overriding-in-java/) & [javatpoint](https://www.javatpoint.com/method-overriding-in-java)</small>


### <a name="overriding-vs-hiding">Overriding VS Hiding (static methods)</a>

> static methods cannot be overidden. But they can be hidden. 
When child class has same static method as parent class. Static method  **hides** another static method. 
<u>Difference</u> Overriding gives run-time polymorphism, hiding does not.

Code example and explanation taken from coderanch:
```
class Foo {
    public static void classMethod() {
        System.out.println("classMethod() in Foo");
    }
 
    public void instanceMethod() {
        System.out.println("instanceMethod() in Foo");
    }
}
 
class Bar extends Foo {
    public static void classMethod() {
        System.out.println("classMethod() in Bar");
    }
 
    public void instanceMethod() {
        System.out.println("instanceMethod() in Bar");
    }
}
  
class Test {
    public static void main(String[] args) {
        Foo f = new Bar();
        f.instanceMethod(); // instanceMethod in Bar
        f.classMethod(); // classMethod in Foo
    }
}
```

<u>**instanceMethod(overriding)**</u>: JVM finds actual class of the instance *f* **at run-time** and determines which method to run. *f* is declared as *Foo* however class created is actually *Bar*. At run-time, JVM find that *f* is *Bar* instance and calls instanceMethod in Bar. 

<u>**classMethod(hiding)**</u>: class/static method. JVM wont expect to need an actual instance to invoke method. At **compile-time** compiler looks at *declared type (Foo)* of reference to decide which method to call. 

Therefore **static methods do not have run-time polymorphism**.

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hy1gdhom4wmqxyneab8a.png)
 
<small> References: [Stack Overflow](https://stackoverflow.com/a/5436790) & [CodeRanch](https://coderanch.com/wiki/659959/Overriding-Hiding) </small>

### <a name="oop-association-java">OOP Java: Association</a>
> Association is relation between 2 separate classes which establishes through their objects. Can be
- one-to-one
- one-to-many
- many-to-one
- many-to-many
Composition & aggreagation are 2 forms of association

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/v1pmta5h85eqza4a84ej.png)

####Aggregation
> special form of assocation
- *Has-A* relationship
- *unidirectional*
- parent can exist without the child & vice-versa

```
public class Foo {
  private Bar bar;
  Foo(Bar bar) {
    this.bar = bar;
  }
}
```
If Foo dies, object Bar can still "live".

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wz5kg36d5t9zget21s6t.png)
 
####Composition
> restricted form of aggreagation, 2 entities are **highly dependent on each other**
- *part-of-realtionship
- child object **cannot exist** without parent entity
- lifecycle of child is controlled by parent that owns it

```
public class House {
   private Room room;
   public House() {
       // without a house there can be no room, if house deleted, room is also deleted
       room = new Room();
   }
}
```


![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jf9noljykjigaguxp6ei.png)
 
<small>Reference: [GeeksforGeeks](https://www.geeksforgeeks.org/association-composition-aggregation-java/) & [infoworld](https://www.infoworld.com/article/3029325/exploring-association-aggregation-and-composition-in-oop.html)</small>
 

### <a name="oop-coupling-java">OOP Java: Coupling</a>
> measure of how much class is dependent on other classes
There should be iminmal dependencis -> low coupling

### <a name="oop-cohesion-java">OOP Java: Cohesion</a>
> measure of how related responsibilitie of class are
class must be highly cohesive (responsibilties shuold be highly related to one another) 

### <a name="runtime-exception">Exceptions handled</a>
> Java Exception Handling frameowork **handles runtime exceptions only**. Compile time exceptions must be handled by developer or else code wont run

<small>Reference: [JournalDev](https://www.journaldev.com/1696/exception-handling-in-java#:~:text=Core%20Java,errors%20only)</small>


### <a name="exception-handling-keyword">Exception Handling: keywords</a>
> - throw
-throws
-try-catch
-finally

- throw
  - used inside function / block of code
  - to explicitly throw an exception in the rpgoram
- throws
  - used in method signature
  - declare exception that might get thrown by method & method will not be handling it.
- try-catch
  - code block for excpetion handling in code
  - can have multiple catch blocks with a try block
  -can be nested
- try
  - start of block
- catch
  - end of try block to handle exceptions
  - required parameter that should be of type Exception
  - java 7 automatic resource management (catch many resource in 1 catch block)
  - `catch(IOException | SQLException ex){}`
- finally
  - **optional** 
  - **always gets executed wheter exception occured or not**
    - onlt NOT executed if exception thrown in finally or if JVM crashes in between (`System.exit()`)
  - can be used with try catch block
  - since exceptions halts process of execution, may have some resources open that will not get closed, close them in finally block

###<a name="java-exception-hierarchy">Java Exception Hierarchy</a>
> When exception is raise, an exception object is geting created.
*Throwable* is parent class of Java Exceptions Hierarchy & has 2 chid objects
- Error
- Exceptions
  - checked exceptions
  - runtime exceptions

Java Exceptions are hierarchichal & inheritance used to categorize different types of exceptions

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j6nco9dm0xr0zhq3y7al.png)

- **Errors**
  - not possible to anticipate or recover from them (fatal)
      - hardware failure
      - OutOfMemoryError
      - StackOverflowError
- **Exceptions**
  - errors that can be anticiapted & recovered from
- **Checked Exceptions**
  - exceptions checked at compile time
  - sually occures when interacting with outside resources
    - FileNotFoundException
    - IOException
- **Runtime Exception**
  - exceptions not checked at compile time
  - usually due to bad programming / mistakes
    - get element from array but give wrong index
    - ArrayIndexOutOfBound, Arithemetic Exception
 
###<a name="java-unchecked-vs-runtime-exception">Java Unchecked VS Runtime Exception</a>
> CheckedException: 
- mandatory to provide try-catch / try-finally block
- force by compiler
- dealing with outside resoruces / networks
Runtime exception: not mandatory
- occur during runtime
  - programming errors

- Checked Exception
  - if not handled, will result in compile time errors
      - either handle with try-catch/  try-finally block or specify method uses `throws`
  - usually error scenarios outside immediate control of program
  - usually interacting with touside resources /networks
     - data base / network 
  - eg.`ClassNotFoundException`, `IOException`, `SQLException`, `FileNotFound`
- RuntimeException
  - **not checked by compiler**
  - will occur once buggy code is executed
  - method not forced to delared unchecked exception thrown
  - eg. `ArithmeticExcetion`, `ArrayStoreException`, `NullPointerException`


<u>Extend from CheckedExcetion or Runtime Excpetion?</u>
Checked Exception
  - method likely to fail 
  - Checked Exception to ensure alternalte processing in case of failure (enforces proper error handling)
Runtime Exception

BUT
 - can make code ugly (lots of boilerplate code)


<small> reference: [GeeksforGeeks](https://www.geeksforgeeks.org/checked-vs-unchecked-exceptions-in-java/) VS [java67](https://www.java67.com/2012/12/difference-between-runtimeexception-and-checked-exception.html) & [javadocs](https://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html)</small> 


###<a name="java-exception-class-methods">Java Exception Class Methods</a>
> all methods depend on parent `Throwable` class
- String getMessage()
- String getLocalizedMessage()
- synchronized Throwable getCause()
- String toString()
- void printStackTrace()

- getMessage()
  - message String of Throwable
  - message provided when creating exception through constructor
- getLocalisedMessage()
  - subclass can override it to provide locale-specific message to calling program
- getCause()
  - cause of exception or null if cause is unnown
- toString()
  - name of throwable class & localised message
- printStackTarce()
  - prints the stack trace information to the standard error stream 
  - is overloaded and can pass PrintStream or PrintWriter as an argument to write the stack trace information to file or stream

###<a name="java-exception-handling-criteria">Java Exception Handling Criteria</a>

<u>ALLOWED</u>
- finally can still be executed if try & catch have return statements
- try without catch is allowed (`try{}finally{}`)

<u>NOT ALLOWED</u>
- try without catch & without finally 



###<a name="java-exception-handling-best-practice">Java Exception Handling Best Practice</a>

- Use Specific Exceptions
  - dont throw base exception class
- throw early / fail fast
  - throw exception as early as possible 
- catch late
  - throw exception to caller
  - let caller decide how to handle & caller can get notification for exception
- closing resources
  - close all resources i finally block 
  - java 7 [try-with-resources](https://www.baeldung.com/java-try-with-resources) block 
  - eg. `try (Scanner scanner = new Scanner(new File("test.txt"))) {scanner.doSomething()}`
- log exceptions
  - log exception messages when throwing exceptions
- single catch block for multiple exceptions
  - `catch(SQLException|AnotherException ex){}`


<small> Reference: [JournalDev](https://www.journaldev.com/1696/exception-handling-in-java#:~:text=Best%20Practices,Specific%20Exceptions) </small>

###<a name="uml-class-diagram">UML Class Diagram</a>

Designing the class
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5i1pphpocvmf8g452h22.png)
 

Association
> very generic term
one class used functionalities provided by another class
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/imo9cmv6wxai3n8bzgnb.png)

Composition
> **part-of** 
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/udolq2bfv2coye177kxz.png)

Aggregation 
> one object "owns" another object but child can exist without parent
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/otjsajyfadsl1wfl2nhp.png)
 

Multiplicty
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6r8zx57870lrlb54r9ux.png)
 
Generalization / Inheritance / Abstraction
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1g1kv9hmgntia6jq1bi0.png)

<small> [source](https://www.visual-paradigm.com/guide/uml-unified-modeling-language/uml-aggregation-vs-composition/) </small>


###<a name="uml-sequence-diagram">UML Sequence Diagram</a>
> denote how objects and classes with code interact with each other
show **sequence of the events**

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jymqg3nbpthu6fhm4u8u.png)

###<a name="oop-design-patterns">OOP: Design Patterns</a>
> basket of pre designed solutions / blueprints to common patterns in OOP or to solve given design problem in code. 

Creational: creating objects
Structural: composition of classes & objects which form larger structures
Behaviour: responsibility & interaction between objects 

 
###<a name="singleton-design-pattern">Singleton Design Pattern</a>
> restricts instantiation of class to one. Ensure only 1 instance of class exists in JVM.
<u>Used for</u>: logging, drivers object, cahcing & thread pool. 
<u>Implementation</u>
1. private construtor to restrict instantiation of class from other classes
2. private static variable of same class that is only instance of class
3. public static method `getInstance()` returning instance of class, so other classes can get instance of singleton

Techniques:
- Eager initialization - create singleton BEFORE its used
  - `public static final SingletonClass instance = new SingletongClass()`
  - use `static` block
- Lazy Initlialization
  - creates instance in `getInstance()` method. can cause issues in *multithreaded* environment
- Thread Sage singleton (for laxy initialization)
  - make `getInstance()` method `synchronized` so only 1 thread executes this method at a time
- use Enum to declare singleton
  - Java ensures any enum value only instantiated once. *does not allow lazy initialization*. `public enum EnumSingleton{INSTANCE;}`
- Serialization & singleton
  - implement `readResolve()` method. When implement serializable interface, when deserialize singleton class, new instance of object is created. `protected Object readResolve() {return getInstance()}`


![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tqrwutqcmnqiod6dsxj0.png)
 

<small> Reference: [vainolo](https://vainolo.com/2012/04/29/singleton-design-pattern-sequence-diagram/) & [journalDev](https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples)</small>

###<a name="factory-design-pattern">Factory Design Pattern</a>
> define an interface or abstract class for creating an object but let the subclasses decide which class to instantiate
Responsibility of instantiation is on *factory class* not *client program*.

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zu09l9s39kiiu8jl3d1s.png)
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9tlijortx4sknrbghe9f.png)
 

Implementation
- super class (`Computer`) can be interface , abstart class or normal class
- Factory class can be singleton or can keep the method returning classes (`getComputer`) as static. 
  - very troublesome to keep instantiating factory clas
- based on input parameter, different subclass created & returned


```
public class ComputerFactory {

	public static Computer getComputer(String type, String ram, String hdd, String cpu){
		if("PC".equalsIgnoreCase(type)) return new PC(ram, hdd, cpu);
		else if("Server".equalsIgnoreCase(type)) return new Server(ram, hdd, cpu);
		
		return null;
	}
}
```


 
Advantage
- remove instantiation of actual classes from client code
- layer of abstraction between implementation classes(`PC` & `Server`) & client code (`ComputerFactory`

<u> Abstract Factory </u>
Abstarct factory is like a factory of factories. 

<small>Reference: [javatpoint](https://www.javatpoint.com/factory-method-design-pattern)&  [JouralDev](https://www.journaldev.com/1392/factory-design-pattern-in-java) & [tutorialspoint](https://www.tutorialspoint.com/design_pattern/factory_pattern.htm) </small>


###<a name="decorator-desgin-pattern">Decorator Design Patterns</a>
> Add new features to existing object with changing its structure
Decorate class wraps original class & provides additional functionality, keeping class methods signature intact 
- *uses abstract classes or interface with **composition** to implement*

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b73zmh25a0ippk1qq9h6.png)
 
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/useas80fsvkt0z3bupia.png)

Decorator class implements HAS-A relationship with component interface. Concrete Decorators will extend base decorator functionality & modify component behaviour. 

```
// Component Implementations
public class BasicCar implements Car {

	@Override
	public void assemble() {
		System.out.print("Basic Car.");
	}

}

// Decorator
public class CarDecorator implements Car {

	protected Car car;
	
	public CarDecorator(Car c){
		this.car=c;
	}
	
	@Override
	public void assemble() {
		this.car.assemble();
	}

}

// Concrete Decorator
public class SportsCar extends CarDecorator {

	public SportsCar(Car c) {
		super(c);
	}

	@Override
	public void assemble(){
		super.assemble();
		System.out.print(" Adding features of Sports Car.");
	}
}
public class LuxuryCar extends CarDecorator {

	public LuxuryCar(Car c) {
		super(c);
	}
	
	@Override
	public void assemble(){
		super.assemble();
		System.out.print(" Adding features of Luxury Car.");
	}
}

// Testing Decorator Program
Car sportsCar = new SportsCar(new BasicCar());
sportsCar.assemble(); 
// Basic Car Adding features of Sports Car
		System.out.println("\n*****");
		
Car sportsLuxuryCar = new SportsCar(new LuxuryCar(new BasicCar()));	sportsLuxuryCar.assemble(); 
// Basic car. Adding features of Luxury Car. Adding Features of SportsCar. 
```


<small> Reference: [Baeldung](https://www.baeldung.com/java-decorator-pattern) & [tutorialspoint](https://www.tutorialspoint.com/design_pattern/decorator_pattern.htm) & [JournalDev](https://www.journaldev.com/1540/decorator-design-pattern-in-java-example) </small>

###<a name="flyweight-design-pattern">Flyweight Design Pattern</a>
> factory which recycles created objects by storing them after creation. Existing object is returned otherwise new one created.
**Flyweight objects must be immutable, any operation on state must be performance by factory**.
<u>Benefits</u>
- decrease memory footprint
- increase performance

<u> When to use </u>
- number of object to be created by application should be huge
- object creation heavy on memory & can be time consuming
- flyweight object must be divided into **intrinsic** & **extrinsic**. Intrinsic properties make object nuique, extrinsic properties are set by client code & used to perform different operations. 

<small> Reference: [Baeldung](https://www.baeldung.com/java-flyweight) & [tutorialspoint](https://www.tutorialspoint.com/design_pattern/flyweight_pattern.htm) & [JournalDev](https://www.journaldev.com/1562/flyweight-design-pattern-java) </small>


###<a name="adapter-design-pattern">Adapter Design Pattern</a>
> act as connector between 2 incompatible interfaces that otherwise cannot be connected directly. 
2 implementations
- class adapter
  - uses **inheritance** & extends adaptee interface
  - single class called adaptor between 2 incompatible interfaces
- object adapter
  - uses **composition** & adapter contains adaptee object. 
  - wraps around class, allowing 2 classes / interface to work together without changing any code on either side. 

<u> Object Adapter</u>
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ogt558q6r8in5dldzhkn.png)
- Client can only see target
- adapter class implements target interface & provides implementation for `Request()`
- adapter is **composed** with adaptee 

<u> Process </u>
- Client makes call to adapter
- adapter does conversion
- makes rqeuired call to adaptee

```
public class SocketObjectAdapterImpl implements Targer{

//Using Composition for adapter pattern
	private Adaptee sock = new Adaptee ();
	
	@Override
	public Volt get120Volt() {
		return sock.getVolt();
	}

	@Override
	public Volt get12Volt() {
		Volt v= sock.getVolt();
		return convertVolt(v,10);
	}

	@Override
	public Volt get3Volt() {
		Volt v= sock.getVolt();
		return convertVolt(v,40);
	}
	
	private Volt convertVolt(Volt v, int i) {
		return new Volt(v.getVolts()/i);
	}
}
```

<u>Class Adapter</u>
 ![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ra8x008gygn4w2szngx4.png)
- adaptor implements target
- inherits adaptee

<u> Process </u>
- Client makes call to adapter
- adapter **DOES NOT** delegate request to adaptee
- adapter uses **inherited method** (`SpecificRequest()`) from adaptee to handle specific request

```
//Using inheritance for adapter pattern
public class SocketClassAdapterImpl extends Adaptee implements Targer{

	@Override
	public Volt get120Volt() {
		return getVolt();
	}

	@Override
	public Volt get12Volt() {
		Volt v= getVolt();
		return convertVolt(v,10);
	}

	@Override
	public Volt get3Volt() {
		Volt v= getVolt();
		return convertVolt(v,40);
	}
	
	private Volt convertVolt(Volt v, int i) {
		return new Volt(v.getVolts()/i);
	}

}
```

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p4gt5jhpm36f6dcee470.png)


<small> [JournalDev](https://www.journaldev.com/1487/adapter-design-pattern-java) & [GeeksforGeeks](https://www.geeksforgeeks.org/adapter-pattern/) </small>

###<a name="observer-design-pattern">Observer Design Pattern</a>
> *one-to-many* dependency between objects so when 1 object (subject) changes state, all of its dependents (observers) are notified & updated automatically.

eg. wishlist item is out of stock, tell website to notify you when it is in stock.
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r3s497ri0g2oikegvyzd.png)

```
// subject
public interface Subject {

//methods to register and unregister observers
  public void register(Observer obj);
  public void unregister(Observer obj);
	
//method to notify observers of change
  public void notifyObservers();
	
//method to get updates from subject
  public Object getUpdate(Observer obj);
}

// object
public interface Observer {
	
//method to update the observer, used by subject
public void update();
// observers will print updated subject in this method
	
//attach with subject to observe
public void setSubject(Subject sub);
}

public class MyTopic implements Subject {

	private List<Observer> observers;
	private String message;
	private boolean changed;
	private final Object MUTEX= new Object();
	
	public MyTopic(){
		this.observers=new ArrayList<>();
	}
	@Override
	public void register(Observer obj) {
		if(obj == null) throw new NullPointerException("Null Observer");
		synchronized (MUTEX) {
		if(!observers.contains(obj)) observers.add(obj);
		}
	}

	@Override
	public void unregister(Observer obj) {
		synchronized (MUTEX) {
		observers.remove(obj);
		}
	}

	@Override
	public void notifyObservers() {
		List<Observer> observersLocal = null;
		//synchronization is used to make sure any observer registered after message is received is not notified
		synchronized (MUTEX) {
			if (!changed)
				return;
			observersLocal = new ArrayList<>(this.observers);
			this.changed=false;
		}
		for (Observer obj : observersLocal) {
			obj.update();
		}

	}

	@Override
	public Object getUpdate(Observer obj) {
		return this.message;
	}
	
	//method to post message to the topic
	public void postMessage(String msg){
		System.out.println("Message Posted to Topic:"+msg);
		this.message=msg;
		this.changed=true;
		notifyObservers();
	}

}

//create subject
MyTopic topic = new MyTopic();
		
//create observers
Observer obj1 = new MyTopicSubscriber("Obj1");
Observer obj2 = new MyTopicSubscriber("Obj2");
Observer obj3 = new MyTopicSubscriber("Obj3");
		
//register observers to the subject
topic.register(obj1);
topic.register(obj2);
topic.register(obj3);
		
//attach observer to subject
obj1.setSubject(topic);
obj2.setSubject(topic);
obj3.setSubject(topic);
		
//check if any update is available
obj1.update(); // Obj1:: No new message
		
//now send message to subject
topic.postMessage("New Message");

// OUTPUT
Message Posted to Topic:New Message
Obj1:: Consuming message::New Message
Obj2:: Consuming message::New Message
Obj3:: Consuming message::New Message
```
 
[Mutex subject](https://docs.oracle.com/javase/tutorial/essential/concurrency/newlocks.html) in code snippet is used for locks

<u>Sequence Diagramm</u>
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vun11twd1b0r1rkpdfcp.png)
 
 





<small>Reference: [vogella](https://www.vogella.com/tutorials/DesignPatternObserver/article.html) & [JournalDev](https://www.journaldev.com/1739/observer-design-pattern-in-java) & [Baeldung](https://www.baeldung.com/java-observer-pattern) & [tutorialspoint](https://www.tutorialspoint.com/design_pattern/observer_pattern.htm)</small>

###<a name="strategy-design-pattern">Strategy Design Patterns</a>
> class behaviour or algorithm can be changed at runtime.
eg. `Collections.sort()`
2 ways:
- interface & implement many times
  - start with interface which is used to apply an algorithm
  - implement it multiple times for each possible algorithm
- Java 8 & lambdas
  - use lambda in place of anonymous inner type

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r5aq7vj4b13ga1kiq10d.png)

<u> Interface & Implementations </u>
```
// Startegy interface
public interface Strategy {
   public int doOperation(int num1, int num2);
}

// Startegy concrete classes
public class OperationAdd implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
      return num1 + num2;
   }
}
public class OperationSubstract implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
      return num1 - num2;
   }
}
public class OperationMultiply implements Strategy{
   @Override
   public int doOperation(int num1, int num2) {
      return num1 * num2;
   }
}

// use context to call & execute startegy interface
public class Context {
   private Strategy strategy;

   public Context(Strategy strategy){
      this.strategy = strategy;
   }

   public int executeStrategy(int num1, int num2){
      return strategy.doOperation(num1, num2);
   }
}

Context context = new Context(new OperationAdd());		
      System.out.println(context.executeStrategy(10, 5)); // 15

context = new Context(new OperationSubstract());		
      System.out.println(context.executeStrategy(10, 5)); //5 

context = new Context(new OperationMultiply());		
      System.out.println(context.executeStrategy(10, 5)); // 50
```


<u> Using Java Lambdas </u>
Java 8 can create static methods in interfaces
```
public interface Discounter {
    BigDecimal applyDiscount(BigDecimal amount);

    static Discounter christmasDiscounter() {
        return amount -> amount.multiply(BigDecimal.valueOf(0.9));
    }

    static Discounter newYearDiscounter() {
        return amount -> amount.multiply(BigDecimal.valueOf(0.8));
    }

    static Discounter easterDiscounter() {
        return amount -> amount.multiply(BigDecimal.valueOf(0.5));
    }
}
```

 

<u> Sequence Diagram </u>
![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yedw6xsauy422uc2qk8b.png)
 

<small> Reference: [Baeldung](https://www.baeldung.com/java-strategy-pattern) & [tutorialspoint](https://www.tutorialspoint.com/design_pattern/strategy_pattern.htm) & [JournalDev](https://www.journaldev.com/1754/strategy-design-pattern-in-java-example-tutorial) </small>



###<a name="state-design-pattern">State Design Patterns</a>
> allows object to change its behaviour (during run time) when the internal state of the object changes.
- used when: object depends on its state & behaviour must be changed during run time depending on its internal state. 
Implementation
**allow object to change its behaviour without changing its class**

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rs96f7y9hb14e6masog0.png)
Context object will change its behaviour based on its internal state.
Context object will have an associated state which can change during program execution
Context will **delegate behaviour to state implementation**. 

Example: TV remote can be on or off
```
// Staet interface 
public interface State {
	public void doAction();
}

// State implementations
public class TVStartState implements State {

	@Override
	public void doAction() {
		System.out.println("TV is turned ON");
	}

}

public class TVStopState implements State {

	@Override
	public void doAction() {
		System.out.println("TV is turned OFF");
	}

}

public class TVContext implements State {

	private State tvState;

	public void setState(State state){
		this.tvState=state;
	}

	public State getState() {
		return this.tvState;
	}

	@Override
	public void doAction() {
		this.tvState.doAction();
	}

}


TVContext context = new TVContext();
State tvStartState = new TVStartState();
State tvStopState = new TVStopState();
			context.setState(tvStartState);
context.doAction(); // TV is turned on	
		context.setState(tvStopState);
context.doAction(); // TV is turned off
```

![alt text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e01sylybgj4wy7zyrsmf.png) 



<small>Reference: [Baeldung](https://www.baeldung.com/java-state-design-pattern) & [tutorialspoint](https://www.tutorialspoint.com/design_pattern/state_pattern.htm) & [JournalDev](https://www.journaldev.com/1751/state-design-pattern-java) & [DZone](https://dzone.com/articles/state-design-pattern-in-java) </small>