java

Java
=============
jshell > to run java code

jshell> /help
jshell> /list
jshell> System.out.println("Hello World!")
Hello World!

=============
primitive types
---------------
byte
short
int
long
float
double
char
boolean

====================
* you can use '_' in int values
int minVal = -2_147_483_648; // 32 bit (4 bytes) (2^31) // Integer.MIN_VALUE;
int maxVal = 2_147_483_647; // Integer.MAX_VALUE;
byte minByteVal = -128; // 8 bit (1 byte)
byte maxByteVal = 128;
short minShortVal = -32767; // 16 bit (2 bytes)
long minLongVal = 100L // 64 bit (8 bytes) (2^63)

long 

A numeric literal that exceeds Integer.MAX_VALUE must use the 'L' suffix.
We cannot create a numeric literal in java, that exceeds Integer.MAX_VALUE, without using the 'L' suffix, we'll always get the error 'integer number too large'.

long bigLongVal = 2_147_483_647_234 // Error: integer number too large
long bigLongVal = 2_147_483_647_234L // no error as we added "L"

type casting
-------------
byte myByteval = (byte)

*Long can hold int, so no need to type cast.

int k = 5 / 3 ; // 1 // 32 bit (4 bytes)
float x = 5f / 3f; // 1.6666666 // 32 bit (4 bytes)
double y = 5d / 3d; // 1.6666666666666667 //64 bit (8 bytes)

for mathematical calculations use double
1. faster on lot of computers
2. java inbuilt functions uses double
3. more precise, 16 digits of precision

char myChar = 'D'; 16 bits (2 bytes) // use single quotes
char myChar = '\u0044'; // D
char myChar = 68'; // D

boolean flag = false; // how many bits? It's virtual machine dependent.



String : is a sequence of characters // use double quotes

Method Overloading:
--------------------
. Method overloading is a feature that allows us to have more than one method with the same name, so long as we use different parameters.
. It is the ability to create multiple methods of the same name with different implementations.
. Calls to an overloadded method will run a specific implementation of that method.

- It improves code readability and re-usability
- It is easier to remember one method name instead of remembering multiple names.
- Achievs consistency in naming. One name for methods that are commonly used for example println.
- Overloaded methods give programmers the flexibility to call a similar method with different types of data.

 * When converting primitive types you can type cast as below;
double x = 2019.4d;
int y = (int) x;

 * When converting non-primitive types you need to typecast as below;
String eId = "65464";
    int id = Integer.parseInt(eId); // here "Integer" is a wrapper class

Reading User input from console
---------------------------------
import java.util.Scanner;

public class Hello {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("Ent: ");
        String name = scanner.nextLine();
        System.out.println("name: " + name);
        scanner.close();
    }
}

Calling another constructor from a constructor
--------------------------------------------------
this(...)
- to call a constructor from another overloaded constructor in the same class
- should be called with in a constructor, and must be the first statement.
super(...) // calling super class constructor

this() example;
-----------------
public class Car {
private String model;
public Car(){
// if the user doesn't provide property values while creating the object,
// we need to set the default values by calling the parameterized constructor with this()
this("Alto");
}
public Car(String model) {
this.model = model;
}
}

* Even Abstract classes have construcotrs, although you can never instantiate an abstract class using the new keyword.
* An abstract class is still a super class, so its constructors run when someone makes an instance of a concrete subclass.
* A constructor can have a call to super() or this() but never both.

Method Overriding
----------------------
. Method overriding means defining a method in a child class that already exists in the parent class with same signature(same name, same arguments)
. It must have same name and same arguments
. It can't have a lower access modifier.
. For example if the parent method is protected then using private in the child is not allowed but using public in the child wourld be allowed.
. Constructors and private methos can't be overridden.
- Methods that are final can't be overridden.
@Override is an annotation, that the compiler reads and will then show us an error if we don't follow overriding rules correctly.

Static Methods
--------------
- Whenever you see a method that does not use instance variables that method should be declared as a static method.

Static variables
----------------
When you declare a static variable in a class, all the objects of that class will share the same value, any object updates the static varibale, then all the objects will get the same updated value.

we can access static variables and methods in non-static context.

> java.lang.Object
---------------------
 * Class {@code Object} is the root of the class hierarchy.
 * Every class has {@code Object} as a superclass. All objects,
 * including arrays, implement the methods of this class.

Inheritance
-------------
- In inheritance you extend the class from another class.
- Inheritance is an "is-a" relationship.
- In java you can only inherit from one super class at a time (but you can implement many interfaces)

Composition
--------------
- You do composition by having an instance of another class C as a field of your class, instead of extending C.
- Creating Objects with in Objects
- Composition is a "has-a" relationship.
- As a general rule, when you're designing your programs, you probably wanna look at using composition before inheritance.
- It gives more flexibility and added advantages.

composition creates has-a or uses-a or can-do relationships, inheritance creates is-a relationship.

Inheritance vs Composition
---------------------------
Inheritance is an "is-a" relationship. Composition is a "has-a" relationship.
In inheritance you extend the class from another class.
You do composition by having an instance of another class C as a field of your class, instead of extending C.

Example: Car has a Engine and Car is a Automobile

In programming this is represented as:

class Engine {} // The Engine class.

class Automobile {} // Automobile class which is parent to Car class.

class Car extends Automobile { // Car is an Automobile, so Car class extends Automobile class.
  private Engine engine; // Car has an Engine so, Car class has an instance of Engine class as its member.
}

Encapsulation
------------------
- is the mechanism that allows you to restrict access to certain components in the objects that you are creating. So, you're able to protect the members of a class from external access in order to guard against unauthorized access.


Polymorphism
---------------
- allows actions to act differently based on the actual object that the action is being performed on.

Arrays
-------
int[] intArray = new int[10]; // 0's will be stored by default for int type arrays, for strings null will be stored, for boolean false will be stored.
int[] myIntArray = {1,2,3,4,5};
double[] myDoubleArray = new double[10];

References types vs Value Types
---------------------------------
All the primitive types are Value Types, that means they hold the value.
Array & Strings are reference types.

ArrayList
----------
(add, get, set, remove, contains, indexOf) // methods will be used

ArrayList<String> groceryList = new ArrayList<String>();
groceryList.add("Tamatos");
groceryList.add("Alu");
System.out.println(groceryList.get(0)); // Tamatos
System.out.println(groceryList.toString()); // [Tamatos, Alu]
groceryList.set(0, "Carrot");
System.out.println(groceryList.get(0)); // Carrot
groceryList.remove(1); // Alu will be removed
System.out.println(groceryList.toString()); // [Carrot]
groceryList.add("Mirchi");
groceryList.contains("Carrot"); // true
groceryList.contains("Tamatos"); // false
groceryList.indexOf("Carrot"); // 0 (returns the index)
groceryList.indexOf("Tamatos"); // -1
groceryList.add(1, "Beans"); // add at index

Wrapper Class
--------------
A wrapper class wraps (encloses) around a data type and gives it an object appearance. Wherever, the data type is required as an object, this object can be used.

Wrapper classes also include methods to unwrap the object and give back the data type.

There are eight wrapper classes available in java.lang package
Byte
Short
Integer
Long
Float
Double
Character
Boolean

You can not directly put primitives into Collections, instead, you first need to convert them into Object and then you can put theme into Collections. Wrapper classes like Integer, Double and Boolean hepls for converting primitive to Object.

Autoboxing & Unboxing
---------------------------
When Java automatically converts primitive type into corresponding wrapper class object like int to Integer, it is callsed autoboxing because primitive is boxed into wrapper class.
While opposite case is called unboxing, where an Integer Object is converted into primitve int.

This is whole process happens automatically without writing any code for conversion its called autoboxing and auto-unboxing.

Compiler uses valueOf() method to convert primitive to Object and uses xxxValue() i.e intValue(), doubleValue() etc to get primitive value from Object.

Integer intValue = 59; // Integer.valueOf(59) will be called while compiling
int x = intValue; // here intValue is an Object, Integer.intValue() will be called

Iterator
-------------
public static void main(String[] args) {
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("Naresh");
linkedList.add("Saresh");
linkedList.add("Earesh");
linkedList.add("Taresh");
linkedList.add("Aaresh");

Iterator<String> i = linkedList.iterator();
while(i.hasNext()) {
System.out.println(i.next());
}
}

ListIterator
----------------
LinkedList<String> cities = new LinkedList<>();

ListIterator<String> stringListIterator = cities.listIterator();
while(stringListIterator.hasNext()) {
sout(stringListIterator.next());
// stringListIterator.previous()
// stringListIterator.next().compareTo()
}

Inner Classes
---------------
package com.luv2code

public class Main {
public static voic main(String[] args) {
Gearbox mcLaren = new Gearbox(6); // Gearbox class has 'Gear' inner class
Gearbox.Gear first = mcLaren.new Gear(1, 12.3); // creating inner class object
}
}

// how to access outerclass property inside inner class, if innerclass has a property with same as outerclass
# OuterClass.this.sessionId
# OuterClass.this.calculate()

// scoping in innerclasses
* innerclass private properties can be accessed from outerclass

public OuterClass {
public void accessInnerPvtProperty(){
InnerClass innerClass = new InnerClass();
System.out.println("InnerClass pvt prop: " + innerClass.myPvtProperty); // here we are accessing private property from outside the class
}
public InnerClass {
private myPvtProperty = 9;
}
}

public static void main(String[] args){
OuterClass outerClass = new OuterClass();
outerClass.accessInnerPvtProperty(); // InnerClass pvt prop: 9

OuterClass.InnerClass innerClass = OuterClass.new Innerclass();
innerClass.myPvtProperty;
System.out.println("InnerClass pvt prop: " + innerClass.myPvtProperty); // this will give error
}

Interfaces
-------------
since java 8 Interfaces can contain default methods. In other words methods with implementation. the keyword default is used and static methods as well.
Since Java 8 an Interface can also contain private methods (commonly used when two default methods in an Interface share common code).

* All Interface properties & methods by default public static final (you should't create private properties or methods)

package com.company;
interface Accessible { // default access modifier (only accessible within the package)
int SOME_CONSTANT = 100; // this is automatically a public (public static final if you don't provide)
public void methodA(); // public
void methodB(); // public
boolean methodC(); // public
}

Generics
-------------
public class Team<T extends Player & Singer & Dancer> { // T (type of) Player (Abstrcat class) or Singer Interface or Dancer Interface
...
}

# something like <T extends MyInterface & MyAbstractClass>

Team<BaseballPlayer> baseballTeam = new Team<>("Chicago Cubs");
baseballTeam.addPlayer(pat);

Scope
===================

#Object Level
---------------
public - the object is visible to all classes everywhere, whether they are in the same package or have imported the package containing the public class.

default (package-private) - the object is only available within its own package (and is visible to every class within the same package). Package-private is specified by not specifying, i.e., it is the default if you do not specify public. There is not a "package-private" keyword.

# Member level
---------------
public - A public class member and public method can be accessed from any other class anywhere, even in a different package.

package-private(default) - properties



Static
=========
- static variable is associated with Class rather than any particular instance of the class.
- static methods can't access the non-static class properties and methods.
- but non-static methods can access the static methods and variables.

Final
=========
- final variables once initialized can't be changed, used to store constant values.
- final class, you can prevent a class from subclassed, not possible to create a subclass from a final class.
- final methods, can't be overridden from subclass.

Static Initializer
=====================
static {
... // initialize static variables
}

- static block will be called before the constructor
- you can have any number of static blocks before and after the constructors

public class StaticBlockTest {
public static final String owner;

static {
owner = "nare";
sysout("1st static block called");
}

public StaticBlockTest(){
sysout("constructor called");
}

static {
sysout("2nd static block called");
}
}

public static void main(){
StaticBlockTest sb = new StaticBlockTest();
}

// output
1st static block called
2nd static block called
constructor called