Elementary Programming in Java Notes

Variables and Data Representation in Java

  • Definition of Variables: In a program, variables are used to store data.

  • Declared Type Requirement: All Java variables must have a declared type.

  • Variable Type Determination: A variable's type determines two specific factors:

    • What kind of value the variable can hold.

    • How much memory to reserve for that variable.

  • Code Examples of Declarations:

    • char letter;

    • int i;

    • double area;

    • String s;

    • Object o;

Categories of Java Variables

  • Primitive Type Variables: These store single pieces of data directly.

    • Example: int i = 1; stores the value 11.

    • Example: char letter = 'A'; stores the value 'A'.

  • Object or Reference Type Variables: These store the reference (memory address) to an object that potentially contains multiple pieces of data.

    • Example: String text = "ABCDEFG";. A String is a sequence of characters; the variable text holds a reference to the location in memory where the sequence "ABCDEFG" is stored.

Java’s Primitive Types and Memory Allocation

  • Integer Types (Whole Numbers):

    • byte: 1 byte. Range: 128-128 to 127127.

    • short: 2 bytes. Range: 32,768-32,768 to 32,76732,767.

    • int: 4 bytes. Range: 2,147,483,648-2,147,483,648 to 2,147,483,6472,147,483,647. This is the default type for integer constants in a program.

    • long: 8 bytes. Range: 9,223,372,036,854,775,808-9,223,372,036,854,775,808 to 9,223,372,036,854,775,8079,223,372,036,854,775,807.

  • Real Number (Floating Point) Types:

    • float: 4 bytes.

    • double: 8 bytes. This is the default type for real constants in a program.

  • Other Primitive Types:

    • char: 2 bytes. Stores a single character using Unicode UTF-16 encoding.

    • boolean: Stores a value of true or false. It typically uses 1 bit or 1 byte.

Variable Assignment and Initialization

  • Assignment Statement: A variable receives a value via an assignment statement using the format: Variable = value_or_expression;.

  • Examples of Assignment:

    • double salary; salary = 20000.0;

    • char grade = 'A';

    • String name = "Mike";

  • Combined Declaration and Initialization: Variables can be declared and assigned a value simultaneously:

    • char yesChar = 'y';

    • String word = "Hello!";

    • double avg = 0.0, stdDev, d = 0.0; (Multiple variables of the same type can be declared in one line).

    • char initial3 = 'T';

    • boolean completed = false;

  • Mechanism of Assignment: The statement variable = expression; works by:

    1. Solving/evaluating the expression first.

    2. Assigning the resulting value to the variable.

  • Exercise Example:

    • Code: int x = 5; x = x + x + 10; System.out.print(x);

    • Logic: 5+5+10=205 + 5 + 10 = 20.

    • Output: 2020.

Rules for Variable Usage

  • Mandatory Declaration: A variable must be declared before any values are assigned to it.

    • Bad Practice Example: Attempting salary = 20000.0; before double salary; results in a Syntax Error.

  • Local Variable Initialization: A local variable (declared within a method) must be initialized with a value before it is used in an expression.

    • Bad Practice Example: double salary; double raise = salary * 0.05; results in a Syntax Error because salary has no initial value.

  • Single Declaration Rule: A variable should be declared only once within a specific block of code.

    • Bad Practice Example: Declaring double salary = 50000.0; and later double salary = 60000.0; in the same scope results in a Syntax Error.

  • Scope Restrictions: Local variables are only accessible within the block { ... } in which they are declared.

    • Bad Scope Example: If double x = 5.0; is declared inside an if block, attempting to access x outside that if block causes a Syntax Error.

Assignment Compatibility and Type Casting

  • Compatibility Rules: The variable and the assigned expression must have compatible types to avoid compiler errors.

  • Widening Conversions (Implicit): Java allows assigning a smaller type to a larger type automatically. The hierarchy is:

    • byte < short < int < long < float < double

    • Example: int x = 5; long y = x; double z = y; (All legal).

  • Narrowing Conversions (Explicit): Assigning a "big" type value to a "little" type variable or a real type to an integer type requires explicit casting.

    • Error Example: double a = 6.5; long b = a; is a Syntax Error.

  • Type Casting Syntax: (type_name)expression

    • Example: double myReal = 10.5; int goodInt = (int)myReal; (Result is 1010; note the loss of fractional data).

  • Boolean Restriction: No type casting is allowed between boolean and any other type.

Arithmetic Operators and Precedence

  • Basic Operators:

    • Addition: +

    • Subtraction: -

    • Multiplication: *

    • Division: /

    • Modulo/Remainder: % (Produces the remainder of integer division).

  • Division Specifics:

    • Integer Division: If both operands are integers, the result is the quotient (fractional part is discarded).

      • Example: 8/3=28 / 3 = 2

    • Double Division: If one or both operands are real numbers, the result is a double.

      • Example: 8.0/3.0=2.6666666666666678.0 / 3.0 = 2.666666666666667

      • Example: 8.0/3=2.6666666666666678.0 / 3 = 2.666666666666667

    • Complex Assignment Examples:

      • double average = 100/8; results in 12.012.0 (Integer division 100/8100/8 results in 1212, which is then promoted to double).

      • int fifty_percent = 50/100; results in 00.

      • double fiftyPercent = 50/100; results in 0.00.0.

      • double fiftyPercent = 50.0/100.0; results in 0.50.5.

  • Rules of Precedence (PEMDAS):

    • Multiplication and division (*, /) hold higher precedence than addition and subtraction (+, -).

    • Example: int x = 5; int y = 10; int z = 2; int num1 = x + y * z; results in 2525 (5+(10×2)5 + (10 \times 2)).

    • Best Practice Advice: Use explicit parentheses to avoid confusion regarding precedence rules.

      • Example: (3 * (4 + 5)) / 6 results in 44 (27/627 / 6 in integer division is 44).

Increment and Decrement Operators

  • Shorthand Operators:

    • ++: Increment by 11

    • --: Decrement by 11

    • +=: Increment by specified amount (e.g., z += 1 is z = z + 1)

    • -=: Decrement by specified amount

    • *=: Multiply by specified amount

    • /=: Divide by specified amount

  • Pre vs. Post Increment/Decrement:

    • Post-Increment (i++): The value is used in the expression before the increment happens.

      • Example: int i = 10; int newNum = 10 * i++; results in newNum = 100 and i = 11.

    • Pre-Increment (++i): The value is incremented before it is used in the expression.

      • Example: int i = 10; int newNum = 10 * (++i); results in newNum = 110 and i = 11.

  • Complex Evaluation Examples:

    • int i = 10; i = ++i + i++;. Step 1: ++i makes i=11i=11. Step 2: Expression uses 11+1111 + 11. Step 3: i increments to 1212 after the second usage, but the result 2222 is then assigned to i. Output: 2222.

    • int i = 10; i = i++ + i++;. Expression uses 10+1110 + 11. Output: 2121.

    • int y = 5; y -= y++ - --y;. Calculation: y = 5 - (5 - 5). Output: 55.

Numeric Literals and Precision

  • Scientific Notation: Floating-point literals can use E or e to represent an exponent.

    • Example: 1.23456e+2=123.4561.23456e+2 = 123.456

    • Example: 1.23456e2=0.01234561.23456e-2 = 0.0123456

  • IEEE 754 Standard: Double values are internally represented as 64-bit double-precision binary fractions.

  • Internal Representation Issue: Most decimal fractions cannot be represented exactly in binary. This leads to approximation errors.

    • Example: System.out.println(1 - 0.1 - 0.1 - 0.1); results in 0.70000001 rather than exactly 0.7.

Constants

  • Syntax: final datatype CONSTANTNAME = VALUE;

  • Properties:

    • Once assigned, the value of a constant cannot be changed.

    • Assignment can happen later if declared without an initial value, but only once.

  • Naming Convention: Constants are written in UPPERCASE letters. This style originates from FORTRAN developers who used uppercase to signify that an identifier was a constant.

    • Example: final double PI = 3.14159;

Character Data Type and Unicode

  • Unicode UTF-16: Java characters use 16-bit encoding.

  • Literals and Codes: Chars can be assigned via literal symbols or Unicode codes.

    • Example: char letter = 'A'; is equivalent to char letter = '\u0041';

    • Range: '\u0000' to '\uFFFF' (corresponds to 65,535+165,535 + 1 characters).

    • Greek Letters: '\u03b1', '\u03b2', '\u03b3' ($\alpha, \beta, \gamma$).

  • Arithmetic on Chars: Increment/decrement operators find the next/previous Unicode character.

    • Example: char ch = 'a'; System.out.println(++ch); displays 'b'.

  • Casting between char and Numeric Types:

    • Implicit: int i = 'a'; (Stores the numeric Unicode value of 'a', which is 9797).

    • Explicit: char c = (char)97; (Stores the character 'a').

  • Escape Sequences for Special Characters:

    • Tab: \t (Unicode '\u0009')

    • Linefeed: \n (Unicode '\u000A')

    • Backslash: \\ (Unicode '\u005C')

    • Single Quote: \' (Unicode '\u0027')

    • Double Quote: \" (Unicode '\u0022')

Java Classes and Methods

  • Class Definition: A program consists of one or more classes.

    • Syntax: public class ClassName { ... }

    • A class serves as a template or blueprint for objects.

  • The main Method: This is the program's point of entry and controls program flow.

    • Signature: public static void main(String[] args) { ... }

    • A class is executable only if it contains a main method.

  • Methods: A collection of statements performing a sequence of operations, invoked using arguments.

    • Example: System.out.println("Welcome to Java!");

Console Input and Packages

  • Reading Input: Done using the Scanner class.

    1. Create a Scanner object: Scanner input = new Scanner(System.in);

    2. Use methods like nextByte(), nextInt(), nextDouble(), nextBoolean(), or next() (for String).

  • Packages: Groups of related types used to prevent naming conflicts and control access.

    • java.util: Contains Scanner.

    • java.lang: Fundamental classes.

    • java.io: Input and output.

  • Importing Types:

    • Fully qualified name: java.util.Scanner input = ...

    • Specific import: import java.util.Scanner;

    • Wildcard import: import java.util.*;

  • Package Hierarchy Note: Packages are not actually architectural hierarchies. import java.awt.*; does not import java.awt.color.* or other sub-packages.

  • CLASSPATH Variable:

    • Windows: set CLASSPATH=C:\path\to\classes

    • Unix: %CLASSPATH=/path/to/classes; export CLASSPATH

Software Engineering and Case Study

  • The Waterfall Model:

    1. Understand and define the problem.

    2. Determine required input and output.

    3. Design an algorithm to solve the problem (Pseudocode).

    4. Implement (code) the solution.

    5. Debug and test.

    6. Maintain and update.

  • Case Study: ChangeMaker:

    • Problem: Provide the minimum number of coins for a change amount (up to 99¢).

    • Logic: Use integer division (/) for the number of coins and modulo (%) for the remainder.

    • Pseudocode Example:

      • numQuarters = originalAmount / 25

      • remainder = originalAmount % 25

      • numDimes = remainder / 10 … and so on.

    • Extended Example ($11.56):

      • Convert to integer: remainingAmount = (int)(11.56 * 100); (11561156 cents).

      • numberOfOneDollars = 1156 / 100; (1111).

      • remainingAmount = 1156 % 100; (5656).

      • numberOfQuarters = 56 / 25; (22).

      • remainingAmount = 56 % 25; (66).