0% found this document useful (0 votes)
12 views33 pages

OOP_REV

This document provides an introduction to Object-Oriented Programming (OOP) and Java, outlining key concepts such as abstraction, encapsulation, inheritance, and polymorphism. It covers the basic structure of a Java program, installation requirements, data types, expressions, and input/output operations. Additionally, it discusses Java's history, editions, and the differences between Java's execution model and traditional compilers.

Uploaded by

harlynmaebatalan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views33 pages

OOP_REV

This document provides an introduction to Object-Oriented Programming (OOP) and Java, outlining key concepts such as abstraction, encapsulation, inheritance, and polymorphism. It covers the basic structure of a Java program, installation requirements, data types, expressions, and input/output operations. Additionally, it discusses Java's history, editions, and the differences between Java's execution model and traditional compilers.

Uploaded by

harlynmaebatalan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

Week 01 - Lesson: Introduction to Object-Oriented Programming and Java

Learning Objectives
By the end of this lesson, you will be able to:
• Define Object-Oriented Programming (OOP) and understand its core concepts.
• Compare and contrast procedural programming and OOP.
• Explain the benefits of using abstract data types (ADTs).
• Understand the basic structure of a Java program.
• Identify the installation requirements for Java.
• Define and use literals, identifiers, primitive data types, and variables in Java.
• Write and evaluate expressions in Java, including understanding operator precedence.
• Explain reference types and type casting in Java.
• Utilize input and output (I/O) statements in Java (using methods such as print, println, printf
and Scanner methods).
• Utilize the Java Math API library for common mathematical functions.
• Comment code effectively for readability and maintenance.

Key Terms
• Object-Oriented Programming (OOP): A programming paradigm that organizes software design
around objects—entities that encapsulate data and behavior.
• Procedural Programming: A programming paradigm where code is organized into procedures or
functions that operate on data, with a focus on sequential execution.
• Abstract Data Types (ADTs): Data types defined by the operations that can be performed on them,
without specifying how these operations are implemented.
• Class: A blueprint or template that defines the structure (attributes) and behavior (methods) of
objects.
• Object: An instance of a class that holds state (data) and can perform actions (methods).
• Encapsulation: The practice of bundling data and methods that operate on that data within a class,
restricting direct access from outside.
• Inheritance: A mechanism by which one class (child) derives attributes and methods from another
class (parent), promoting code reuse.
• Polymorphism: The ability of different objects to respond uniquely to the same method call,
typically achieved via method overriding.
• Abstraction: The process of hiding complex implementation details and exposing only the essential
features of an object.
• Java Virtual Machine (JVM): The runtime environment that executes Java bytecode, allowing Java
programs to run on any platform.
• Literals: Fixed values explicitly written in the code (e.g., numbers, characters, strings).
• Identifiers: Names given to program elements such as variables, methods, and classes.
• Primitive Data Types: Basic data types provided by Java (e.g., int, boolean, char, double) that store
simple values.
• Variables: Named storage locations in memory that hold data which may change during program
execution.
• Operators: Symbols that perform operations on one or more operands (e.g., arithmetic, relational,
logical operators).
• Reference Types: Data types that refer to objects (such as instances of classes or arrays) rather
than containing their own values.
• Type Casting: Converting a value from one data type to another, either implicitly or explicitly.
• Input/Output Statements: Constructs that allow programs to receive input (e.g., via the Scanner
class) and produce output (e.g., via System.out methods).
• Java Math API Library: A collection of methods in Java’s Math class for performing mathematical
operations such as square roots, powers, and random number generation.
• Comments: Non-executable annotations in code used to explain and document the logic for
human readers.
• Java History: The timeline of Java’s development, starting with its creation in 1995 by Sun
Microsystems.
• Java Editions: Variants of Java such as Java SE (Standard Edition), Java EE (Enterprise Edition), and
Java ME (Micro Edition) tailored for different types of applications.
1. Introduction to Object-Oriented Programming (OOP)
1.1 Procedural vs. Object-Oriented Programming

• Procedural Programming: Organizes code into procedures or functions that manipulate data; data
and functions are kept separate. For example, languages like C and Pascal follow this approach.
• Object-Oriented Programming (OOP): Organizes code around objects that encapsulate both data
(attributes) and behaviors (methods). This design reflects real-world entities and is central to
languages such as Java and C++.

Feature Procedural Programming Object-Oriented Programming


Organization Functions and procedures Objects and classes
Data Handling Data is separate from functions Data is bundled with methods
Reusability Limited by function scope Inheritance and polymorphism enhance reusability
Examples C, Pascal Java, C++

1.2 Abstract Data Types (ADTs)


• Definition: An ADT specifies what operations can be performed (its behavior) rather than how they
are implemented.
• Example: A Stack ADT might define operations like push(), pop(), and peek(), without specifying the
internal storage (array, linked list, etc.).

1.3 Core OOP Concepts


• Abstraction: Hiding complex implementation details while exposing only the necessary features.
• Encapsulation: Combining data and the methods that operate on that data into a single unit (a
class).
• Inheritance: A mechanism that allows one class (child) to inherit fields and methods from another
(parent), enabling code reuse.
• Polymorphism: The ability to treat objects of different classes through the same interface, often
using method overriding.

2. Introduction to Java Programming


2.1 Basic Anatomy of a Java Program
A Java program typically contains:
• Class Declaration: Defines the blueprint for objects (data and methods).
• Main Method: The entry point of the program, declared as:

Sample Java Code


public static void main(String[] args) {
// Code to run
}

Sample Java Code


public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}

2.2 Installation Requirements for Java


To develop and run Java programs, you need:
• Java Development Kit (JDK): Contains the compiler, tools, and the Java Runtime Environment
(JRE).
• Java Virtual Machine (JVM): Runs the compiled Java bytecode.
• Integrated Development Environment (IDE) (Optional): Tools like Eclipse, IntelliJ IDEA, or
NetBeans can simplify coding and debugging.

2.3 Literals, Identifiers, Primitive Data Types, and Variables


• Literals: Fixed values that appear directly in code (e.g., 10, 3.14, 'A').
• Identifiers: Names used for classes, methods, and variables.
• Primitive Data Types: Basic types such as int, double, char, and boolean.
• Variables: Memory locations to store data that may change during execution.
Sample Java Code
int age = 25;
double price = 99.99;
char grade = 'A';
boolean isPassed = true;

2.4 Expressions, Operators, and Precedence


• Expressions: Combinations of literals, variables, and operators that yield a value.
• Operators: Include arithmetic (+, -, *, /), relational (==, <, >), and logical (&&, ||, !).
• Operator Precedence: Rules that determine the order in which operations are evaluated (e.g.,
multiplication before addition).

Sample Java Code


int result = 10 + 5 * 2; // result is 20, not 30

2.5 Reference Types and Type Casting


• Reference Types: Variables that refer to objects (e.g., instances of String, Scanner). They store
memory addresses.
• Type Casting: Converting a variable from one type to another. Casting can be implicit or explicit.

Sample Java Code


double num = 10.5;
int castedNum = (int) num; // Explicitly casting double to int

3. I/O Statements in Java


3.1 Output Methods
Java provides three primary methods for output:
• System.out.print(): Prints text without a newline.
Sample Java Code
System.out.print("Hello ");
System.out.print("World!");
// Output: Hello World!

• System.out.println(): Prints text and moves to a new line.


Sample Java Code
System.out.println("Hello");
System.out.println("World!");
// Output:
// Hello
// World!

• System.out.printf(): Provides formatted output using format specifiers.


Sample Java Code
int age = 25;
double pi = 3.14159;
String name = "Alice";
System.out.printf("My name is %s, I am %d years old, and Pi is %.2f.%n", name, age, pi);
// Output: My name is Alice, I am 25 years old, and Pi is 3.14.

3.2 Input Methods


The Scanner class (from java.util) is used to read input from the console.
Usage:
Sample Java Code
Import the Scanner class:
import java.util.Scanner;
Create a Scanner object:
Scanner scanner = new Scanner(System.in);
Methods for Various Data Types:
Method Data Type Example Usage
nextByte() byte byte b = scanner.nextByte();
nextShort() short short s = scanner.nextShort();
nextInt() int int num = scanner.nextInt();
nextLong() long long l = scanner.nextLong();
nextFloat() float float f = scanner.nextFloat();
nextDouble() double double d = scanner.nextDouble();
next() single word (String) String word = scanner.next();
nextLine() full line (String) String line = scanner.nextLine();

Example (Reading a Full Line):


import java.util.Scanner;
public class NextLineExample {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter a sentence: ");
String sentence = scanner.nextLine();
System.out.println("You entered: " + sentence);
}
}
Note: If nextLine() follows nextInt() or nextDouble(), use an extra scanner.nextLine() to consume the newline
character.

4. Java Math API Library


The Java Math API offers many methods for common mathematical functions. Some frequently used
methods include:
• Math.sqrt(x): Returns the square root of x.
• Math.pow(x, y): Returns x raised to the power y.
• Math.random(): Returns a random double between 0.0 (inclusive) and 1.0 (exclusive).

Example:
public class MathExample {
public static void main(String[] args) {
double squareRoot = Math.sqrt(16); // 4.0
double power = Math.pow(2, 3); // 8.0
double randomValue = Math.random(); // Random value between 0.0 and 1.0

System.out.printf("Square root: %.2f%nPower: %.2f%nRandom: %.4f%n",


squareRoot, power, randomValue);
}
}

5. Comments in Java
Comments help make code easier to understand. Java supports:
• Single-line comments: Begin with //.
• Multi-line comments: Enclosed between /* and */.

Example:
public class CommentsExample {
public static void main(String[] args) {
// This is a single-line comment

/* This is a multi-line comment.


It spans several lines.
*/
System.out.println("Comments improve code readability.");
}
}
6. History of Java and Essential Terminologies

6.1 History of Java

• Java was developed by a team led by James Gosling at Sun Microsystems. Originally called Oak,
Java was designed in 1991 for use in embedded chips in consumer electronic appliances.
• Java was introduced in 1995 by Sun Microsystems as a platform-independent language.
• Its design was influenced by the need for a language that could be used on a variety of devices—
from embedded systems to large-scale enterprise applications.
• Over time, Java has evolved through multiple editions, each adding new features while maintaining
backward compatibility.
• Sun Microsystems was purchased by Oracle in 2010.

6.2 Java Editions

• Java SE (Standard Edition): The core Java platform for developing and running desktop applications
and simple server-side applications.

• Java EE (Enterprise Edition): Built on Java SE, this edition includes additional libraries and tools for
developing large-scale, multi-tiered, and web-based enterprise applications.

• Java ME (Micro Edition): A subset of Java designed for mobile and embedded devices.

6.3 Essential Java Terminologies

• JVM (Java Virtual Machine): The runtime engine that executes Java bytecode and provides platform
independence.

• JDK (Java Development Kit): A toolkit that includes the JRE, compilers, and tools needed to
develop Java applications.

• JRE (Java Runtime Environment): Provides the libraries and JVM necessary to run Java programs.

• Bytecode: The intermediate representation of Java code that is executed by the JVM.

Conclusion
In this lesson, we laid a comprehensive foundation in Java programming and object-oriented principles.
We explored:

• OOP Fundamentals: The differences between procedural and object-oriented programming, the
benefits of ADTs, and core OOP concepts such as abstraction, encapsulation, inheritance, and
polymorphism.

• Java Basics: The structure of a Java program, installation requirements (JDK, JVM, IDE), and
essential language elements like literals, identifiers, primitive data types, variables, expressions,
and operators.

• I/O Operations & Math API: How to perform input and output using Scanner and System.out
methods, and how to use Java’s Math API for common mathematical functions.

• Java History and Editions: An overview of Java’s history, its evolution since 1995, and the key
editions (Java SE, Java EE, Java ME) along with essential terminology like JVM, JDK, and JRE.

This comprehensive introduction prepares you for advanced topics in Java programming while grounding
you in the core concepts and historical context that have shaped the language. As you continue your
journey, practice these concepts through hands-on projects and further study to build robust,
maintainable applications.
Java Interpreter vs. Other Compilers

Overview:
Java uses a unique execution model compared to traditionally compiled languages like C or C++. In Java,
source code is first compiled into an intermediate form called bytecode by the Java compiler (javac). This
bytecode is then executed by the Java Virtual Machine (JVM), which functions as an interpreter and, in
many modern implementations, a Just-In-Time (JIT) compiler.

Key Differences:

• Compilation Process:
o Java:
▪ Step 1: Source code (.java) is compiled into platform-independent bytecode (.class
files).
▪ Step 2: The JVM interprets (or JIT-compiles) this bytecode at runtime, allowing Java
applications to run on any platform that has a compatible JVM.
o Other Compilers (e.g., C/C++):
▪ Source code is directly compiled into native machine code specific to a target
operating system and hardware, resulting in an executable file that runs directly on
that system.

• Platform Independence:
o Java:
▪ Bytecode is platform-independent, meaning the same compiled code can run on
different systems without modification.
o Other Compilers:
▪ Native machine code is platform-specific and requires recompilation for different
environments.

• Runtime Performance:
o Java:
▪ The JVM’s interpreter can introduce overhead, but modern JVMs use JIT compilation
to optimize performance by compiling frequently executed code paths into native
code at runtime.
o Other Compilers:
▪ Compiled directly to native code, which often results in faster startup and execution
times since there is no additional interpretation layer.

• Error Handling and Security:


o Java:
▪ The JVM provides robust error handling and security features (such as runtime checks
and sandboxing) that help prevent common programming errors.
o Other Compilers:
▪ Rely more heavily on the developer and operating system for error handling and
security, which can sometimes lead to vulnerabilities if not managed properly.

Conclusion:
Java’s two-step compilation and execution process provides platform independence and added security,
while modern optimizations like JIT compilation help improve performance. In contrast, traditional
compilers generate native code directly, often yielding faster execution in certain scenarios but lacking the
cross-platform flexibility of Java.
Week 02-03 - Lesson: Selection and Looping Statements in Java
Learning Objectives
By the end of this lesson, you should be able to:
• Discuss the usage of boolean variables, literals, and expressions in Java.
• Identify and use relational (==, !=, >, <, >=, <=) and logical operators (&&, ||, !, ^).
• Implement selection control using various if statements:
o One-way if statement
o Two-way if–else statement
o Nested if statements
o Multi-way if–else chains
• Utilize switch statements for multi-conditional selection.
• Implement loops using:
o The while loop
o The do-while loop
o The for loop
• Employ nested loops for complex iterative tasks.
• Use break and continue statements effectively to control loop execution.

Key Terms
• Boolean literals: The values true and false.
• Boolean expressions: Expressions that evaluate to a boolean value.
• Boolean variables: Variables that store boolean values.
• Relational operators: Operators used to compare values (e.g., ==, !=, >, <, >=, <=).
• Logical operators: Operators used to combine boolean expressions (e.g., &&, ||, !, ^).
• if statement: A selection control statement that executes code if a condition is true.
• if–else statement: Executes one block of code if a condition is true and another block if it is false.
• Nested if statement: An if statement placed within another if statement.
• Multi-way if–else statement: A chain of if–else statements to test multiple conditions.
• switch statement: A multi-branch selection statement that selects execution paths based on a
variable’s value.
• while loop: Repeats a block of code as long as a condition is true (pre-test loop).
• do–while loop: Executes a block of code at least once and then repeats it while a condition is true
(post-test loop).
• for loop: A control structure that provides initialization, condition checking, and update in one line.
• Nested loop: A loop placed inside the body of another loop.
• break statement: Exits the closest loop or switch block immediately.
• continue statement: Skips the remaining part of the current loop iteration and proceeds with the
next iteration.

1. Selection Statements
Selection statements allow your program to choose different execution paths based on conditions.
1.1 Boolean Literals, Expressions, and Variables
• Boolean literals: true and false are used directly.
• Boolean expressions: Formed using relational and logical operators; they evaluate to true or false.

Example:
boolean isJavaFun = true; // boolean variable
int a = 5, b = 10;
boolean comparison = (a < b); // evaluates to true

1.2 Relational and Logical Operators


• Relational operators: Compare values (e.g., a < b, a == b).
• Logical operators: Combine boolean expressions (e.g., (a < b) && (b != 0)).

Example:
if ((a < b) && (b != 0)) {
System.out.println("a is less than b and b is not zero.");
}
1.3 One-Way if Statement
Executes a block of code only if the condition is true.
Syntax:
if (condition) {
// Code to execute if condition is true
}

Example:
if (a < b) {
System.out.println("a is less than b.");
}

1.4 Two-Way if–Else Statement


Executes one block if the condition is true and another if it is false.
Syntax:
if (condition) {
// Code if true
} else {
// Code if false
}

Example:
if (a < b) {
System.out.println("a is less than b.");
} else {
System.out.println("a is not less than b.");
}

1.5 Nested if and Multi-Way if–Else Statements


• Nested if statements: One if statement inside another.
• Multi-way if–else chain: Tests several conditions sequentially.

Example (Nested if):


if (a < b) {
if (a < 0) {
System.out.println("a is less than b and negative.");
} else {
System.out.println("a is less than b and non-negative.");
}
}

Example (Multi-way if–else):


if (a < b) {
System.out.println("a is less than b.");
} else if (a == b) {
System.out.println("a is equal to b.");
} else {
System.out.println("a is greater than b.");
}
1.6 Switch Statements
A switch statement provides an alternative to long if–else chains when comparing a single variable against
many constant values.
Syntax:
switch (variable) {
case value1:
// Code for case value1
break;
case value2:
// Code for case value2
break;
// ...
default:
// Code if no case matches
}

Example:
int day = 3;
switch (day) {
case 1:
System.out.println("Monday");
break;
case 2:
System.out.println("Tuesday");
break;
case 3:
System.out.println("Wednesday");
break;
default:
System.out.println("Another day");
}

2. Looping Statements
Loops allow the repeated execution of a block of code until a condition is met.

2.1 while Loop


The while loop checks its condition before executing the loop body.
Syntax:
while (condition) {
// Loop body: executed as long as condition is true
}

Example:
int i = 1;
while (i <= 5) {
System.out.println("i = " + i);
i++;
}

2.2 do–while Loop


The do–while loop executes its body first and then checks the condition. This guarantees that the loop body
runs at least once.
Syntax:
do {
// Loop body
} while (condition);
Example:
int j = 1;
do {
System.out.println("j = " + j);
j++;
} while (j <= 5);

2.3 for Loop


The for loop is ideal when the number of iterations is known beforehand. It integrates initialization,
condition-checking, and update in one statement.
Syntax:
for (initialization; condition; update) {
// Loop body
}

Example:
for (int k = 1; k <= 5; k++) {
System.out.println("k = " + k);
}

2.4 Nested Loops


Nested loops occur when one loop is placed inside the body of another. The inner loop completes all its
iterations for every single iteration of the outer loop.

Example:
for (int row = 1; row <= 3; row++) {
for (int col = 1; col <= 3; col++) {
System.out.print("[" + row + "," + col + "] ");
}
System.out.println(); // Move to next line after each row
}

2.5 break and continue Statements


• break: Immediately exits the closest loop (or switch), regardless of the remaining iterations.
• continue: Skips the rest of the current loop iteration and moves to the next iteration.
Examples:

Example (Using break):


for (int num = 1; num <= 10; num++) {
if (num == 6) {
break; // Exit the loop when num is 6
}
System.out.print(num + " ");
}
// Output: 1 2 3 4 5

Example (Using continue):


for (int num = 1; num <= 10; num++) {
if (num % 2 == 0) {
continue; // Skip even numbers
}
System.out.print(num + " ");
}
// Output: 1 3 5 7 9
Example (Using continue - Break in nested loops with a label):
outer:
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++) {
if (i * j > 2) {
break outer; // Exits both loops when condition is met
}
System.out.print("(" + i + "," + j + ") ");
}
System.out.println();
}
// Output: 1 3 5 7 9

Conclusion
In this lesson, we explored how Java enables decision-making and repetitive tasks through selection and
looping statements. We learned that:

• Selection Statements:
o Boolean variables, expressions, and literals form the basis of decision making.
o Relational and logical operators help combine and compare values.
o The if statement (in its one-way, two-way, nested, and multi-way forms) and switch
statement allow you to execute code based on conditions.

• Looping Statements:
o The while, do–while, and for loops help repeat actions, with each suited for different
scenarios.
o Nested loops are valuable for processing multi-dimensional data or creating patterns.
o The break and continue statements give you fine-grained control over loop execution.

Mastering these constructs is essential for developing efficient, clear, and maintainable Java programs. As
you progress, practice by writing small programs that incorporate these selection and looping statements.
Week 04 - Lesson: Methods in Java
Learning Objectives
By the end of this lesson, you will be able to:
• Define what a method is and explain its purpose in Java.
• Differentiate between parameters and arguments.
• Discuss the different return types of methods (void and value-returning methods).
• Understand the concept of variable scope within methods.
• Define and use method overloading to write cleaner and more modular code.

Key Terms and Their Meanings


• Method: A block of code designed to perform a specific task; it promotes code reusability and
modularity.
• Parameter: A variable declared in a method’s header that acts as a placeholder for a value to be
passed into the method.
• Argument: The actual value passed to the method when it is invoked.
• Return type: The data type of the value a method returns; it could be a primitive type, an object, or
void if no value is returned.
• void: A keyword indicating that a method does not return any value.
• Method signature: The unique combination of a method’s name and its parameter list; it
distinguishes one method from another.
• Method overloading: The ability to define multiple methods with the same name in a class, as long
as their parameter lists differ.
• Variable scope: The region within the code where a variable is accessible; local variables declared
in a method are only accessible within that method.

Lesson Content
1. What Are Methods?
Methods in Java are self-contained blocks of code that perform specific tasks. They allow you to break
complex problems into smaller, manageable parts, increase code reusability, and improve readability.
Rather than writing the same code multiple times, you can call a method whenever you need to perform
that task.

Example
public class Calculator {
// 'a' and 'b' are parameters
public static int add(int a, int b) {
return a + b;
}

public static void main(String[] args) {


// 5 and 10 are arguments passed to the add method
int sum = add(5, 10);
System.out.println("Sum: " + sum);
}
}
In this example, the method sayHello() encapsulates the task of printing "Hello, World!" and is called from
the main method.

2. Parameters vs. Arguments


• Parameters are the variables listed in a method’s definition.
• Arguments are the actual values passed to the method when it is called.

Example
public class HelloWorld {
public static void main(String[] args) {
sayHello(); // method invocation
}

// Method definition
public static void sayHello() {
System.out.println("Hello, World!");
}
}
3. Method Return Types (void vs. Value-Returning Methods)
A method’s return type indicates whether the method returns a value:
• void methods do not return any value.
• Value-returning methods specify a return type (e.g., int, double) and use the return statement to
pass a value back to the caller.

Example
Void method:
public static void printMessage() {
System.out.println("This method does not return a value.");
}
Value-returning method:
public static int multiply(int x, int y) {
return x * y; // returns an integer value
}

4. Scope of Variables
The scope of a variable is the part of the program where it can be accessed:
• Local variables: Declared within a method, only accessible within that method.
• Parameters: Considered local variables whose scope is limited to the method body.

Example
public class ScopeDemo {
public static void main(String[] args) {
int result = add(3, 4);
System.out.println("Result: " + result);
// 'x' and 'y' are not accessible here because they are local to the add method.
}

public static int add(int x, int y) {


// 'x' and 'y' are local variables (and parameters) with scope limited to this method.
int sum = x + y;
return sum;
}
}

5. Method Overloading
Method overloading allows you to define multiple methods with the same name in the same class, as long
as they have different parameter lists (different number or types of parameters). This enhances code
readability and usability by providing different ways to perform similar tasks.

Example
public class OverloadExample {
// Overloaded method: two int parameters
public static int add(int a, int b) {
return a + b;
}

// Overloaded method: three int parameters


public static int add(int a, int b, int c) {
return a + b + c;
}

public static void main(String[] args) {


System.out.println("Sum of 2 numbers: " + add(5, 10)); // Calls first add method
System.out.println("Sum of 3 numbers: " + add(5, 10, 15)); // Calls second add method
}
}
Conclusion
In this lesson, we covered the fundamental concepts related to methods in Java:

• Methods allow you to encapsulate code for specific tasks, promoting modularity and reusability.
• Parameters vs. Arguments: Parameters are placeholders in method definitions, while arguments
are the actual values passed when the method is invoked.
• Return Types: Methods can either return a value (e.g., int, double) or be declared with void to
indicate they do not return any value.
• Variable Scope: Variables declared within a method (including parameters) are only accessible
within that method.
• Method Overloading: You can define multiple methods with the same name as long as they have
different parameter lists, making your code more flexible and easier to understand.

Understanding these concepts is essential for writing well-structured, maintainable, and reusable Java
programs. As you continue learning, practice writing methods to perform common tasks and explore more
advanced topics such as recursion and passing objects as parameters.
Week 05 - Lesson: Objects and Classes in Java

Learning Objectives
By the end of this lesson, you will be able to:
• Discuss the concepts of objects and classes and understand their roles in Java.
• Create classes and objects to model real-world entities.
• Understand and use access modifiers (public, private, protected) to control visibility.
• Define and use methods and attributes (data fields) within classes.
• Implement constructors to initialize objects at creation time.
• Discuss deconstructors and garbage collection, noting that Java handles memory cleanup
automatically.
• Define and use class methods and class variables (static members) that belong to the class
rather than any instance.

Key Terms and Short Definitions


• Object: An instance of a class that encapsulates state (attributes) and behavior (methods).
• Class: A blueprint or template that defines the properties (attributes) and actions (methods) for
objects.
• Access modifiers: Keywords (public, private, protected) that set the visibility and accessibility of
classes, methods, and fields.
• Methods: Functions defined within a class that describe the behaviors or actions that objects can
perform.
• Attributes: Also known as data fields; these are variables declared in a class that hold the state of
an object.
• Constructors: Special methods with the same name as the class, used to initialize objects when
they are created.
• Deconstructors: Unlike some languages, Java does not use explicit deconstructors; instead, it
relies on garbage collection to reclaim memory when objects are no longer referenced.
• Garbage collection: The process by which the Java Virtual Machine (JVM) automatically removes
unused objects from memory.
• Class methods: Also known as static methods; these methods belong to the class itself rather than
to any individual instance.
• Class variables: Also known as static variables; these variables are shared by all instances of a
class.

Lesson Content

1. Objects and Classes

1.1 Objects and Classes Overview


• Objects:
Represent real-world entities. They combine state (attributes) and behavior (methods) in a single
package.
• Classes:
Serve as blueprints for objects. A class defines the attributes and methods that its objects will have.

Example
public class Car {
// Attributes (fields)
String color;
String model;

// Methods
void drive() {
System.out.println("The " + this.color + " " + this.model + " is driving.");
}
}

Here, Car is a class, and individual cars created from it are objects.
1.2 Creating Classes and Objects
• Creating a Class: Use the class keyword to define a class, and inside, declare attributes and
methods.
• Creating an Object: Use the new keyword to instantiate a class.

Example
public class Main {
public static void main(String[] args) {
// Creating an object (instance) of the Car class
Car myCar = new Car();
myCar.color = "red";
myCar.model = "Toyota";
myCar.drive(); // Output: The red Toyota is driving.
}
}

2. Access Modifiers
Access modifiers control the visibility of classes, methods, and attributes:
• public: Accessible from any class.
• private: Accessible only within the same class.
• protected: Accessible within the same class, subclasses, and classes in the same package.

Example
public class Person {
public String name; // Accessible anywhere
private int age; // Accessible only within Person
protected String address; // Accessible within package and subclasses

// Public method to access private age


public int getAge() {
return this.age;
}

public void setAge(int age) {


if(age >= 0) { // Validation before setting age
this.age = age;
}
}
}

3. Methods and Attributes


• Attributes:
Variables that store the state of an object.
• Methods:
Functions that define the behaviors of an object.

Example
public class Calculator {
// Attribute
int lastResult;

// Method: adds two numbers and updates lastResult


public int add(int a, int b) {
this.lastResult = a + b;
return this.lastResult;
}
}
4. Constructors
Constructors are special methods invoked when an object is created. They initialize the object’s state.

Example
public class Book {
String title;
String author;

// Constructor: same name as the class, no return type


public Book(String title, String author) {
this.title = title;
this.author = author;
}
}

public class Library {


public static void main(String[] args) {
// Creating a new Book object using the constructor
Book myBook = new Book("1984", "George Orwell");
System.out.println("Book: " + myBook.title + " by " + myBook.author);
}
}

5. Deconstructors and Garbage Collection


• Deconstructors: Java does not have explicit deconstructors. Instead, it uses garbage collection.
• Garbage Collection: The JVM automatically frees memory occupied by objects that are no longer
in use.

Key Point: While you cannot force garbage collection, you can suggest it by calling System.gc(), though
this is generally not recommended in production code.

6. Class Methods and Class Variables


• Class Methods (static methods): Belong to the class rather than any instance. They are declared
with the static keyword.
• Class Variables (static variables): Shared among all instances of a class.

Example
public class MathUtil {
// Class variable: shared by all instances
public static final double PI = 3.14159;

// Class method: can be called without creating an instance of MathUtil


public static int square(int number) {
return number * number;
}
}

public class TestStatic {


public static void main(String[] args) {
// Accessing class variable and method without an object
System.out.println("PI: " + MathUtil.PI);
System.out.println("Square of 5: " + MathUtil.square(5));
}
}
Conclusion
In this lesson, we have covered the foundational aspects of objects and classes in Java:

• Objects and Classes: We learned that classes serve as blueprints for objects, encapsulating state
and behavior.

• Access Modifiers: We discussed how public, private, and protected keywords control the visibility
of class members.

• Methods and Attributes: Methods define behavior, while attributes represent the state of an
object.

• Constructors: Constructors initialize new objects.

• Deconstructors and Garbage Collection: Java automatically reclaims memory via garbage
collection, so explicit deconstructors are not required.

• Class Methods and Class Variables: Static members belong to the class rather than individual
objects, enabling shared behavior and data.

Mastering these concepts is essential for building well-structured, maintainable, and reusable Java
applications. As you continue learning, practice by designing classes that model real-world scenarios and
experimenting with various access levels, constructors, and static members.
Week 06 - Lesson: Object-Oriented Thinking and Class Relationships in Java
Learning Objectives
By the end of this lesson, you will be able to:
• Understand the concept of object-oriented thinking.
• Learn the differences between the procedural paradigm and the object-oriented paradigm.
• Explore common relationships among classes: association, aggregation, and composition.
• Design classes use object-oriented principles such as abstraction and encapsulation.

Key Terms
• Class Abstraction: The separation of a class’s implementation details from the way it is used. It
allows the user to interact with a class solely through its public interface.
• Class Encapsulation: The practice of hiding the internal state and implementation details of a
class, exposing only what is necessary through public methods.
• Abstract Data Type (ADT): A data type defined by its behavior (the operations that can be
performed) rather than its implementation.
• Association: A general relationship between two classes that indicates they interact with each
other. It is a broad term for any connection between objects.
• Aggregation: A specialized form of association that represents an “owns-a” relationship, where one
object (the whole) contains another object, but both can exist independently.
• Composition: A strong form of aggregation where the lifetime of the contained object is strictly
dependent on the lifetime of the container object.

Lesson Content

1. Object-Oriented Thinking
Object-oriented thinking is a paradigm that models real-world entities as objects—each having state
(attributes) and behavior (methods). This approach focuses on designing software by modeling
interactions among these objects. In Java, everything (except primitive types) is an object, and classes
serve as blueprints for these objects.

Key idea: Rather than writing step-by-step instructions (as in procedural programming), you design objects
that interact with one another to accomplish tasks.

2. Procedural Paradigm vs. Object-Oriented Paradigm

• Procedural Paradigm: In procedural programming, code is organized into procedures or functions


that operate on data. The focus is on the sequence of tasks to perform.

• Object-Oriented Paradigm: In OOP, data and functions are bundled together within objects. This
design facilitates reuse, scalability, and maintainability by emphasizing real-world modeling.

Comparison: While procedural programming separates functions from data, OOP couples them,
promoting encapsulation and modular design. This shift enhances software reusability and
maintainability.

3. Class Relationships
Understanding how classes interact is crucial in object-oriented design. Three common types of
relationships are:

• Association: A general relationship where two classes are connected because they interact. For
example, a Teacher class might be associated with a Student class.

• Aggregation: A specialized form of association representing an ownership relationship where the


contained object can exist independently. For example, a Library class aggregates Book objects, but
a book can exist even if the library is closed.

• Composition:
A stronger form of aggregation where the lifetime of the contained object is tied to the container. For
example, a House class is composed of Room objects; if the house is destroyed, the rooms cease
to exist.
4. Designing Classes Using OOP Principles
When designing classes, keep in mind the following principles:

• Class Abstraction: Design your class so that users interact with it through a well-defined interface
without knowing the internal workings.

• Class Encapsulation: Hide the internal state of the class and expose only necessary functionalities
through public methods. Use access modifiers (public, private, protected) to control visibility.

• Defining Relationships: Decide whether a relationship between classes is a simple association,


aggregation, or composition. This choice affects how objects are created, managed, and destroyed.

Example:
Consider a class Car that aggregates Engine objects. In an aggregation relationship, the engine may be
replaced or exist outside the context of the car. In a composition relationship (e.g., a House composed of
Room objects), rooms do not exist independently of the house.

Conclusion
In this lesson, we explored the fundamentals of object-oriented thinking and examined key class
relationships in Java. We learned that:

• Object-Oriented Thinking centers around modeling real-world entities as objects with attributes
and behaviors.

• The procedural paradigm focuses on functions and sequences of steps, while the object-oriented
paradigm integrates data and behavior for more modular and maintainable code.

• Class relationships—association, aggregation, and composition—allow you to design complex


systems by clearly defining how classes interact.

• Core design principles such as class abstraction and encapsulation are essential for creating
robust and reusable classes.

By understanding these concepts, you will be able to design and implement classes that model real-world
scenarios effectively and build maintainable Java applications.
Week 06 - Lesson: Inheritance, Polymorphism, and Dynamic Binding in Java
Learning Objectives
By the end of this lesson, you will be able to:
• Understand the concept of inheritance and its benefits in object-oriented programming.
• Learn about superclasses and subclasses and their roles in the inheritance hierarchy.
• Use the super keyword to invoke superclass constructors and methods.
• Understand method overriding and its importance for achieving polymorphism.
• Learn about polymorphism and how it allows objects to take on many forms.
• Understand dynamic binding and how the JVM determines which method to call at runtime.

Key Terms
• Inheritance: A mechanism that allows you to create a new class (subclass) based on an existing
class (superclass), inheriting its attributes and behaviors.
• Superclass: The existing (parent) class from which properties and methods are inherited.
• Subclass: The new (child) class that inherits from a superclass and can add its own attributes and
methods.
• Method Overriding: When a subclass provides its own implementation of a method that is already
defined in its superclass. This enables runtime polymorphism.
• Polymorphism: The ability of a variable of a supertype to refer to objects of different subtypes,
allowing the same method call to behave differently based on the actual object type.
• Dynamic Binding: The process by which the Java Virtual Machine (JVM) determines at runtime
which overridden method to call, based on the actual object’s type rather than the reference type.
• super Keyword: Used in a subclass to call a constructor or method of its superclass, allowing
access to overridden or hidden members.

Lesson Content

1. Inheritance
Inheritance is a cornerstone of object-oriented programming. It allows you to create new classes that are
built upon existing classes. This not only promotes code reuse by allowing subclasses to inherit common
functionality from a superclass but also helps in building a logical hierarchy that models real-world
relationships.

Example
// Superclass (Parent)
public class Animal {
public void makeSound() {
System.out.println("Some generic animal sound");
}
}

// Subclass (Child) inherits from Animal


public class Dog extends Animal {
// Method Overriding
@Override
public void makeSound() {
System.out.println("Bark!");
}
}

In this example, Dog inherits from Animal and overrides the makeSound() method to provide a specific
behavior.

2. Superclass and Subclass

• Superclass:
The parent class that defines common attributes and methods.

• Subclass:
The child class that inherits from the superclass and can add its own properties or override inherited
methods.
Using the super Keyword: The super keyword is used within a subclass to:
• Invoke the superclass constructor.
• Call a method from the superclass that has been overridden in the subclass.

Example
public class Animal {
String name;

// Constructor of the superclass


public Animal(String name) {
this.name = name;
}

public void display() {


System.out.println("Animal: " + name);
}
}

public class Cat extends Animal {


String breed;

// Subclass constructor calls superclass constructor using super()


public Cat(String name, String breed) {
super(name); // Calls Animal(String name)
this.breed = breed;
}

// Overriding the display method


@Override
public void display() {
// Calling superclass method
super.display();
System.out.println("Breed: " + breed);
}
}
In this example, Cat is a subclass of Animal. It uses super(name) to invoke the Animal constructor and
super.display() to call the superclass method within the overridden display() method.

3. Method Overriding and Polymorphism

Method Overriding: When a subclass provides its own implementation of a method already defined in its
superclass, it is known as method overriding. This allows the subclass to offer specific behavior while
preserving the method’s signature.

Example
public class Bird extends Animal {
@Override
public void makeSound() {
System.out.println("Chirp!");
}
}
Polymorphism: Polymorphism allows you to use a superclass reference to objects of a subclass. This
means you can write code that works on the superclass level, but the actual behavior at runtime is
determined by the subclass.

Example
public class TestPolymorphism {
public static void main(String[] args) {
Animal myAnimal = new Dog(); // Dog is an Animal
myAnimal.makeSound(); // Outputs "Bark!" due to dynamic binding

myAnimal = new Cat("Whiskers", "Siamese");


myAnimal.makeSound(); // Calls Cat's version of makeSound() if overridden, else Animal's method
}
}

Example:
Here, even though the variable myAnimal is of type Animal, it can hold objects of subclasses (Dog, Cat).
The actual method called is determined at runtime (dynamic binding), demonstrating polymorphism.

4. Dynamic Binding
Dynamic binding (or late binding) is the process by which the JVM determines at runtime which method
implementation to invoke when a method is overridden in a subclass. This means that the method call is
resolved based on the actual object type, not the reference type.

Example
Animal animalRef = new Dog();
animalRef.makeSound(); // JVM dynamically binds the Dog's implementation of makeSound()

animalRef = new Cat("Luna", "Persian");


animalRef.makeSound(); // JVM dynamically binds the Cat's implementation of makeSound()
Dynamic binding is essential for polymorphism, allowing your program to be flexible and extensible.

Conclusion
Inheritance, polymorphism, and dynamic binding form the backbone of object-oriented programming in
Java. In this lesson, we learned that:

• Inheritance allows you to define new classes based on existing classes, promoting code reuse and
reducing redundancy.

• Superclasses and subclasses define a hierarchy where subclasses inherit common behavior from
superclasses and can extend or override that behavior.

• The super keyword provides a way to invoke superclass constructors and methods, ensuring that
inherited behaviors are accessible.

• Method overriding is a key feature that enables polymorphism by allowing subclasses to provide
specialized implementations.

• Polymorphism lets a single reference variable refer to objects of different subclasses, while
dynamic binding ensures that the appropriate method is called at runtime.

By mastering these concepts, you will be able to design and implement robust, flexible, and maintainable
object-oriented applications in Java. These principles not only help in creating efficient code but also in
modeling real-world problems in a clear and organized way.
Week 07 - Lesson: The Java String Class
Learning Objectives
By the end of this lesson, you will be able to:
• Discuss the Java String class and its purpose.
• Declare and instantiate String objects.
• Perform String concatenation, determine String length, and compare String objects.
• Format Strings using printf.
• Manipulate Strings using methods like substring, indexOf, and lastIndexOf.

Key Terms
• String: A sequence of characters; in Java, it is an immutable object from the java.lang package.
• String concatenation: The process of combining two or more strings into one.
• String length: The total number of characters in a String, determined using the length() method.
• String comparison: Checking whether two strings have the same sequence of characters (using
methods like equals and compareTo).
• String formatting: Creating formatted text output with methods such as printf and format
specifiers.
• String manipulation: Altering or extracting portions of a string using methods like substring,
indexOf, and lastIndexOf.

1. The Java String Class

1.1 Overview
A String in Java represents a sequence of characters. The String class is fundamental because it offers
built-in methods to create, compare, and manipulate text. Strings are immutable, meaning once created
their content cannot change.

1.2 Declaring and Instantiating String Objects


There are two common ways to create a String in Java:
1. Using a String literal: This is the simplest form and Java automatically creates a String object for
you.

Example
String greeting = "Welcome to Java";

2. Using the new keyword: Explicitly creates a new String object.

Example
String message = new String("Welcome to Java");

1.3 String Concatenation


String concatenation combines two or more strings into one. It can be done using the concat method:

Example
String s1 = "Welcome ";
String s2 = "to ";
String s3 = "Java";
String s4 = s1.concat(s2).concat(s3); // "Welcome to Java"
The + operator:
String s5 = s1 + s2 + s3; // Also "Welcome to Java"

1.4 String Length


The length() method returns the number of characters in a String.

Example
String message = "Welcome to Java";
int length = message.length(); // length is 15
1.5 String Comparison
There are two common ways to compare strings:
• Using equals: Checks if two strings have the same content.

Example
String s1 = "Welcome to Java";
String s2 = "Welcome to Java";
boolean isEqual = s1.equals(s2); // returns true

• Using compareTo: Compares strings lexicographically.

Example
String s3 = "Welcome to C++";
int comparison = s1.compareTo(s3); // returns a positive value if s1 > s3 lexicographically

1.6 String Formatting


The printf method enables formatted output. Use format specifiers like %s for strings and %d for integers.

Example
String name = "John";
int age = 30;
System.out.printf("My name is %s and I am %d years old.\n", name, age);

1.7 String Manipulation


The String class provides several useful methods:
• substring: Extracts a portion of a string.

Example
String text = "Welcome to Java";
String sub = text.substring(8); // "to Java"

• indexOf: Returns the index of the first occurrence of a character or substring.

Example
int index = text.indexOf("Java"); // index where "Java" starts

• lastIndexOf: Returns the index of the last occurrence of a character or substring.

Example
int lastIndex = text.lastIndexOf("a"); // last occurrence of 'a'

2. Conclusion
In this lesson, we examined the Java String class, a fundamental part of Java programming for working with
text. We learned how to:

• Declare and instantiate String objects.

• Concatenate strings using both the + operator and the concat method.

• Determine the length of a String using length().

• Compare strings using equals and compareTo.

• Format strings with printf and format specifiers.

• Manipulate strings using methods like substring, indexOf, and lastIndexOf.

Understanding these concepts and methods is essential for writing efficient, readable, and maintainable
Java programs. As you practice, try experimenting with these methods in various scenarios to deepen your
familiarity with string handling in Java.
Lesson: Arrays and Vectors in Java
Learning Objectives
By the end of this lesson, you will be able to:
• Discuss the use of arrays for storing collections of elements.
• Declare and instantiate arrays of various data types.
• Access and modify elements in arrays.
• Traverse through arrays using loops and iterators.
• Search for elements in arrays using linear and binary search.
• Explain the concept of vectors and how they differ from arrays.
• Create and manipulate one-dimensional, two-dimensional, and multi-dimensional vectors.
• Perform operations on vectors such as adding, removing, and searching for elements.

Key Terms and Short Definitions


• Array: A fixed-size data structure that stores a sequential collection of elements of the same type.
• Vector: A dynamic array (from java.util) that can grow or shrink in size as needed.
• One-dimensional array: An array with a single index; it stores elements in a single row.
• Two-dimensional array: An array of arrays; it is like a table with rows and columns.
• Multi-dimensional array: An array with more than two dimensions; essentially an array of arrays of
arrays, etc.
• Index: A numerical position used to access an element in an array; indexing in Java starts at 0.
• Element: An individual value stored in an array or vector.
• Array declaration: The statement that defines an array’s type and name (e.g., int[] numbers;).
• Array instantiation: The process of allocating memory for an array using the new keyword (e.g., new
int[10];).
• Array initialization: Assigning initial values to an array’s elements at the time of declaration or
afterward.
• Linear search: A search method that checks each element in sequence until the target is found.
• Binary search: A more efficient search method that requires a sorted array and repeatedly divides
the search interval in half.

1. Arrays

1.1 Overview of Arrays


An array is a data structure that stores a fixed-size, sequential collection of elements, all of the same type.
Because arrays have a fixed size, they must be allocated with a specific number of elements, and their
length cannot change once created.

1.2 Declaring, Instantiating, and Initializing Arrays


To declare an array in Java, use the type followed by square brackets and a variable name. To instantiate an
array, use the new keyword along with the type and size.

Example
// Declaration and instantiation of an array of 10 integers
int[] numbers = new int[10];

// Array initialization can also be done at the time of declaration:


int[] primes = {2, 3, 5, 7, 11};

1.3 Accessing and Modifying Array Elements


Array elements are accessed using an index (starting at 0).

Example
numbers[0] = 5; // Assigns 5 to the first element
int firstPrime = primes[0]; // Retrieves the first element (2)
System.out.println("First prime: " + firstPrime);
1.4 Traversing Arrays
Arrays can be traversed using loops such as the classic for-loop, enhanced for-loop (for-each), or even
iterators (if converting to collections).

Example
for (int i = 0; i < numbers.length; i++) {
System.out.println("Element at index " + i + ": " + numbers[i]);
}

1.5 Searching in Arrays


• Linear Search: Sequentially checks each element until the desired element is found.

Example
int target = 7;
boolean found = false;
for (int num : primes) {
if (num == target) {
found = true;
break;
}
}
System.out.println("Target found: " + found);

• Binary Search: Requires a sorted array and repeatedly divides the search interval in half.
(Java’s Arrays.binarySearch() method can be used for this purpose.)

Example
import java.util.Arrays;

int[] sortedArray = {2, 3, 5, 7, 11};


int index = Arrays.binarySearch(sortedArray, 7);
System.out.println("Index of 7: " + index);

2. Vectors

2.1 Overview of Vectors

A vector is a dynamic array provided by Java in the java.util package. Unlike arrays, vectors can grow or
shrink dynamically as elements are added or removed. Vectors are synchronized (thread-safe) but have
more overhead compared to other dynamic array classes like ArrayList.

2.2 Declaring and Instantiating Vectors

Example
import java.util.Vector;

Vector<Integer> numbersVector = new Vector<>(); // A vector of integers

2.3 Adding, Accessing, and Traversing Vectors


Adding Elements:

Example
numbersVector.add(5);
numbersVector.add(10);
numbersVector.add(15);

Accessing Elements:

Example
int firstElement = numbersVector.get(0);
System.out.println("First element: " + firstElement);
Traversing with a for-loop:

Example
for (int i = 0; i < numbersVector.size(); i++) {
System.out.println("Element at index " + i + ": " + numbersVector.get(i));
}

2.4 Searching in Vectors


Vectors provide methods such as contains and indexOf to search for elements.

Example
if (numbersVector.contains(10)) {
System.out.println("Vector contains 10 at index: " + numbersVector.indexOf(10));
}

3. Multi-Dimensional Arrays

3.1 Overview
Java supports multi-dimensional arrays, which are essentially arrays of arrays. A two-dimensional array
can be thought of as a table with rows and columns.

Example
// Declaration and instantiation of a 5x5 matrix of integers
int[][] matrix = new int[5][5];

3.2 Accessing Elements


Elements are accessed using two indices:

Example
matrix[0][0] = 1; // Assigns 1 to the element in the first row and first column
System.out.println("Element at (0,0): " + matrix[0][0]);

3.3 Traversing Multi-Dimensional Arrays

2D Array: The following example demonstrates how to traverse a 2D array (matrix) using nested loops:

Example
public class TwoDArrayExample {
public static void main(String[] args) {
// A 3x4 matrix of integers
int[][] matrix = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};

System.out.println("2D Array (Matrix):");


// Loop through rows and columns
for (int i = 0; i < matrix.length; i++) { // For each row
for (int j = 0; j < matrix[i].length; j++) { // For each column
System.out.print(matrix[i][j] + " ");
}
System.out.println(); // New line after each row
}
}
}
3D Array: This example shows how to work with a 3D array using three nested loops:

Example
public class ThreeDArrayExample {
public static void main(String[] args) {
// Declaration and instantiation of a 3D array (2 blocks x 3 rows x 4 columns)
int[][][] threeDArray = {
{
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 }
},
{
{ 13, 14, 15, 16 },
{ 17, 18, 19, 20 },
{ 21, 22, 23, 24 }
}
};

System.out.println("3D Array:");
// Traverse the 3D array with three nested loops
for (int i = 0; i < threeDArray.length; i++) { // For each block
System.out.println("Block " + (i + 1) + ":");
for (int j = 0; j < threeDArray[i].length; j++) { // For each row in the block
for (int k = 0; k < threeDArray[i][j].length; k++) { // For each element in the row
System.out.print(threeDArray[i][j][k] + " ");
}
System.out.println(); // New line after each row
}
System.out.println(); // Extra line between blocks
}
}
}

4. Conclusion
In this lesson, we explored two essential data structures in Java: arrays and vectors.

• Arrays are fixed-size, sequential data structures used to store elements of the same type. We
learned how to declare, instantiate, and initialize arrays, access and modify elements, traverse
arrays with loops, and search using linear and binary search methods.

• Vectors are dynamic arrays that can adjust their size as needed. We covered how to declare and
instantiate vectors, add and access elements, traverse vectors, and search for elements using built-
in methods.

• We also briefly discussed multi-dimensional arrays, which allow for the storage and manipulation
of data in a matrix-like format.

Understanding arrays and vectors is fundamental for writing efficient and effective Java programs that
require storing and processing collections of elements. Master these concepts through hands-on
practice, and you’ll be well prepared for more complex data structures and algorithms.
Week 08 - Lesson: The Java Collections Framework
Learning Objectives
By the end of this lesson, you will be able to:
• Understand the purpose of the Collections Framework in Java.
• Identify different types of collections: Lists, Stacks, Queues, Priority Queues, Sets, and Maps.
• Explain the characteristics and appropriate use cases of each collection type.
• Explore common methods and operations provided by each collection.
• Use iterators to traverse through collection elements.

Key Terms
• Collection: A framework that provides architecture to store and manipulate groups of objects.
• List: An ordered collection that allows duplicate elements.
• Stack: A Last-In, First-Out (LIFO) data structure used to store elements in reverse order of insertion.
• Queue: A First-In, First-Out (FIFO) data structure where the first element added is the first one
removed.
• Priority Queue: A data structure where elements are processed based on their assigned priority
rather than insertion order.
• Set: A collection that stores unique (non-duplicate) elements.
• Map: A collection that stores key-value pairs, where each key is unique.
• Iterator: An object that enables you to traverse the elements of a collection sequentially.

Lesson Content

1. The Collections Framework Overview

The Java Collections Framework is a unified architecture for representing and manipulating collections.
It provides interfaces and classes for various data structures (Lists, Sets, Maps, etc.) that improve code
reusability and efficiency. All these classes reside in the java.util package.

2. Lists
A List is an ordered collection that allows duplicate elements. Two common implementations are:

• ArrayList: Uses a dynamic array. It provides fast random access but slower insertion/deletion in the
middle.

Example
import java.util.ArrayList;
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("Apple");
arrayList.add("Banana");
System.out.println(arrayList); // Output: [Apple, Banana]

• LinkedList: Uses a doubly linked list. It provides efficient insertion and deletion at any position but
slower random access.

Example
import java.util.LinkedList;
LinkedList<String> linkedList = new LinkedList<>();
linkedList.add("Carrot");
linkedList.add("Date");
System.out.println(linkedList); // Output: [Carrot, Date]

3. Stacks
A Stack is a LIFO data structure. The Java Collections Framework includes the legacy Stack class (which
extends Vector) for simple stack operations.

Example
import java.util.Stack;
Stack<Integer> stack = new Stack<>();
stack.push(10);
stack.push(20);
int top = stack.pop(); // Removes 20
System.out.println("Popped element: " + top); // Output: 20
4. Queues
A Queue is a FIFO data structure. The Queue interface has several implementations; two common ones
are LinkedList and PriorityQueue.

• LinkedList as a Queue:

Example
import java.util.Queue;
import java.util.LinkedList;
Queue<String> queue = new LinkedList<>();
queue.add("First");
queue.add("Second");
String head = queue.poll(); // Retrieves and removes "First"
System.out.println("Head of queue: " + head); // Output: First

• PriorityQueue:

Example
import java.util.PriorityQueue;
PriorityQueue<Integer> pq = new PriorityQueue<>();
pq.add(30);
pq.add(10);
pq.add(20);
int highestPriority = pq.poll(); // Retrieves and removes the smallest element (10)
System.out.println("Priority element: " + highestPriority); // Output: 10

5. Sets
A Set stores unique elements without duplicates. Common implementations include:

• HashSet: Uses a hash table; fast for basic operations but does not maintain order.

Example
import java.util.HashSet;
HashSet<String> set = new HashSet<>();
set.add("Red");
set.add("Blue");
set.add("Red"); // Duplicate; ignored
System.out.println(set); // Order not guaranteed

• LinkedHashSet: Maintains insertion order with a slight performance overhead.

Example
import java.util.LinkedHashSet;

public class LinkedHashSetExample {


public static void main(String[] args) {
LinkedHashSet<String> fruits = new LinkedHashSet<>();
fruits.add("Banana");
fruits.add("Apple");
fruits.add("Cherry");
fruits.add("Date");

System.out.println("LinkedHashSet (insertion order):");


for (String fruit : fruits) {
System.out.println(fruit);
}
}
}
• TreeSet:
Stores elements in sorted order but can be slower for insertion.

Example
import java.util.TreeSet;

public class TreeSetExample {


public static void main(String[] args) {
TreeSet<String> fruits = new TreeSet<>();
fruits.add("Banana");
fruits.add("Apple");
fruits.add("Cherry");
fruits.add("Date");

System.out.println("TreeSet (sorted order):");


for (String fruit : fruits) {
System.out.println(fruit);
}
}
}

6. Maps
A Map stores key-value pairs, with each key unique. Common implementations include:
• HashMap: Uses a hash table; offers fast operations but no ordering.

Example
import java.util.HashMap;
HashMap<String, Integer> map = new HashMap<>();
map.put("Alice", 25);
map.put("Bob", 30);
System.out.println("Map: " + map);

• LinkedHashMap: Maintains insertion order.

Example
import java.util.LinkedHashMap;
import java.util.Map;

public class LinkedHashMapExample {


public static void main(String[] args) {
LinkedHashMap<Integer, String> numberMap = new LinkedHashMap<>();
numberMap.put(3, "Three");
numberMap.put(1, "One");
numberMap.put(4, "Four");
numberMap.put(2, "Two");

System.out.println("LinkedHashMap (insertion order):");


for (Map.Entry<Integer, String> entry : numberMap.entrySet()) {
System.out.println(entry.getKey() + " => " + entry.getValue());
}
}
}
• TreeMap: Stores keys in sorted order.

Example
import java.util.TreeMap;
import java.util.Map;

public class TreeMapExample {


public static void main(String[] args) {
TreeMap<Integer, String> numberMap = new TreeMap<>();
numberMap.put(3, "Three");
numberMap.put(1, "One");
numberMap.put(4, "Four");
numberMap.put(2, "Two");

System.out.println("TreeMap (keys in sorted order):");


for (Map.Entry<Integer, String> entry : numberMap.entrySet()) {
System.out.println(entry.getKey() + " => " + entry.getValue());
}
}
}

7. Iterators
An Iterator allows you to traverse a collection one element at a time. It is used with most collection types
to safely remove or process elements.

Example
import java.util.ArrayList;
import java.util.Iterator;
ArrayList<String> list = new ArrayList<>();
list.add("Item1");
list.add("Item2");

Iterator<String> iter = list.iterator();


while (iter.hasNext()) {
System.out.println(iter.next());
}

Conclusion

In this lesson, we examined the Java Collections Framework, an essential toolkit for storing and
manipulating groups of objects. We discussed:

• Lists as ordered collections (using ArrayList and LinkedList).

• Stacks and their LIFO behavior.

• Queues (FIFO) and Priority Queues for processing elements based on priority.

• Sets for storing unique elements.

• Maps for managing key-value pairs.

• The role of iterators in traversing collections.

Understanding these collection types, their characteristics, and common operations will enable you to
write more efficient, maintainable, and flexible Java applications. By selecting the appropriate collection
for your specific task, you can optimize performance and code clarity.

You might also like