java-training/src/IntroToJava.java
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class IntroToJava {
    public int len = 2;

    public int test() {
        return 9;
    }

    public static void main2(String[] args) {
        // instantiating an object of class AccessSpecifiers
        AccessSpecifiers test = new AccessSpecifiers();

        // setting an instance field of test variable to 2
        test.a = 2;

        System.out.println("Hello world!");

        // java is strongly typed => specify what datatype a variable stores beforehand
        // 8 data types in java, below 5 are frequently used
        int x2 = 2;
        long m = 4L;
        double z = 4.6;
        boolean n = true;
        char ch = 'A';

        int a = 2;
        int b = 4;
        int sum = a + b;

        System.out.println(sum + " is sum");

        int fixOp = (++sum * 2);

        System.out.println(fixOp + " is fixOp");

        System.out.println(sum + " is sum");

        // ternary operator
        // condition ? return_this_if_true : return_this_if_false
        int x = (a + b == 6) ? 2 : 8;

        // switch condition
        // subset of if-else (for single variable)
        int seasonCode = 2;
        String seasonName = switch (seasonCode)
        {
            case 0 -> "Spring";
            case 1 -> "Summer";
            case 2 -> "Fall";
            case 3 -> "Winter";
            default -> "???";
        };

        System.out.println(seasonName + " is seasonName");

        // enums
        enum Size { SMALL, MEDIUM, LARGE, EXTRA_LARGE };

        int sum2 = (2 + 3) * 5 / 3;

        // strings are immutable
        // once created we cannot change the character at some location in the string
        // the only way is to create a new string
                    //01234
        String str = "abcde";

        char ch2 = str.charAt(3);

        System.out.println(ch2 + " is char at 3");

        System.out.println(str.substring(2, 4));

        String str2 = "blablabla";

        System.out.println(str.length());

        System.out.println(str + " " + str2);

        // arrays and initializing them

        int[] arrayOfInts = new int[7];
        int[] smallPrimes = new int[] {2, 3, 5, 7, 11};

        // array utility function are present in java.util.Arrays
        // here we used one of them - Arrays.toString()
        // Arrays.toString() loops throught the array and returns a string by concatenating all the elements
        System.out.println(Arrays.toString(smallPrimes));

        arrayOfInts[3] = 8;

        // this prints the address of the string
        System.out.println(arrayOfInts);

        // loop through the array using the enhanced for-each loop
        for (int arrayOfInt : arrayOfInts) {
            System.out.println(arrayOfInt);
        }

        System.out.println(Arrays.toString(arrayOfInts));

        String str3 = new String("abcde");

        System.out.println(str);
        System.out.println(str3);

        // always compare strings using .equals() and not ==
        // == checks only the address of the strings
        // the same thing applies to any object comparision
        // use .equals (implement it yourself for custom classes) for checking equality between objects
        if (str.equals(str3)) {
            System.out.println("Are equal");
        } else {
            System.out.println("Not equal");
        }

        // BigInteger class to deal with very large integers
        // int and long classes have a limit - 4 and 8 bytes
        // for even bigger numbers, use BigInteger
        BigInteger reallyBig
                = new BigInteger("222232244629420445529739893461909967206666939096499764990979600");

        reallyBig = reallyBig.add(new BigInteger("1"));

        System.out.println(reallyBig);

        // int, double, boolean - primitive data types

        // Collections like List, Set, Map are implemented with generics
        // Generics => without specifying the type so that it can be used with any datatype
        // ex: the same ArrayList implementation is used for integers and characters with
        // ArrayList<Integer> and ArrayList<Character>
        // and when creating the function they use a generic type like E -> ArrayList<E>
        // ... which can be plugged in with any datatype

        // We cannot use primitives in collections.
        // Because they are not full-fledged classes => they do not have functions like equals(), hashCode() defined
        // (Say in a Set<Integer> implementation, we need to find if they are already present, we would
        // ... want our function to work with any class. And this would make it difficult to create Collections
        // ... implementation with primitive types like int, booleean)
        // So they came up with full-fledged classes like Integer, Boolean, Character .... corresponding to all
        // ... the primitive types. These can be used in place of the primitive types in collections.
        // They have equals() and hashCode() defined on them, so implementing collection is easy.

        List<Integer> list = new ArrayList<>();

        // Code to an interface => have an interface on the left and concrete implementation on the right
        // becomes easier to switch a concrete implementation to another concrete implementation
        List<Character> list2 = new ArrayList<>();

        List<Boolean> list3 = new ArrayList<>();

        list.add(2);
        list.add(3);

        System.out.println(list);

        System.out.println(list.size());

        list.add(4);

        System.out.println(list.size());

        for (Integer i : list) {
            System.out.println("Int is " + i);
        }

        // if else if else
        if (x == 2) {
            System.out.println("Hello");
        } else if (x == 3) {
            System.out.println("sdgfis");
        } else {
            System.out.println("skudfisugdf");
        }
    }

    // multi dimensional array initialization
    int[][] magicSquare =
    {
            {16, 3, 2, 13},
            {5, 10, 11, 8},
            {9, 6, 7, 12},
            {4, 15, 14, 1}
    };

}

/*

Java 7 -> C++
Java 8 -> Functional Programming
Java 11 and Java 17 -> new features record, shortened syntaxes

LTS Versions are 8, 11 and 17. Use JDK 17 for anything new

Book
1. Problem-Solving in Java by Walter Savitch
2. Core Java, Volume I Fundamentals, 12th Edition

*/
