JAVA, the good, the bad and the ugly


JAVA


VIEW SOURCE CODE BACK TO CATEGORIES









Java Code

JAVA


JAVA. The good the bad and the ugly. Lots of Java classes and code snippets here covering the core topics making up the Java language. As of the time writing this, JDK 10 was released. However, I'm going to begin the focus around the new features released in the 8 and 9 JDK's firstly. Oh well, lots of new things on the horizon to explore!.

If you have any questions or suggestions send me a message.

Remember, to force a browser cache refresh and reload any page press Ctrl + F5. Or hold down Shift + Reload .

Divider
1.0 Primative Types, Strings and Basic Operators

Basic primative types, Strings and basic operators and ternary operator.

    
public class Main {

    public static void main(String[] args) {

        Main m1 = new Main();

        /* ((1)) PRIMITIVE TYPES, STRINGS AND RANGES */
        m1.basicDataTypes();

        /* ((2)) BASIC OPERATORS */
        m1.operators();

        /* ((3)) RETURN METHOD AND DISPLAY PROCEDURE */
        int s1 = calculateHighScorePosition(1500);
        displayHighScorePosition("Leon", s1);

        s1 = calculateHighScorePosition(900);
        displayHighScorePosition("Mark", s1);

        s1 = calculateHighScorePosition(400);
        displayHighScorePosition("Veronica", s1);

        s1 = calculateHighScorePosition(50);
        displayHighScorePosition("John", s1);
    }

    /* ((1)) PRIMITIVE TYPES, STRINGS AND RANGES */
    private void basicDataTypes() {

        //Separate literals for improved readability
        int myVal = 123_123_123;
        System.out.println(myVal);

        /* BYTE, SHORT, INT AND LONG PRIMITIVE TYPES */

        System.out.println();
        System.out.println("WHOLE NUMBERS");
        System.out.println();

        // -128 to 127 Width of 8 (not 255 because of two's compliment)
        byte aByte = (byte) Math.pow(2, 7);
        System.out.println("-128 to 127 because of signed bit: " + aByte);

        // -32_768 to 32_767 Width of 16 (not 65,536 because of two's compliment)
        short aShort = (short) Math.pow(2, 15);
        System.out.println("-32_768 to 32_767 because of signed bit: " + aShort);

        // -2_147_483_648 to 2_147_483_647 Width of 32 (not 4,294,967,296 because of two's compliment)
        int anInt = (int) Math.pow(2, 31);
        System.out.println("-2_147_483_648 to -2_147_483_647 because of signed bit: " + anInt);

        // -9_223_372_036_854_775_808 to 9_223_372_036_854_775_807 Width of 64 (not 18,446,744,073,709,551,616 because of two's compliment)
        long aLong = (long) Math.pow(2, 63);
        System.out.println("-9_223_372_036_854_775_808 to 9_223_372_036_854_775_807 because of signed bit: " + aLong);

        //Java implicitly casts byte to an 'int' in an expression
        byte myByte = 10;
        byte castByte = (byte) (myByte / 2);
        System.out.println("Must cast to a byte as Java will implicitly cast it to an 'int' in an expression. " + castByte);

        //Java implicitly casts short to an 'int' in an expression
        short myShort = 10;
        short castShort = (short) (myShort / 2);
        System.out.println("Must cast to a short as Java will implicitly cast it to an 'int' in an expression. " + castShort);

        //'Long' literals use an 'L'
        long myLong = 120000000L + (2 * 10);
        System.out.println("Always use an 'L' for 'long' literals: " + myLong);

        /* FLOAT AND DOUBLE FLOATING POINT NUMBERS */

        System.out.println();
        System.out.println("FLOATING POINT NUMBERS");
        System.out.println();

        //Long way to initialise a float
        float longFloat = (float) 20.5;

        //Short way to initialise a float
        float shortFloat = 20.5f;
        System.out.println("LONG WAY: float longFloat = (float)20.5; " + " " + "SHORT WAY: float shortFloat = 20.5f; " + longFloat + " " + shortFloat);

        //FLOATS are 32 bits (4 bytes)
        float smallDivide = 5f / 2f;
        System.out.println("Float 5 / 2 = " + smallDivide);

        //DOUBLE is 64bits (8 bytes)
        //Use 'double' precision mostly over floats as faster on modern computers
        //Like 'int', Java takes precedence or defaults to 'doubles', so you can leave the 'd' out if you wish.
        double myDouble = 5d / 2d;
        System.out.println("Double 5 / 2 = " + myDouble);

        /* FLOAT AND DOUBLE FLOATING POINT NUMBERS */

        System.out.println();
        System.out.println("FLOATING POINT NUMBERS");
        System.out.println();

        //CHAR are 16 bits in width (2 bytes - Accepts Unicode characters - Use '\\u' ) One back-slash is escaped.
        char myChar = 'L';
        char myUniChar = '\u00A9';
        System.out.println("Single char: " + myChar + " Unicode character: " + myUniChar);

        //BOOLEAN - TRUE OR FALSE
        boolean myFlag = false;

        /* COMPLEX TYPE - STRING */

        System.out.println();
        System.out.println("STRINGS - Sequence of characters");
        System.out.println();

        String copyright = "Leon Mercanti ";
        System.out.println("This is my string: " + copyright);
        System.out.println(copyright + "\u00A9" + " 2018");
    }

    /* ((2)) BASIC OPERATORS */
    private void operators() {

        int result = 6 + 2; //addition
        System.out.println("Result is: " + result);

        result = result - 2; //subtraction
        System.out.println("Result is: " + result);

        result = result / 2; //division
        System.out.println("Result is: " + result);

        result = result * 5; //multiply
        System.out.println("Result is: " + result);

        result = result % 4; //modulo
        System.out.println("Result is: " + result);

        result++; //increment by 1
        System.out.println("Result is: " + result);

        result--; //decrement by 1
        System.out.println("Result is: " + result);

        result += 2; //add 2 to result
        System.out.println("Result is: " + result);

        result -= 2; //minus 2 from result
        System.out.println("Result is: " + result);

        result *= 2; //multiply result by 2
        System.out.println("Result is: " + result);

        result /= 2; //divide result by 2
        System.out.println("Result is: " + result);

        //BOOLEANS
        boolean isOver18 = false;
        System.out.println("Am I false? " + (isOver18 == false)); //compare false with false? True
        System.out.println("Am I not false? " + (!isOver18 == false)); //compare not false with false? False
        if (isOver18)   {
            System.out.println("I won't be printed as 'isOver18' is false");
        }

        //'AND &&' / 'OR ||' OPERATORS
        int score = -4;
        if ((score > 100) || (score < 0)) {
            System.out.println("You have entered an invalid score.");
        } else if (score >= 90 && score <= 100) {
            System.out.println("Awesome score!");
        } else if (score < 90 && score >= 80) {
            System.out.println("Pretty good score.");
        } else {
            System.out.println("Sorry your score sucks.");
        }

        //TERNARY OPERATOR
        boolean dayOrNight = false;
        String dayNight = dayOrNight ? "It is daytime" : "It is night time";
        System.out.println("Is it day or night? " +dayNight);

        boolean temp = true;
        int tooHotOrCold = temp ? 97 : 103;
        System.out.println("What is the temperature? " +tooHotOrCold);
    }

    /* ((3)) DISPLAY PROCEDURE */
    private static void displayHighScorePosition(String name, int position) {
        System.out.println("Players name: "+name+ ". At position: " +position);
    }

    /* ((3)) RETURN METHOD */
    private static int calculateHighScorePosition(int score)    {
        if (score >= 1000)   {
            return 1;
        }
        else if (score >= 500 && score < 1000)   {
            return 2;
        }
        else if (score >= 100 && score < 500)    {
            return 3;
        }
        else return 4;
    }
}
    
1.0 Output
    
123123123

WHOLE NUMBERS

-128 to 127 because of signed bit: -128
-32_768 to 32_767 because of signed bit: -32768
-2_147_483_648 to -2_147_483_647 because of signed bit: 2147483647
-9_223_372_036_854_775_808 to 9_223_372_036_854_775_807 because of signed bit: 9223372036854775807
Must cast to a byte as Java will implicitly cast it to an 'int' in an expression. 5
Must cast to a short as Java will implicitly cast it to an 'int' in an expression. 5
Always use an 'L' for 'long' literals: 120000020

FLOATING POINT NUMBERS

LONG WAY: float longFloat = (float)20.5;  SHORT WAY: float shortFloat = 20.5f; 20.5 20.5
Float 5 / 2 = 2.5
Double 5 / 2 = 2.5

FLOATING POINT NUMBERS

Single char: L Unicode character: ©

STRINGS - Sequence of characters

This is my string: Leon Mercanti 
Leon Mercanti © 2018
Result is: 8
Result is: 6
Result is: 3
Result is: 15
Result is: 3
Result is: 4
Result is: 3
Result is: 5
Result is: 3
Result is: 6
Result is: 3
Am I false? true
Am I not false? false
You have entered an invalid score.
Is it day or night? It is night time
What is the temperature? 97
Players name: Leon. At position: 1
Players name: Mark. At position: 2
Players name: Veronica. At position: 3
Players name: John. At position: 4
    
2.0 Overloading

Not to get overloading confused with overriding, overloading is reusing a method name with a unique signature.

    
public class Main {

    public static void main(String[] args) {

        Main m1 = new Main();

        //((1))SIMPLE OVERLOADING EXAMPLE 1
        int res1 = m1.doScore();
        res1 = m1.doScore("Humpty", 23);
        res1 = m1.doScore("Josh", 14, 4);

        System.out.println();

        //((2))PRACTICAL OVERLOADING EXAMPLE
        feetInchesToCentimeters(200);
    }

    // ((1))SIMPLE OVERLOADING EXAMPLE 1
    //Needs unique parameters/signatures. Different return types or voids do not effect overloading.
    private int doScore() {
        System.out.println("No parameter overload");
        return 0;
    }

    private int doScore(String s, int score) {
        System.out.println("The score for " + s + " is: " + score);
        return score;
    }

    private int doScore(String s, int score, int bonus) {
        int bonusResult = score * bonus;
        System.out.println("The score for " + s + " with the bonus is: " + bonusResult);
        return bonusResult;
    }

    //((2)) PRACTICAL OVERLOADING EXAMPLE
    //Remember try and do all your validation first. Whatever conditions are needed, validate the opposite.
    private static double feetInchesToCentimeters(double feet, double inches) {
        if ((feet < 0) || (inches < 0 || inches > 12)) {
            System.out.println("Feet input or inch input value invalid. Inches must be between 0 and 12 inclusive");
            return -1;
        }
        //Convert feet to centemeters - 12 inches in a foot, times 1 inch being 2.54cm
        double convertFeetToCent = (feet * 12) * 2.54;
        //Now add the inches onto the
        convertFeetToCent += inches * 2.54;
        System.out.println(feet + " feet and " + inches + " inches equals " + convertFeetToCent + "cm's");
        return convertFeetToCent;
    }

    private static double feetInchesToCentimeters(double inches) {
        if (inches < 0) {
            System.out.println("Invalid. Inches input less than zero");
        }
        double covertBackToFeet = (int) inches / 12;
        double getRemainderInches = (int) inches % 12;
        System.out.println(inches + " inches back to feet is equal to: " + covertBackToFeet + " feet and " + getRemainderInches + " inches.");
        return feetInchesToCentimeters(covertBackToFeet, getRemainderInches);
    }
}
    
2.0 Output
	
No parameter overload
The score for Humpty is: 23
The score for Josh with the bonus is: 56

200.0 inches back to feet is equal to: 16.0 feet and 8.0 inches.
16.0 feet and 8.0 inches equals 508.0cm's	  
	
3.0 Control Flow

Techniques for directing flow of execution and iteration. SWITCH control flow, FOR, WHILE and DO/WHILE loops.

    
	
import java.util.Scanner;

public class Main {

    //SWITCH, FOR, WHILE AND DO WHILE CONTROL FLOW AND LOOPS
    public static void main(String[] args) {

        //((1)) The SWITCH Control Flow
        Scanner s = new Scanner(System.in);
        while (true) {
            System.out.println("Choose a level between 1 and 5");
            int getInput = s.nextInt();
            if (getInput < 0 || getInput > 5) {
                System.out.println("Noo!! Pick a number between 1 and 5 only");
            } else {
                theSwitchStatement(getInput);
                break;
            }
        }
		
        System.out.println();

        //((2)) The 'FOR' Loop
        incrementInterest(12250, 5);

        //((3)) Prime
        int counter = 0;
        for (int i = 2; i < 1000; i++) {
            if (checkIfPrime(i))  {
                counter++;
                System.out.println("The number: " +i+ " is a prime number.");
            }
        }
        System.out.println("Total number of primes found was: " +counter);
    }

    //((1)) The SWITCH Control Flow
    //Good to use if your testing the SAME variable and want to test different values for that variable.
    private static void theSwitchStatement(int input) {

        //Takes a String, byte, short, char or int.
        switch (input) {
            case 1:
                System.out.println("You have chosen level 1 = Very Easy");
                break;
            case 2:
                System.out.println("You have chosen level 2 = Easy");
                break;
            case 3:
                System.out.println("You have chosen level 3 = Normal");
                break;
            case 4:
                System.out.println("You have chosen level 4 = Hard");
                break;
            case 5:
                System.out.println("You have chosen level 5 = Very Hard");
                break;
            //default: Could add a 'default' here which is executed if all 'case' fails.
            //break;
        }
    }

    //((2)) The 'FOR' Loop
    private static void incrementInterest(double investAmount, int years) {

        double result = 0.0;
        //for(initialise termination increment)
        for (double interest = 1; interest <= years; interest++) {
            result  =  (interest / 100) * investAmount;
            System.out.println("Interest rate at: " +interest+ "% with cash start at: $" +investAmount+ " = $"+ String.format("%.2f", result)+" interest");
        }
    }

    //((3)) Prime
    private static boolean checkIfPrime(int n)  {
        if (n == 1)
            return false;

        for (int i = 2; i <= Math.sqrt(n); i++) {
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }
}
    
3.0 Output
	
Choose a level between 1 and 5
4
You have chosen level 4 = Hard

Interest rate at: 1.0% with cash start at: $12250.0 = $122.50 interest
Interest rate at: 2.0% with cash start at: $12250.0 = $245.00 interest
Interest rate at: 3.0% with cash start at: $12250.0 = $367.50 interest
Interest rate at: 4.0% with cash start at: $12250.0 = $490.00 interest
Interest rate at: 5.0% with cash start at: $12250.0 = $612.50 interest

The number: 2 is a prime number.
The number: 3 is a prime number.
The number: 5 is a prime number.
The number: 7 is a prime number.
Total number of primes found was: 4  
	
4.0 Classes

Basic Introduction to Classes and Objects

    
	public class Main {

    public static void main(String[] args)  {

		//Create an object of type Car
        Car car1 = new Car("Holden", "red");

        car1.setModel("Ford");
        System.out.println(car1.printLine());

        car1.setModel("porshe");
        System.out.println(car1.printLine());

		//Create an account of type Account
        Accounts accountOne = new Accounts();
        accountOne.setAccountNumber(54353456);
        accountOne.setCustomerName("George Washington");
        accountOne.setEmail("foo@gmail.com");
        accountOne.setPhone(97251365L);
        accountOne.setBalance(500.00);

        System.out.println(accountOne.getBalance());
        accountOne.deposit(450.00);
        accountOne.withdraw(100.00);
        System.out.println(accountOne.printString());
        accountOne.withdraw(4000);

        System.out.println();

        //Constructor initialization
        Accounts accountTwo = new Accounts(2345324, 0.00, "Veronica Love", "veron@gmail.com", 0414443424);
        System.out.println(accountTwo.printString());
        accountTwo.setBalance(900);
        System.out.println(accountTwo.printString());
        accountTwo.withdraw(500);
        System.out.println(accountTwo.printString());
        accountTwo.withdraw(1000);

        //Uses the third constructor where the account number and balance have been set with defaults
        Accounts accountThree = new Accounts("Josh Higgins", "josh@gmail.com", 978623456);
        System.out.println(accountThree.printString());

        System.out.println();

        //VIP Class
        //Default constructor
        VipCustomer vipOne = new VipCustomer();
        System.out.println("Default customer: " +vipOne.getCustName()+ " Default credit limit: " +vipOne.getCreditLimit()+ " Default email: " +vipOne.getEmail());

        //Second constructor with one default field
        VipCustomer vipTwo = new VipCustomer("Rodger Ramjet", 5000.00);
        System.out.println("Customer: " +vipTwo.getCustName()+ " Credit limit: " +vipTwo.getCreditLimit()+ " Default email: " +vipTwo.getEmail());

        //Main constructor
        VipCustomer vipThree = new VipCustomer("Tintin", 1000.00, "timtam@gmail.com");
        System.out.println("Customer: " +vipThree.getCustName()+ " Credit limit: " +vipThree.getCreditLimit()+ " Email: " +vipThree.getEmail());
    }
}

class Car   {

    private String model;
    private String colour;

    Car(String model, String colour)    {
        this.model = model;
        this.colour = colour;
    }

    public void setModel(String model) {
		//Basic validation
        String s = model.toLowerCase();
        if ((s.equals("holden")) || (s.equals("porshe"))) {
            this.model = model;
        }
    }

    public String getModel() {
        return model;
    }

    public String getColour() {
        return colour;
    }

    public void setColour(String colour) {
        this.colour = colour;
    }

    public String printLine()   {
        return "This is a " +this.model+ " with the colour " + this.colour;
    }
}

class Accounts  {
    private int accountNumber;
    private double balance;
    private String customerName;
    private String email;
    private long phone;

    public Accounts(){
        //Call this constructor if an empty object is created with no arguments
        //"Calls" the other constructor
        this(000000, 0.00, "Default name", "Default email", 11111111);
        System.out.println("Default constructor");
    }

    //The main constructor.  All other constructors should reuse this one with the 'this'
    //Its good practice to have one main constructor that initialized ALL fields, then use 'this' to create your custom constructors.
    //Constructor will only ever get called once. Initialize the object when it is created. Won't need to type setters
    public Accounts(int accountNumber, double balance, String customerName, String email, long phone) {
        this.accountNumber = accountNumber;
        this.balance = balance;
        this.customerName = customerName;
        this.email = email;
        this.phone = phone;
    }

    //Another constructor which sets default account number and balance but uses the other 3 parameters
    public Accounts(String customerName, String email, long phone) {
        this(000000, 0.00, customerName, email, phone);
    }

    //GETTERS
    public int getAccountNumber()   {
        return accountNumber;
    }

    public double getBalance()  {
        if (balance < 0)   {
            System.out.println("Your balance is in the negative");
        }
        return balance;
    }

    public String getCustomerName() {
        return customerName;
    }

    public String getEmail()    {
        return email;
    }

    public long getPhone()  {
        return phone;
    }

    //SETTERS
    public void setAccountNumber(int accountNumber) {
        this.accountNumber = accountNumber;
    }

    public void setBalance(double balance)  {
        this.balance = balance;
    }

    public void setCustomerName(String name)    {
        this.customerName = name;
    }

    public void setEmail(String email)  {
        this.email = email;
    }

    public void setPhone(long phone)  {
        this.phone = phone;
    }

    public void deposit(double amount)   {
        this.balance += amount;
    }

    public void withdraw(double amount) {
        if (balance - amount < 0)   {
            System.out.println("Not enough funds. Your balance is: " +balance);
        }
        else    {
            this.balance -= amount;
            System.out.println("Withdrawal processed of amount " +amount+ " Current balance: " +balance);
        }
    }

    public String printString() {
        return "Account number: " +accountNumber+ " Balance: " + String.format("%.2f", balance)+ " Customer Name: " +customerName+ " Email: " +email+ " Phone: " +phone;
    }
}

class VipCustomer   {

    private String custName;
    private double creditLimit;
    private String email;

    //Add default fields constructor
    public VipCustomer()   {
        this("Defualt name", 0.00, "Default email");
    }

    //Third parameter is default
    public VipCustomer(String name, double creditLimit)    {
        this(name, creditLimit, "Default Email");
    }

    //Main constructor
    public VipCustomer(String custName, double creditLimit, String email) {
        this.custName = custName;
        this.creditLimit = creditLimit;
        this.email = email;
    }

    public String getCustName() {
        return custName;
    }

    public double getCreditLimit() {
        return creditLimit;
    }

    public String getEmail() {
        return email;
    }
}
    
4.0 Output
	
This is a Holden with the colour red
This is a porshe with the colour red
Default constructor
500.0
Withdrawal processed of amount 100.0 Current balance: 850.0
Account number: 54353456 Balance: 850.00 Customer Name: George Washington Email: foo@gmail.com Phone: 97251365
Not enough funds. Your balance is: 850.0

Account number: 2345324 Balance: 0.00 Customer Name: Veronica Love Email: veron@gmail.com Phone: 70403860
Account number: 2345324 Balance: 900.00 Customer Name: Veronica Love Email: veron@gmail.com Phone: 70403860
Withdrawal processed of amount 500.0 Current balance: 400.0
Account number: 2345324 Balance: 400.00 Customer Name: Veronica Love Email: veron@gmail.com Phone: 70403860
Not enough funds. Your balance is: 400.0
Account number: 0 Balance: 0.00 Customer Name: Josh Higgins Email: josh@gmail.com Phone: 978623456

Default customer: Defualt name Default credit limit: 0.0 Default email: Default email
Customer: Rodger Ramjet Credit limit: 5000.0 Default email: Default Email
Customer: Tintin Credit limit: 1000.0 Email: timtam@gmail.com
	
5.0 Inheritance

The 4 pillars in Java are encapsulation, abstraction, polymorphism and inheritance. Let's have a basic first look at inheritance.

    
import java.util.Date;

public class SimpleShape {

    private String colour;
    private boolean isFilled;
    private java.util.Date dateCreated;

    public SimpleShape() {
        this("Default Colour", false);
    }

    public SimpleShape(String colour) {
        this(colour, false);
    }

    public SimpleShape(String colour, boolean isFilled) {
        dateCreated = new java.util.Date();
        this.colour = colour;
        this.isFilled = isFilled;
    }

    //Get current colour
    public String getColour() {
        return colour;
    }

    /**
     * Set a new colour for the shape     
     * @param colour Colour
     */
    public void setColour(String colour) {
        this.colour = colour;
    }

    //Get 'true' of 'false' if shape is filled or not
    public boolean isFilled() {
        return isFilled;
    }

    /**
     * Set fill for shape     
     * @param filled true for filled false for not
     */
    public void setFilled(boolean filled) {
        isFilled = filled;
    }

    public Date getDateCreated() {
        return dateCreated;
    }

    public String toString() {
        return "The current shape colour is: " + colour + " and is set to: " + isFilled + ". The date is: " + dateCreated;
    }
}

class Square extends SimpleShape {
    private int width;
    private int height;

    public Square(int width, int height) {
        this.width = width;
        this.height = height;
    }

    public Square(String colour, int width, int height) {
        super(colour);
        this.width = width;
        this.height = height;
    }

    public Square(String colour, boolean isFilled, int width, int height) {
        super(colour, isFilled);
        this.width = width;
        this.height = height;
    }

    private String squareString() {
        return "Width of Square: " + this.width + " Height of Square: " + this.height;
    }

    //Adding functionality with squareString() while retaining the inherited toString() method
    @Override
    public String toString() {
        return super.toString() + " " + squareString();
    }
}

class Circle extends SimpleShape {
    private int radius;
    private static final double PI = Math.PI;

    public Circle(int radius) {
        this.radius = radius;
    }

    public Circle(String colour, boolean isFilled, int radius) {
        super(colour, isFilled);
        this.radius = radius;
    }

    private double doArea() {
        return (radius * radius) * PI;
    }

    public void setRadius(int r) {
        this.radius = r;
    }

    public int getRadius() {
        return radius;
    }

    @Override
    public String toString() {
        return super.toString() + " With radius: " + radius + ", Area is: " + doArea();
    }
}

class Main {

    public static void main(String[] args) {

        SimpleShape shape1 = new SimpleShape();
        System.out.println(shape1.toString());

        SimpleShape shape2 = new SimpleShape("Blue");
        System.out.println(shape2.toString());

        SimpleShape shape3 = new SimpleShape("Red", true);
        System.out.println(shape3.toString());

        Square square1 = new Square("Pink", 100, 100);
        System.out.println(square1.toString());

        Circle circle1 = new Circle("Yellow", false, 3);
        System.out.println(circle1.toString());

        circle1.setColour("White");
        circle1.setFilled(true);
        circle1.setRadius(12);
        System.out.println(circle1.toString());
    }
}
	
5.0 Output
	
The current shape colour is: Defualt Colour and is set to: false. The date is: Wed May 16 21:40:09 AEST 2018
The current shape colour is: Blue and is set to: false. The date is: Wed May 16 21:40:09 AEST 2018
The current shape colour is: Red and is set to: true. The date is: Wed May 16 21:40:09 AEST 2018
The current shape colour is: Pink and is set to: false. The date is: Wed May 16 21:40:09 AEST 2018 Width of Square: 100 Height of Square: 100
The current shape colour is: Yellow and is set to: false. The date is: Wed May 16 21:40:09 AEST 2018 With radius: 3, Area is: 28.274333882308138
The current shape colour is: White and is set to: true. The date is: Wed May 16 21:40:09 AEST 2018 With radius: 12, Area is: 452.3893421169302
	
5.1 Inheritance - Part 2

Further two examples of how inheritance works.

    
//INHERITANCE EXAMPLE ((1))
//Base/Super class
class Animals {

    private String animalName;
    private int size;
    private int weight;
    private int body;

    public Animals(String animalName, int size, int weight, int body) {
        this.animalName = animalName;
        this.size = size;
        this.weight = weight;
        this.body = body;
    }

    public String getAnimalName() {
        return animalName;
    }

    public int getSize() {
        return size;
    }

    public int getWeight() {
        return weight;
    }

    public int getBody() {
        return body;
    }

    public void move(int speed) {
        System.out.println("All animals move: I'm moving at " + speed);
    }

    public void eat() {
        System.out.println("All animals eat");
    }

    public void sleep() {
        System.out.println("All animals sleep");
    }

    public void myToString() {
        System.out.println("Animal: " + this.animalName + " size: " + this.size + " weight: " + this.weight + " body: " + this.body);
    }
}

//Class Dog Extends Animals - Inherits
class Dog extends Animals {

    private String coat;
    private int legs;
    private int tail;
    private int teeth;

    //All parameters for both the calling of Super(Animals) constructor and Dog parameters need to be listed here,
    //Unless you explicitly use a literal as parameter in 'super'. Look at the 'body' parameter for example.
    public Dog(String animalName, int size, int weight, String coat, int legs, int tail, int teeth) {
        //Calling the constructor that you are extending from
        //You need to call each field but as you can see I have removed the 'body' parameter and added it as a literal '1'
        //Basically, if your passing in a parameter literal then you can leave out the parameter altogether.
        //Now you can define your specific parameters to further define features to a 'Dog' class.
        super(animalName, size, weight, 1);
        //Now you just need to initialize the other specific parameters defined for this dog class. so add them in above (public) as you would normally.
        this.coat = coat;
        this.legs = legs;
        this.tail = tail;
        this.teeth = teeth;
    }

    //FURTHER DEFINING Animals.eat() with chewBones()
    //All dog eat but now create a more specific method that further defines how a dog eats
    //Make private to the dog class only
    //Make this private as it will cannot be overwritten
    //More specific method which will be added to the generic 'eat()' method already defined in 'Animals'
    private void chewBones() {
        //This could be implemented straight into the eat() method but creating its own private method is better
        System.out.println("private Dog chewBones() called: A dog chews bones");
    }

    //Overwrite the 'eat' method in 'Animals'.
    @Override
    public void eat() {
        //Call chewBones unique to the dog class method here
        chewBones();
        //If you want to call the super 'eat()' method too and not just the 'chewBones()' method then use 'super'
        //So 'chewBones()' will be printed FIRST followed by 'eat()' method in Animals
        super.eat();
    }

    //FURTHER DEFINING Animals.move(int) with walk() and run()
    public void walk() {
        System.out.println("Dog walk() called. ");
        move(3);
    }

    public void run() {
        System.out.println("Dog run() called. ");
        move(7);
    }

    public String getCoat() {
        return coat;
    }

    public int getLegs() {
        return legs;
    }

    public int getTail() {
        return tail;
    }

    public int getTeeth() {
        return teeth;
    }

    @Override
    public void myToString() {
        //Calls these methods of calls
        eat();
        System.out.println("Dog coat: " + this.coat + " Dog legs: " + this.legs + " Dog tail: " + this.tail + " Dog: " + this.teeth);
        //Calls base class myStoString() method
        super.myToString();
    }
}

class Fish extends Animals {
    private int eyes;
    private int gills;
    private int fins;

    public Fish(String animalName, int size, int weight, int eyes, int gills, int fins) {
        super(animalName, size, weight, 1);
        this.eyes = eyes;
        this.gills = gills;
        this.fins = fins;
    }

    private void rest() {

    }

    private void swim() {

    }

    private void moveTail() {

    }

    private void moveFins() {

    }

    private void swim(int speed) {
        moveTail();
        moveFins();
        super.move(speed);
    }

    public int getEyes() {
        return eyes;
    }

    public int getGills() {
        return gills;
    }

    public int getFins() {
        return fins;
    }
}

//INHERITANCE EXAMPLE ((2))
class Vehicle {
    private int size;
    private String colour;

    private int currentVelocity;
    private int currentDirection;

    public Vehicle(int size, String colour) {
        this.size = size;
        this.colour = colour;

        currentDirection = 0;
        currentVelocity = 0;
    }

    //Set speed and direction to a specific number
    public void move(int velocity, int direction) {
        this.currentVelocity = velocity;
        this.currentDirection = direction;
        System.out.println("Vehicle.move() Velocity: " + currentVelocity + " Direction: " + currentDirection);
    }

    //Change relative to the current direction
    public void steer(int direction) {
        this.currentDirection += direction;
        System.out.println("Vehicle.steer() Steering at: " + currentDirection + " degrees");
    }

    protected void stop() {
        this.currentVelocity = 0;
    }

    public int getSize() {
        return size;
    }

    public String getColour() {
        return colour;
    }

    public int getCurrentVelocity() {
        return currentVelocity;
    }

    public int getCurrentDirection() {
        return currentDirection;
    }

    public String printVehicle() {
        return "Vehicle  size: " + this.size + " Vehicle  colour: " + this.colour;
    }
}

class Car extends Vehicle {

    private int gears;
    private int wheels;
    private int doors;
    private boolean manualAuto;

    private int currentGear;

    public Car(int size, String colour, int gears, int wheels, int doors, boolean manualAuto) {
        super(size, colour);
        this.gears = gears;
        this.wheels = wheels;
        this.doors = doors;
        this.manualAuto = manualAuto;
        this.currentGear = 0;
    }

    public void changeVelocity(int speed, int direction) {
        //Overwriting (simply re-using) the super move(int velocity, int direction) method
        //Could be more specific here and define more if you wanted
        move(speed, direction);
        System.out.println("Car.changeVelocity() Speed: " + speed + " Direction: " + direction);
    }

    public void changeGear(int currentGear) {
        this.currentGear = currentGear;
        System.out.println("Car.changeGear(int currentGear) Gear number: " + currentGear);
    }

    private String printCar() {
        return "Car gears: " + gears + " Car wheels: " + wheels + " Car doors: " + doors + " Car manualAuto: " + manualAuto + " Car current gear: " + currentGear;
    }

    @Override
    public String printVehicle() {
        return super.printVehicle() + " " + printCar();
    }

    public int getCurrentGear() {
        return this.currentGear;
    }
}

class VWBeetle extends Car {
    private String model;
    private int monthsOfService;

    //Hard coded fixed parameters that do not need to be passed in as arguments - 'size', 'colour', 'gears', 'wheels' and 'doors'.
    public VWBeetle(String model, int monthsOfService) {
        super(2, "Yellow", 4, 4, 2, false);
        this.model = model;
        this.monthsOfService = monthsOfService;
    }

    public void accelerate(int rate) {

        int newVelocity = getCurrentVelocity() + rate;

        if (newVelocity == 0) {
            stop();
            changeGear(1);
        } else if (newVelocity > 0 && newVelocity <= 5) {
            changeGear(1);
        } else if (newVelocity > 5 && newVelocity <= 10) {
            changeGear(2);
        } else if (newVelocity > 10 && newVelocity <= 15) {
            changeGear(3);
        } else if (newVelocity > 15 && newVelocity <= 20) {
            changeGear(4);
        }

        if (newVelocity > 0) {
            changeVelocity(newVelocity, getCurrentDirection());
        }
    }

    public String getModel() {
        return model;
    }

    public int getMonthsOfService() {
        return monthsOfService;
    }

    private String printVwBeetle() {
        return " VW model: " + model + " VW service months: " + monthsOfService;
    }

    @Override
    public String printVehicle() {
        return super.printVehicle() + printVwBeetle();
    }
}

public class Main {
    public static void main(String[] args) {

        Animals animalOne = new Animals("Lion", 8, 5, 1);
        animalOne.myToString();

        System.out.println();

        Dog dogOne = new Dog("Doberman", 4, 3, "Short Haired", 4, 1, 32);
        dogOne.myToString();

        System.out.println();

        Vehicle vehicleOne = new Vehicle(5, "Purple");
        vehicleOne.move(5, 270);
        vehicleOne.steer(60);
        vehicleOne.printVehicle();

        System.out.println();

        Car carOne = new Car(4, "Blue", 6, 4, 4, false);
        System.out.println(carOne.printVehicle());
        carOne.changeVelocity(9, 180);
        System.out.println(carOne.printVehicle());

        System.out.println();

        System.out.println("START");
        VWBeetle vwOne = new VWBeetle("Golf 3.0 Turbo", 6);
        vwOne.steer(25);
        vwOne.accelerate(14);
    }
}
	
5.1 Output
	
Animal: Lion size: 8 weight: 5 body: 1

private Dog chewBones() called: A dog chews bones
All animals eat
Dog coat: Short Haired Dog legs: 4 Dog tail: 1 Dog: 32
Animal: Doberman size: 4 weight: 3 body: 1

Vehicle.move() Velocity: 5 Direction: 270
Vehicle.steer() Steering at: 330 degrees

Vehicle  size: 4 Vehicle  colour: Blue Car gears: 6 Car wheels: 4 Car doors: 4 Car manualAuto: false Car current gear: 0
Vehicle.move() Velocity: 9 Direction: 180
Car.changeVelocity() Speed: 9 Direction: 180
Vehicle  size: 4 Vehicle  colour: Blue Car gears: 6 Car wheels: 4 Car doors: 4 Car manualAuto: false Car current gear: 0

START
Vehicle.steer() Steering at: 25 degrees
Car.changeGear(int currentGear) Gear number: 3
Vehicle.move() Velocity: 14 Direction: 25
Car.changeVelocity() Speed: 14 Direction: 25
	
6.0 Composition

Use composition over inheritance whenever possible.

    
//RELATIONSHIPS
//Inheritance = Fish "IS A" Animal --> The "IS-A" relationship
//Composition = PC "HAS A" Motherboard --> The "HAS-A" relationship
//Inheritance is good but only use it if it's needed. Always use COMPOSITION over inheritance
//Use composition when you have 'smaller parts' to a bigger whole
//Use inheritance when something actually is a sub class of the super class

//PC class holds all other class contents through composition - PC "HAS-A" Motherboard, PC "HAS-A" Monitor, PC "HAS-A" ComputerCase
class PC {
    private MotherBoard motherBoard;
    private Monitor monitor;
    private ComputerCase computerCase;

    public PC(MotherBoard motherBoard, Monitor monitor, ComputerCase computerCase) {
        this.motherBoard = motherBoard;
        this.monitor = monitor;
        this.computerCase = computerCase;
    }

    public MotherBoard getMotherBoard() {
        return motherBoard;
    }

    public Monitor getMonitor() {
        return monitor;
    }

    public ComputerCase getComputerCase() {
        return computerCase;
    }
}

class MotherBoard {

    private String model;
    private String manufacturer;
    private String chipset;
    private int maxRam;
    private int socket;
    private double bios;

    public MotherBoard(String model, String manufacturer, String chipset, int maxRam, int socket, double bios) {
        this.model = model;
        this.manufacturer = manufacturer;
        this.chipset = chipset;
        this.maxRam = maxRam;
        this.socket = socket;
        this.bios = bios;
    }

    public void executeProgram(String name) {
        System.out.println("Program " + name + " is loading...");
    }

    public String getModel() {
        return model;
    }

    public String getManufacturer() {
        return manufacturer;
    }

    public String getChipset() {
        return chipset;
    }

    public int getMaxRam() {
        return maxRam;
    }

    public int getSocket() {
        return socket;
    }

    public double getBios() {
        return bios;
    }
}

class Monitor {

    private String model;
    private String manufacturer;
    private int size;

    //Composed from the Resolution class - A monitor "HAS A" resolution
    private Resolution resolution;

    public Monitor(String model, String manufacturer, int size, Resolution resolution) {
        this.model = model;
        this.manufacturer = manufacturer;
        this.size = size;
        this.resolution = resolution;
    }

    public void render(int x, int y, String colour) {
        System.out.println("Render point at X: " + x + " Render point at Y: " + y + " with colour: " + colour);
    }

    public String getModel() {
        return model;
    }

    public String getManufacturer() {
        return manufacturer;
    }

    public int getSize() {
        return size;
    }

    public Resolution getResolution() {
        return resolution;
    }
}

class ComputerCase {

    private String model;
    private String manufacturer;
    private int numFans;
    private String powerSupply;

    //Composed from the Dimensions class -  A computer case "HAS A" dimension
    private Dimensions dimensions;

    public ComputerCase(String model, String manufacturer, int numFans, String powerSupply, Dimensions dimensions) {
        this.model = model;
        this.manufacturer = manufacturer;
        this.numFans = numFans;
        this.powerSupply = powerSupply;
        this.dimensions = dimensions;
    }

    public void turnOnPower() {
        System.out.println("Power button pressed!");
    }

    public String getModel() {
        return model;
    }

    public String getManufacturer() {
        return manufacturer;
    }

    public int getNumFans() {
        return numFans;
    }

    public String getPowerSupply() {
        return powerSupply;
    }

    public Dimensions getDimensions() {
        return dimensions;
    }
}

//Composition class for the Monitor class
class Resolution {

    private double width;
    private double height;

    public Resolution(double width, double height) {
        this.width = width;
        this.height = height;
    }

    public double getWidth() {
        return width;
    }

    public double getHeight() {
        return height;
    }
}

//Composition class for the ComputerCase class
class Dimensions {

    private int width;
    private int height;

    public Dimensions(int width, int height) {
        this.width = width;
        this.height = height;
    }

    public int getWidth() {
        return width;
    }

    public int getHeight() {
        return height;
    }
}

//MAIN
public class Main {

    public static void main(String[] args) {

        //Composition standards
        //Create a Dimension object and pass it to the Case class argument of type Dimension
        //Creating the variable to be passed to the Case argument
        Dimensions d1 = new Dimensions(1200, 800);
        ComputerCase caseOne = new ComputerCase("12-JA-123213", "ASUS", 8, "Samsung", d1);

        //Create a Resolution object and pass it to the Monitor class argument of type Resolution
        //If you do not need an actual variable to be created you can simply use 'new' in the argument
        //Could write this out if the variable is needed...
        //Resolution r1 = new Resolution(1920, 1080);
        //Otherwise simply do this:                                                      Passed straight in as an argument
        Monitor monitorOne = new Monitor("B-1234-BQ10", "BENQ", 24, new Resolution(1920, 1080));

        //Create a motherboard
        MotherBoard motherBoardOne = new MotherBoard("AX-100X", "ASUS", "Intel-100X", 64, 1151, 1.15);

        //Now put it all together into a PC object using composition
        PC pcOne = new PC(motherBoardOne, monitorOne, caseOne);

        //How would you access the 'render()' method in 'Monitor' if we have an object of type 'PC'??
        //There are two ways to use composition, direct access through a calling object.
        //And secondly hiding the calling object (no getters) and calling from within the composed class itself
        //First way:
        //Where your using the 'getMonitor()' getter method defined in PC to access the 'render()' method in 'Monitor'
        //Remember PC class is composed with Monitor class etc.
        //This is how to actually use composition
        pcOne.getMonitor().render(150, 200, "Red");
        //Same thing for the 'Motherboard' object
        pcOne.getMotherBoard().executeProgram("Start Linux");
        //And the 'Case' object to turn on the power for it
        pcOne.getComputerCase().turnOnPower();

        //Second way:
        //If you don't want to have the calling program have direct access to those other objects (Motherboard, Case, Monitor)
        //like above, you can hide the implementation and do the calling inside the PC class itself. Eradicates the need to use
        //the 'getter' methods inside the PC class. Example...

        /*
         * Firstly you can remove the getters from the PC class
         * Then, create a method:
         * class PC {
         *  ComputerCase computerCase;
         *  Monitor monitor;
         *  Motherboard motherboard;
         *
         *  public void doPower()    {
         *      computerCase.turnOnPower();
         *      renderLogo();
         *  }
         *
         *  private void renderLogo()    {
         *      ...Some fancy graphics code
         *      monitor.render(150, 200, "Red");
         *  }
         * }
         * So with this way we are calling the specific methods through each composed calling class (Monitor, Motherboard, Case)
         */
    }
}
	
6.0 Output
	
Render point at X: 150 Render point at Y: 200 with colour: Red
Program Start Linux is loading...
Power button pressed!
	
7.0 Polymorphism

A powerful feature of Java when used in conjunction with inheritence is polymorphism. It allows the use of a base class along with specifically defined implementations (overwritten concrete methods) to be executed depending on the type of class being used.

    
	
class Movies {

    private String title;

    public Movies(String title) {
        this.title = title;
    }

    public String storyLine() {
        return "There is no plot for this method";
    }

    public String getTitle() {
        return this.title;
    }
}

class StarWars extends Movies {

    public StarWars() {
        super("Star Wars");
    }

    @Override
    public String storyLine() {
        return "The plot of Star Wars is a battle for galactic supremacy.";
    }
}

class BraveHeart extends Movies {

    public BraveHeart() {
        super("Brave Heart");
    }

    @Override
    public String storyLine() {
        return "The English VS the Scottish.";
    }
}

class DieHard extends Movies {

    public DieHard() {
        super("Die Hard II");
    }

    @Override
    public String storyLine() {
        return "Bruce Willis action film.";
    }
}

class Godfather extends Movies {

    public Godfather() {
        super("The Godfather - Part 1");
    }

    @Override
    public String storyLine() {
        return "Best gangster movie of all time.";
    }
}

//FIRST CONCEPT TO POLYMORPHISM
//Not an actual movie. An aspect to polymorphism is if their is no calling method inside the specific class
//the default super class method will be executed. Take NOTE of this and look at the output results.
//The super class storyLine() method is called when the outcome for the below random number generator is 5.
//Of course it will be because the storyLine() method doesn't exist in the 'NoPlotMethod' so its called from the base class instead.
class NoPlotMethod extends Movies {

    public NoPlotMethod() {
        super("No Plot constructor");
    }
    //NO storyLine() METHOD ADDED HERE
}

public class Main {

    public static void main(String[] args) {

        for (int i = 0; i < 10; i++) {
            Movies movie = getRandomMovie();
            //SECOND CONCEPT TO POLYMORPHISM
            //movie.storyLine() is the interesting method call here because it shows the basic understanding of how polymorphism works.
            //We are assigning different functionality depending on the type of object that is created.
            //Create a type of Movie and depending on the above outcome of getRandomMovie(), the corresponding movie.storyLine() will be
            //executed for that particular class. Simple example but a powerful feature of Java.
            System.out.println("Movie number: " + i + ". Movie title: " + movie.getTitle() + ". Plot is: " + movie.storyLine());
            System.out.println();
        }
    }

    private static Movies getRandomMovie() {

        //Random returns a double between 0.0 and 1.0.
        //So to get a random range between 1 and 4, multiply it by 4 and add 1.
        int random = (int) (Math.random() * 5) + 1;
        System.out.print("Random movie number between 1 and 4: " + random + " \n");

        //Return a random movie
        //Notice the getTitle() method is called from the super class constructor for a specific movie class but is
        //implemented in the concrete sub-classes.
        switch (random) {
            case 1:
                return new StarWars();
            case 2:
                return new BraveHeart();
            case 3:
                return new DieHard();
            case 4:
                return new Godfather();
            case 5:
                return new NoPlotMethod();
        }
        return null;
    }
}	
	
7.0 Output
	
Random movie number between 1 and 4: 3 
Movie number: 0. Movie title: Die Hard II. Plot is: Bruce Willis action film.

Random movie number between 1 and 4: 2 
Movie number: 1. Movie title: Brave Heart. Plot is: The English VS the Scottish.

Random movie number between 1 and 4: 1 
Movie number: 2. Movie title: Star Wars. Plot is: The plot of Star Wars is a battle for galactic supremacy.

Random movie number between 1 and 4: 3 
Movie number: 3. Movie title: Die Hard II. Plot is: Bruce Willis action film.

Random movie number between 1 and 4: 4 
Movie number: 4. Movie title: The Godfather - Part 1. Plot is: Best gangster movie of all time.

Random movie number between 1 and 4: 4 
Movie number: 5. Movie title: The Godfather - Part 1. Plot is: Best gangster movie of all time.

Random movie number between 1 and 4: 2 
Movie number: 6. Movie title: Brave Heart. Plot is: The English VS the Scottish.

Random movie number between 1 and 4: 5 
Movie number: 7. Movie title: No Plot constructor. Plot is: There is no plot for this method

Random movie number between 1 and 4: 5 
Movie number: 8. Movie title: No Plot constructor. Plot is: There is no plot for this method

Random movie number between 1 and 4: 2 
Movie number: 9. Movie title: Brave Heart. Plot is: The English VS the Scottish.
	
8.0 Java Arrays and ArrayLists

A fundamental data structure in Java is the standard array. It has a fixed size so use it when you know exatly the size of your array and when you know the array length will not change. Arrays use random access which means you can query a value without having to iterate over the array. However, if your going to be updating the array, a different data structure called an ArrayList should be used. An array list has a different set of in built methods that can be used but the mian difference is that an Array List will automatically resize itself as you add new values to it, unlike a standard array.

    
import java.util.ArrayList;
import java.util.Scanner;

public class Main {

    private static Scanner scanner = new Scanner(System.in);
    private static ProductsList productList = new ProductsList();

    public static void main(String[] args) {

        //Arrays are mutable. The original state of an array changes each time you perform an operation on it.
        int[] array = new int[5];

        //Initialize. The current state of the array
        for (int i = 0; i < array.length; i++) {
            array[i] = i * 2;
        }

        //Print out the current state of the array
        for (int i = 0; i < array.length; i++) {
            System.out.print("First operation change to the array: " + array[i] + "  ");
        }

        //Perform another basic operation on the array. Adding 2
        for (int i = 0; i < array.length; i++) {
            array[i] += 2;
        }

        System.out.println();

        //Print out the current state of the array again. Use a 'for each' loop instead for the fun of it.
        //This should demonstrate the mutable nature of Java arrays, unlike Strings which are immutable.
        for (int element : array) {
            System.out.print("Second operation change to the array: " + element + "  ");
        }

        //Sort Arrays
        int[] getInput = getIntegers(5);

        //First way to sort
        printArray(sorted(getInput));

        System.out.println();

        //Second way to sort
        printArray(sorted2(getInput));

        //From below: ARRAY LISTS (Products List basic functionality) Add, print, update, remove, exits, find
        boolean exit = false;
        int chooseProduct = 0;
        while (!exit) {
            System.out.println("\nType your choice: ");
            int choice = scanner.nextInt();
            if (choice < 0 || choice > 8) {
                System.out.println("Please choose a number between zero and 8 only. Press 'zero' for instructions.");
            }
            scanner.nextLine();

            switch (choice) {
                case 0:
                    productInstructions();
                    break;
                case 1:
                    viewItems1();
                    break;
                case 2:
                    addItems1();
                    break;
                case 3:
                    modifyList1();
                    break;
                case 4:
                    removeItem1();
                    break;
                case 5:
                    doesExist1();
                    break;
                case 6:
                    findItem1();
                    break;
                case 7:
                    processArrayList();
                    break;
                case 8:
                    exit();
                    exit = true;
                    break;
            }
        }
    }

    //Switch statement will call one of there below methods, which in turn will call the corresponding method located in the
    //ProductList class.

    //View items user input
    public static void viewItems1() {
        productList.viewItems2();
    }

    //Add user item from user input (String)
    public static void addItems1() {
        System.out.println("Please enter the product.");
        productList.addItems2(scanner.nextLine());
        System.out.println("Your item has been added.");
    }

    //User input value will be the index value of an item. Item input String will replace the item at that index
    public static void modifyList1() {
        System.out.println("Enter the product item.");
        String storeItem = scanner.nextLine();
        System.out.println("Enter the item too add.");
        String storeNewItem = scanner.nextLine();
        productList.modifyList2(storeItem, storeNewItem);
    }

    //Take user input number and use that as index to the item for removal
    public static void removeItem1() {
        System.out.println("Enter the product item to remove.");
        String getItem = scanner.nextLine();
        productList.removeItem2(getItem);
    }

    public static void doesExist1() {
        System.out.println("Enter your item to check if it exists.");
        System.out.println(productList.doesExist2(scanner.nextLine()));
    }

    public static void findItem1() {
        System.out.println("Enter the item product to find.");
        String getItem = scanner.nextLine();
        if (productList.onFile(getItem)) {
            System.out.println("Your item was found: " + getItem);
        } else {
            System.out.println("Your item was not found.");
        }
    }

    //Copy/save current product list to new ArrayList. Much easier/faster than having to use iteration.
    public static void processArrayList() {
        //First way
        ArrayList newArrayList = new ArrayList<>();
        newArrayList.addAll(productList.getList());

        //Second way if you want to copy/save a new array list when you declare and initialize
        //simply uses the 'getter' for the array list in the concrete implementation class (ProductList)
        ArrayList newArrayList2 = new ArrayList<>(productList.getList());

        //If you want to convert your array list to an ordinary array
        String[] normalArray = new String[productList.getList().size()]; //Just gets the length
        normalArray = productList.getList().toArray(normalArray); //Does the actual conversion
    }

    public static void exit() {
        System.out.println("Exiting...");
    }

    //Instructions for the product list to be called when zero is pressed
    public static void productInstructions() {
        System.out.println("\nPress: ");
        System.out.println("\tPress: 0 - View Instructions");
        System.out.println("\tPress: 1 - View The Products In The List");
        System.out.println("\tPress: 2 - Add An Item To The List");
        System.out.println("\tPress: 3 - Update A Product To The List (modify)");
        System.out.println("\tPress: 4 - Remove An Item From The List");
        System.out.println("\tPress: 5 - Does A Specific Item Exist In The List");
        System.out.println("\tPress: 6 - Find An Item In The List");
        System.out.println("\tPress: 7 - Find An Item In The List");
        System.out.println("\tPress: 8 - Exit");
    }


    //BREAK COMPLEX PROGRAMS DOWN INTO SMALLER COMPONENTS
    //Take input from a user and store the values in an array. Sort the values and return a new array. Print the values.
    //(1)Get user input from keyboard and store inside array
    public static int[] getIntegers(int n) {
        int[] storeNums = new int[n];
        System.out.println("Enter " + n + " numbers to sort\r");
        for (int i = 0; i < storeNums.length; i++) {
            storeNums[i] = scanner.nextInt();
        }
        return storeNums;
    }

    //(2)Then pass the returned array from above into the parameter.
    //Sorts the array list in descending order
    public static int[] sorted(int[] a) {
        int[] sortedArray = new int[a.length];
        int temp = 0;
        for (int i = 0; i < a.length - 1; i++) {
            for (int j = 0; j < a.length - 1; j++) {
                if (a[j] < a[j + 1]) {
                    temp = a[j];
                    a[j] = a[j + 1];
                    a[j + 1] = temp;
                    sortedArray = a;
                }
            }
        }
        return sortedArray;
    }

    //(3)Print the final values from the new array
    public static void printArray(int[] a) {
        for (int i = 0; i < a.length; i++) {
            System.out.print(a[i] + ", ");
        }
    }

    //(2.b)Another way to implement the above 'sorted' method
    //Sort the array list in descending order
    public static int[] sorted2(int[] a) {
        int[] sortedArray2 = new int[a.length];
        for (int i = 0; i < a.length; i++) {
            sortedArray2[i] = a[i];
        }
        boolean flag = true;
        while (flag) {
            flag = false;
            int temp = 0;
            for (int i = 0; i < sortedArray2.length - 1; i++) {
                if (sortedArray2[i] < sortedArray2[i + 1]) {
                    temp = sortedArray2[i];
                    sortedArray2[i] = sortedArray2[i + 1];
                    sortedArray2[i + 1] = temp;
                    flag = true;
                }
            }
        }
        return sortedArray2;
    }
}

//ARRAY LISTS (Products List basic functionality) Add, print, update, remove, exits, find
class ProductsList {

    //List collection is an interface (polymorphism). Array list class implements from List.
    //Just create a type ArrayList for now. We store it in this class and have access to it through the instantiation of this class
    //when we create the object in the Main.
    private static ArrayList list = new ArrayList<>();

    public ArrayList getList() {
        return list;
    }

    //Print the items in the list
    public void viewItems2() {
        System.out.println("There are " + list.size() + " items in your list.");
        for (int i = 0; i < list.size(); i++) {
            System.out.println("Item " + (i + 1) + ": " + list.get(i));
        }
    }

    //Add an item to the list
    public void addItems2(String item) {
        list.add(item);
    }

    //Overloaded
    //Type in the item you want to replace, and then type in the item you want to replace it with
    public void modifyList2(String oldItem, String newItem) {
        int pos = findItem2(oldItem);
        if (pos >= 0) {
            modifyList2(pos, newItem);
        }
    }

    //Overloaded
    //Position of item (index) - Starting from 1 not zero. Item will replace the current item at index value.
    private void modifyList2(int position, String item) {
        //position is the index value
        list.set(position, item);
        System.out.println("Item from position " + (position + 1) + " has been modified with " + "'" + item + "'");

    }

    //Overloaded
    public void removeItem2(String s) {
        int pos = findItem2(s);
        if (pos >= 0) {
            removeItem2(pos);
        }
    }

    //Overloaded
    //Remove an item from the product list
    private void removeItem2(int position) {
        list.remove(position);
        System.out.println("Your item at position: " + (position + 1) + " has been removed.");
    }

    //Check to see if an item exists or not.
    //Use the optimized 'contains' built in function instead of manually iterating and searching.
    //Search for the actual value, not the index, so parameter is of type String. Only tells you if the item exists.
    public String doesExist2(String item) {
        boolean findItem = list.contains(item);
        return findItem ? "Item " + item + " found. " : " Item not found.";
    }

    //Check to see if an item exists AND return the index.
    private int findItem2(String item) {
        return list.indexOf(item);
    }

    public boolean onFile(String s) {
        int isExists = findItem2(s);
        if (isExists > 0) {
            return true;
        }
        return false;
    }
}

	
8.0 Output
	
First operation change to the array: 0  First operation change to the array: 2  
First operation change to the array: 4  First operation change to the array: 6  
First operation change to the array: 8  
Second operation change to the array: 2  Second operation change to the array: 4  
Second operation change to the array: 6  Second operation change to the array: 8  
Second operation change to the array: 10  Enter 5 numbers to sort
34
56
89
23
766
766, 89, 56, 34, 23, 
766, 89, 56, 34, 23, 
Type your choice: 
0

Press: 
	Press: 0 - View Instructions
	Press: 1 - View The Products In The List
	Press: 2 - Add An Item To The List
	Press: 3 - Update A Product To The List (modify)
	Press: 4 - Remove An Item From The List
	Press: 5 - Does A Specific Item Exist In The List
	Press: 6 - Find An Item In The List
	Press: 7 - Process Array Lists (not an option - for learning purposes
	Press: 8 - Exit

Type your choice: 
1
There are 0 items in your list.

Type your choice: 
2
Please enter the product.
shoes
Your item has been added.

Type your choice: 
2
Please enter the product.
bag
Your item has been added.

Type your choice: 
2
Please enter the product.
cheese
Your item has been added.

Type your choice: 
2
Please enter the product.
chair
Your item has been added.

Type your choice: 
2
Please enter the product.
mouse
Your item has been added.

Type your choice: 
1
There are 5 items in your list.
Item 1: shoes
Item 2: bag
Item 3: cheese
Item 4: chair
Item 5: mouse

Type your choice: 
3
Enter the product item.
chair
Enter the item too add.
sofa
Item from position 4 has been modified with 'sofa'

Type your choice: 
1
There are 5 items in your list.
Item 1: shoes
Item 2: bag
Item 3: cheese
Item 4: sofa
Item 5: mouse

Type your choice: 
4
Enter the product item to remove.
bag
Your item at position: 2 has been removed.

Type your choice: 
1
There are 4 items in your list.
Item 1: shoes
Item 2: cheese
Item 3: sofa
Item 4: mouse

Type your choice: 
5
Enter your item to check if it exists.
chair
 Item not found.

Type your choice: 
5
Enter your item to check if it exists.
cheese
Item cheese found. 

Type your choice: 
8
Exiting...

	
9.0 ArrayLists and Autoboxing and Unboxing

Below is a similar implemenation as above but a little mopre advanced using complex data types. Consists of a Main, MobilePhone and Contacts classes. Notice the passing of 'Contacts' complex type as parameters. Also included in Main are a couple of independent examples of autoboxing and unboxing wrapper types and primative values.

    
/*
This program uses an ArrayList that performs mobile phone .
The MobilePhone class managers the operations while the Contacts class manages the individual contacts
The input is implemented in the main class, hiding the ArrayList implementation.
 */
import java.util.ArrayList;
import java.util.Scanner;

public class Main {

    private static Scanner scanner = new Scanner(System.in);
    private static MobilePhone mobilePhone = new MobilePhone("0414344452");

    public static void main(String[] args) {

        boolean quit = false;
        startPhone();
        printActions();
        while (!quit) {
            System.out.println("\nPress 6 to show available actions");
            int scan = scanner.nextInt();

            switch (scan) {
                case 0:
                    System.out.println("\nShutting down...");
                    quit = true;
                    break;
                case 1:
                    printContacts();
                    break;
                case 2:
                    addContact();
                    break;
                case 3:
                    updateContact();
                    break;
                case 4:
                    removeContact();
                    break;
                case 5:
                    querycontact();
                    break;
                case 6:
                    printActions();
                    break;
            }
        }
    }

    private static void startPhone() {
        System.out.println("Starting phone...");
    }

    private static void printContacts() {
        mobilePhone.printContacts();
    }

    private static void addContact() {
        System.out.println("Enter new name: ");
        String name = scanner.nextLine();

        System.out.println("Enter new phone number: ");
        String number = scanner.nextLine();
        Contacts contact = Contacts.createContact(name, number);
        if (mobilePhone.addNewContact(contact)) {
            System.out.println("New contact added. Name: " + name + ". Phone: " + number);
        } else {
            System.out.println("Cannot add " + name + ". Already on file.");
        }
    }

    private static void updateContact() {
        System.out.println("Enter existing contact.");
        String name = scanner.nextLine();
        Contacts existingContact = mobilePhone.queryContact(name);
        if (existingContact == null) {
            System.out.println("Contact not found.");
            return;
        }
        System.out.println("Enter new contact name: ");
        String newName = scanner.nextLine();
        System.out.println("Enter new phone number: ");
        String newNumber = scanner.nextLine();
        Contacts newContact = Contacts.createContact(newName, newNumber);
        if (mobilePhone.updateContact(existingContact, newContact)) {
            System.out.println("Contact update successful.");
        } else {
            System.out.println("Error updating record.");
        }
    }

    private static void removeContact() {
        System.out.println("Enter existing contact.");
        String name = scanner.nextLine();
        Contacts existingContact = mobilePhone.queryContact(name);
        if (existingContact == null) {
            System.out.println("Contact not found.");
            return;
        }
        if (mobilePhone.remove(existingContact)) {
            System.out.println("Successfully removed.");
        } else {
            System.out.println("No record to remove.");
        }
    }

    private static void querycontact() {
        System.out.println("Enter existing contact.");
        String name = scanner.nextLine();
        Contacts existingContact = mobilePhone.queryContact(name);
        if (existingContact == null) {
            System.out.println("Contact not found.");
            return;
        }
        System.out.println("Name: " + existingContact.getContactName() + " phone number: " + existingContact.getNumber());
    }

    private static void printActions() {
        System.out.println("\nAvailable actions:\nPress");
        System.out.println(
                "0 - Shutdown\n" +
                        "1 - Print Contacts\n" +
                        "2 - Add new contact\n" +
                        "3 - Update existing contact\n" +
                        "4 - Remove Contact\n" +
                        "5 - Query if a contact exists\n" +
                        "6 - Print a list of available actions.");
        System.out.println("Choose your action: ");
    }

    //NOT PART OF THE MOBILE PHONE IMPLEMENTATION - Auto boxing/unboxing example
    private static void AutoBoxExample() {
        ArrayList intArray = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            //Autoboxing: Taking a primitive and converting to Integer (wrapper)
            intArray.add(Integer.valueOf(i));
        }

        //Unboxing: Taking the Integer wrapper values and converting them back into primitive ints.
        for (int i = 0; i < intArray.size(); i++) {
            System.out.println(i + " ---> " + intArray.get(i).intValue());
        }
    }

    //Take note the above is the long way and is not necessary. Java will do the conversion automatically at compile time.
    //So this will work too.
    Integer myInteger = 321; //Integer.valueOf(321) As you can see there is no error. You don't have to use the 'new' keyword.
    int myint = myInteger; //myInteger.intValue(); Unboxing works too. No need to use the method intValue().
}

class MobilePhone {

    private String myNumber;
    private ArrayList contactList;

    public MobilePhone(String myNumber) {
        this.myNumber = myNumber;
        this.contactList = new ArrayList();
    }

    public void printContacts() {
        for (int i = 0; i < this.contactList.size(); i++) {
            System.out.println(i + 1 + ": " + contactList.get(i).getContactName() + ": " + contactList.get(i).getNumber());
        }
    }

    public boolean addNewContact(Contacts contact) {
        if (findContact(contact.getContactName()) >= 0) {
            System.out.println("Contact already exists");
            return false;
        }
        contactList.add(contact);
        return true;
    }

    private int findContact(Contacts contact) {
        return this.contactList.indexOf(contact);
    }

    private int findContact(String name) {
        for (int i = 0; i < contactList.size(); i++) {
            Contacts contact = contactList.get(i);
            if (contact.getContactName().equals(name)) {
                return i;
            }
        }
        return -1;
    }

    //Helper method for the above 'findContact' method. We don't want to expose these private methods, publicly.
    //Essentially calls the above find method but returns a String instead of an int.
    public String queryContact(Contacts contact) {
        if (findContact(contact) >= 0) {
            return contact.getContactName();
        }
        return null;
    }

    public Contacts queryContact(String name) {
        int position = findContact(name);
        if (position >= 0) {
            return this.contactList.get(position);
        }
        return null;
    }

    public boolean updateContact(Contacts oldContact, Contacts newContact) {

        int getIndex = findContact(oldContact);
        if (getIndex < 0) {
            System.out.println(oldContact.getContactName() + " not found. No update possible.");
            return false;
        }
        this.contactList.set(getIndex, newContact);
        System.out.println(oldContact.getContactName() + " replaced with " + newContact.getContactName());
        return true;
    }

    public boolean remove(Contacts contact) {
        int getPosition = findContact(contact);
        if (getPosition < 0) {
            System.out.println(contact.getContactName() + " was not found.");
            return false;
        }
        this.contactList.remove(contact);
        System.out.println(contact.getContactName() + " was deleted.");
        return true;
    }
}

class Contacts {

    private String contactName;
    private String number;

    public Contacts(String contactName, String number) {
        this.contactName = contactName;
        this.number = number;
    }

    public String getContactName() {
        return contactName;
    }

    public String getNumber() {
        return number;
    }

    public static Contacts createContact(String name, String number) {
        return new Contacts(name, number);
    }
}
	
9.0 Output
	
	No output for the above examples. Run the code and try for yuorself.
	
Up Arrow