Java Arrays
Programs consist of logic and data, and arrays are a powerful tool for storing structured data.
One-Dimensional Arrays
Defining One-Dimensional Arrays
// Declare array reference first, then allocate memory
// int[] grades;
// grades = new int[10];
// Combined declaration and initialization
int[] scores = new int[10], helper; // helper is an uninitialized array reference
float[] measurements = new float[33];
double[] precisionData = new double[123];
char[] charBuffer = new char[21];
String[] stringList = new String[10];
Array Initialization
// Direct inline value initialization
int[] fixedNums = {5, 10, 15}; // 3-element array with values 5,10,15
int[] defaultInit = new int[3]; // 3 elements all initialized to 0
char[] charSet = {'x', 'y', 'z'}; // Character array initialization
Accessing Array Elements
Array elements are accessed using zero-based indices:
public class ArrayElementAccess {
public static void main(String[] args) {
int[] sampleArr = {2, 4, 6}; // Indices start at 0
System.out.printf("%d %d %d%n", sampleArr[0], sampleArr[1], sampleArr[2]);
sampleArr[0] = 8;
System.out.println(sampleArr[0]);
}
}
Enhanced For-Loop Traversal
import java.util.Scanner;
public class EnhancedLoopDemo {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] userArray = new int[10];
for (int i = 0; i < 10; i++) {
userArray[i] = i;
}
for (int num : userArray) {
System.out.println(num);
}
}
}
Practice Exercise 1: Calculate Nth Fibonacci Number Using Array
import java.util.Scanner;
public class FibonacciArray {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int target = input.nextInt();
int[] fibSequence = new int[target + 1]; // Covers indices 0 to target
fibSequence[0] = 0;
fibSequence[1] = 1;
for (int i = 2; i <= target; i++) {
fibSequence[i] = fibSequence[i - 1] + fibSequence[i - 2];
}
System.out.println(fibSequence[target]);
}
}
Practice Exercise 2: Reverse and Output Input Integers
import java.util.Scanner;
public class ReverseArrayOutput {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int count = input.nextInt();
int[] inputNums = new int[count];
for (int i = 0; i < count; i++) {
inputNums[i] = input.nextInt();
}
for (int i = count - 1; i >= 0; i--) {
System.out.printf("%d ", inputNums[i]);
}
}
}
Practice Exercise 3: Sort and Output Input Integers in Ascending Order
import java.util.Scanner;
public class BubbleSortArray {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int total = input.nextInt();
int[] sortArray = new int[total];
for (int i = 0; i < total; i++) {
sortArray[i] = input.nextInt();
}
// Bubble sort implementation
for (int i = 0; i < total; i++) {
for (int j = i + 1; j < total; j++) {
if (sortArray[i] > sortArray[j]) {
int temp = sortArray[i];
sortArray[i] = sortArray[j];
sortArray[j] = temp;
}
}
}
for (int num : sortArray) {
System.out.printf("%d ", num);
}
}
}
Two-Dimensional Arrays
Multi-dimensional arrays are essentially arrays of arrays.
Defining Two-Dimensional Arrays
public class TwoDArrayDefinition {
public static void main(String[] args) {
int[][] grid = new int[3][4]; // 3 rows, each with 4 integer elements
int[][][] cube = new int[10][20][30]; // 3D array, all elements default to 0
}
}
Two-Dimensional Array Initialization
public class TwoDArrayInit {
public static void main(String[] args) {
int[][] predefinedGrid = {
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11}
};
// Reset first row to all zeros
for (int i = 0; i < 4; i++) {
predefinedGrid[0][i] = 0;
}
// Print full 2D array
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 4; col++) {
System.out.printf("%d ", predefinedGrid[row][col]);
}
System.out.println();
}
}
}
Enhanced For-Loop for Two-Dimensional Arrays
import java.util.Scanner;
public class TwoDEnhancedLoop {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[][] multiArr = new int[10][10];
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
multiArr[i][j] = i * j;
}
}
for (int[] row : multiArr) {
for (int val : row) {
System.out.printf("%2d ", val);
}
System.out.println();
}
}
}
Standard Array Properties and Utility Methods
length Property
Returns the length of an array, no parentheses required:
public class ArrayLengthDemo {
public static void main(String[] args) {
int[][] sampleGrid = {
{0, 1, 2, 3},
{4, 5, 6, 7},
{8, 9, 10, 11}
};
System.out.println(sampleGrid.length); // Number of rows: 3
for (int i = 0; i < sampleGrid.length; i++) {
System.out.println(sampleGrid[i].length); // Length of each row: 4
}
}
}
Arrays.sort() for Sorting Arrays
import java.util.Arrays;
import java.util.Scanner;
public class ArraySortDemo {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int count = input.nextInt();
int[] unsortedArr = new int[count];
for (int i = 0; i < count; i++) {
unsortedArr[i] = input.nextInt();
}
Arrays.sort(unsortedArr);
System.out.println(Arrays.toString(unsortedArr));
}
}
Reverse Sorting for One-Dimensional Arrays
Requires a custom comparator, use wrapper classes instead of primitive types:
import java.util.Arrays;
import java.util.Scanner;
public class ReverseSortDemo {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int count = input.nextInt();
Integer[] sortArr = new Integer[count];
for (int i = 0; i < count; i++) {
sortArr[i] = input.nextInt();
}
// Sort in descending order
Arrays.sort(sortArr, (a, b) -> b - a);
System.out.println(Arrays.toString(sortArr));
}
}
Sorting Two-Dimensional Arrays
Sort by the first element of each sub-array:
import java.util.Arrays;
public class TwoDSortDemo {
public static void main(String[] args) {
int[][] unsortedGrid = {
{4,5,6,7},
{0,1,2,3},
{8,9,10,11}
};
Arrays.sort(unsortedGrid, (row1, row2) -> row1[0] - row2[0]);
System.out.println(Arrays.deepToString(unsortedGrid));
}
}
Arrays.fill() for Populating Arrays
Sets all elements of a one-dimensional array to a specified value:
import java.util.Arrays;
import java.util.Scanner;
public class ArrayFillDemo {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int[] fillArr = new int[10];
Arrays.fill(fillArr, -1);
System.out.println(Arrays.toString(fillArr));
}
}
Arrays.toString() for One-Dimensional Arrays
Covnerts a 1D array to a readable string:
System.out.println(Arrays.toString(sampleArray));
Arrays.deepToString() for Multi-Dimensional Arrays
Converts nested arrays to a readable string:
System.out.println(Arrays.deepToString(twoDGrid));
Important Notes
- Local array variables in Java have default initial values:
intarrays: default to 0chararrays: default to\u0000(null character)Stringarrays: default tonulldouble/floatarrays: default to 0.0booleanarrays: default tofalse
- Unlike C++, local variables in Java are initialized to default values, not random garbage
- Java arrays cannot be resized after creation
- You must import
java.util.Arraysto use the array utility methods - Array references can be reassigned to new array instances:
int[] original = {1,2,3}; original = new int[5]; // Reassigns to a new 5-element array
Classes and Objects in Java
Java is an object-oriented programming language. The String type is a built-in class. Declarations like String str1, str2 create references to instances of the String class.
- The class name must match the filename of the Java file
- A package declaration acts as a directory path for your code files
- Always write package declarations first, followed by import statements, then class definitions
- Class names should start with an uppercase letter
Object-oriented programming focuses on using existing components to perform tasks:
- A class is a blueprint describing common properties and behaviors of a group of objects
- An object is a concrete instance of a class, with actual stored data and functionality
- Define member variables (properties) first, then assign values when creating objects
Common examples:
- Member properties (nouns): phone brand, price, color
- Member methods (verbs): makeCall, sendMessage, playGame
Useful IDE shortcut: CTRL+D duplicates the current line
It is recommended to only define one public class per Java file.
The standard format for member variables is: accessModifier dataType variableName = initialValue;
Initial values are often omitted, letting the JVM assign default values. Use "property" for nouns and "behavior" for verbs when describing class members.
Encapsulation
Encapsulation means letting objects handle their own internal operations:
- A person draws a circle: the circle object handles its own drawing
- A person closes a door: the door object handles its own closing logic
- If someone harms another individual, the harm is handled by the affected individual
private Access Modifier
The private keyword restricts direct access to class members, allowing only controlled assignment and retrieval to ensure data validity.
- Variables defined inside a method are local variables
- Variables defined inside a class but outside any method are member variables
this Keyword
The this keyword distinguishes between member variables and local variables with the same name. By default, Java uses the nearest variable (local variable) when names overlap. Using this.variableName references the member variable instead. If no name overlap exists, you can omit this entirely.
package ThisDemo;
public class Girlfriend {
private int age; // Member variable, defaults to 0
public void showAge() {
int age = 10; // Local variable
System.out.println(age); // Prints 10, using local variable
System.out.println(this.age); // Prints 0, using member variable
}
}
package ThisDemo;
public class GirlfriendTest {
public static void main(String[] args) {
Girlfriend myGf = new Girlfriend();
myGf.showAge();
}
}
Tree Algorithm Practice (LeetCode 1498: Deepest Root)
To validate if a given graph is a tree, use a Union-Find data structure to check if there is exactly one connected component. Enumerate each node as a potential root, run DFS/BFS to calculate the maximum depth, then collect all nodes with the maximum depth. Note that edges are undirected, so add both directions when building the adjacency list.
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int MAX_NODES = 10010;
const int MAX_EDGES = MAX_NODES * 2;
int n;
int head[MAX_NODES], edge[MAX_EDGES], nextEdge[MAX_EDGES], edgeIdx;
int parent[MAX_NODES];
int find(int x) {
if (parent[x] != x) {
parent[x] = find(parent[x]);
}
return parent[x];
}
void addEdge(int a, int b) {
edge[edgeIdx] = b;
nextEdge[edgeIdx] = head[a];
head[a] = edgeIdx++;
}
int dfs(int current, int father) {
int maxDepth = 0;
for (int i = head[current]; ~i; i = nextEdge[i]) {
int neighbor = edge[i];
if (neighbor == father) continue;
maxDepth = max(maxDepth, dfs(neighbor, current) + 1);
}
return maxDepth;
}
int main() {
cin >> n;
memset(head, -1, sizeof(head));
for (int i = 1; i <= n; i++) {
parent[i] = i;
}
int connectedComponents = n;
for (int i = 0; i < n - 1; i++) {
int a, b;
cin >> a >> b;
if (find(a) != find(b)) {
connectedComponents--;
parent[find(a)] = find(b);
}
addEdge(a, b);
addEdge(b, a);
}
if (connectedComponents > 1) {
printf("Error: %d components\n", connectedComponents);
} else {
vector<int> candidateRoots;
int maxDepth = -1;
for (int i = 1; i <= n; i++) {
int currentDepth = dfs(i, -1);
if (currentDepth > maxDepth) {
maxDepth = currentDepth;
candidateRoots.clear();
candidateRoots.push_back(i);
} else if (currentDepth == maxDepth) {
candidateRoots.push_back(i);
}
}
for (int root : candidateRoots) {
cout << root << endl;
}
}
return 0;
}