In programming, it's common to work with collections of related data. An array is one of the most basic and useful data structures for storing multiple values of the same type in a single, organized place.
In this section, we’ll introduce one-dimensional arrays and then extend to multidimensional arrays, especially two-dimensional arrays. You’ll learn how to declare, create, and access elements, along with examples of looping through arrays and a simple exercise to reinforce these concepts.
An array is a fixed-size collection of elements, all of the same type. Once created, the size of the array cannot change.
Think of an array as a row of numbered boxes where you can store values. Each box is called an element, and its position is called an index.
To declare a one-dimensional array, you specify the type and use square brackets:
int[] numbers;
This creates a variable numbers
that can hold an array of integers but doesn’t create the array yet.
You create the actual array with the new
keyword and specify its size:
numbers = new int[5]; // An array that holds 5 integers
You can also combine declaration and instantiation:
int[] numbers = new int[5];
You can assign values to array elements using their index, which starts at 0:
numbers[0] = 10;
numbers[1] = 20;
numbers[2] = 30;
To access or print elements:
System.out.println(numbers[0]); // Prints 10
int[] numbers = {5, 10, 15, 20, 25}; // Initialize with values
for (int i = 0; i < numbers.length; i++) {
System.out.println("Element at index " + i + " is " + numbers[i]);
}
Output:
Element at index 0 is 5
Element at index 1 is 10
Element at index 2 is 15
Element at index 3 is 20
Element at index 4 is 25
A two-dimensional array can be thought of as a grid or table — rows and columns of elements.
int[][] matrix; // Declaration of a 2D integer array
matrix = new int[3][4]; // 3 rows, 4 columns
You can also combine these:
int[][] matrix = new int[3][4];
You use two indices — one for the row and one for the column:
matrix[0][0] = 1; // First row, first column
matrix[2][3] = 10; // Third row, fourth column
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix[row].length; col++) {
System.out.print(matrix[row][col] + " ");
}
System.out.println();
}
Output:
1 2 3
4 5 6
7 8 9
public class Test {
public static void main(String[] args) {
int[][] matrix = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
for (int row = 0; row < matrix.length; row++) {
for (int col = 0; col < matrix[row].length; col++) {
System.out.print(matrix[row][col] + " ");
}
System.out.println();
}
}
}
Try this small task:
Example code snippet:
int[] values = {3, 7, 2, 9, 4};
int sum = 0;
for (int i = 0; i < values.length; i++) {
sum += values[i];
}
System.out.println("Sum of elements: " + sum);
Expected output:
Sum of elements: 25
Try printing a 5x5 grid of stars (*
) using nested loops:
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
System.out.print("* ");
}
System.out.println();
}
Output:
* * * * *
* * * * *
* * * * *
* * * * *
* * * * *
arr[index]
or matrix[row][col]
).for
loops) are essential to process arrays efficiently.Mastering arrays is crucial since they form the foundation for more advanced data structures and algorithms in Java.
Arrays are fundamental in programming, but just storing data isn’t enough — you need to process it efficiently. This section walks you through some essential array algorithms: finding the maximum/minimum values, reversing arrays, searching (linear and binary), and sorting (selection or bubble sort). Along the way, you’ll see how to think about algorithms and their efficiency, and then get a challenge to practice!
To find the maximum or minimum in an array, you typically scan through all elements, updating your current max or min as you go.
public static int findMax(int[] arr) {
int max = arr[0]; // Assume first element is max initially
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i]; // Update max if current element is bigger
}
}
return max;
}
Similarly, for minimum, change the comparison to arr[i] < min
.
Reversing means swapping elements from the start and end moving toward the center.
public static void reverse(int[] arr) {
int left = 0;
int right = arr.length - 1;
while (left < right) {
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
}
A simple search algorithm that checks each element until it finds the target or reaches the end.
public static int linearSearch(int[] arr, int target) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == target) {
return i; // Return index if found
}
}
return -1; // Not found
}
Efficiency: Runs in O(n) time, checking each element once.
Used on sorted arrays, binary search cuts the search space in half each time.
public static int binarySearch(int[] arr, int target) {
int left = 0;
int right = arr.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1; // Not found
}
Efficiency: Runs in O(log n) time — much faster than linear search for large arrays.
Sorting organizes elements in ascending (or descending) order. Two simple sorting algorithms are selection sort and bubble sort.
Finds the smallest element and swaps it with the first unsorted element, then repeats.
public static void selectionSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
// Swap
int temp = arr[minIndex];
arr[minIndex] = arr[i];
arr[i] = temp;
}
}
Repeatedly swaps adjacent elements if they are in the wrong order, "bubbling" the largest element to the end.
public static void bubbleSort(int[] arr) {
boolean swapped;
for (int i = 0; i < arr.length - 1; i++) {
swapped = false;
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
// Swap
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swapped = true;
}
}
// If no swaps, array is sorted
if (!swapped) break;
}
}
public class ArrayAlgorithms {
public static int findMax(int[] arr) {
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
public static int findMin(int[] arr) {
int min = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] < min) {
min = arr[i];
}
}
return min;
}
public static void reverse(int[] arr) {
int left = 0, right = arr.length - 1;
while (left < right) {
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
left++;
right--;
}
}
public static int linearSearch(int[] arr, int target) {
for (int i = 0; i < arr.length; i++) {
if (arr[i] == target) return i;
}
return -1;
}
public static int binarySearch(int[] arr, int target) {
int left = 0, right = arr.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) return mid;
else if (arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1;
}
public static void selectionSort(int[] arr) {
for (int i = 0; i < arr.length - 1; i++) {
int minIndex = i;
for (int j = i + 1; j < arr.length; j++) {
if (arr[j] < arr[minIndex]) {
minIndex = j;
}
}
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
public static void bubbleSort(int[] arr) {
boolean swapped;
for (int i = 0; i < arr.length - 1; i++) {
swapped = false;
for (int j = 0; j < arr.length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
swapped = true;
}
}
if (!swapped) break;
}
}
public static void printArray(int[] arr) {
for (int val : arr) {
System.out.print(val + " ");
}
System.out.println();
}
public static void main(String[] args) {
int[] array = {34, 7, 23, 32, 5, 62};
System.out.println("Original array:");
printArray(array);
System.out.println("Maximum: " + findMax(array));
System.out.println("Minimum: " + findMin(array));
System.out.println("Reversed array:");
reverse(array);
printArray(array);
int searchVal = 23;
System.out.println("Linear search for " + searchVal + ": " + linearSearch(array, searchVal));
selectionSort(array);
System.out.println("Selection sorted:");
printArray(array);
System.out.println("Binary search for " + searchVal + ": " + binarySearch(array, searchVal));
int[] array2 = {12, 3, 45, 2, 18};
bubbleSort(array2);
System.out.println("Bubble sorted another array:");
printArray(array2);
}
}
Try this on your own:
filterEvenNumbers(int[] arr)
that returns a new array containing only the even numbers from the input array.Mastering these fundamental algorithms will give you a strong foundation to understand more complex data structures and algorithms later.
Strings are one of the most common data types you’ll use in Java. They allow you to store and manipulate text, from simple words to entire sentences. In this section, we’ll explore how strings work in Java, why they are immutable, and how the StringBuilder class offers an efficient way to modify text.
In Java, a String is an object that represents a sequence of characters, such as "Hello, world!"
. Java stores strings in a special memory area called the string pool. When you create a string literal, Java checks the pool first to reuse existing strings, improving performance and memory usage.
Strings in Java are immutable, meaning once created, they cannot be changed. Any operation that seems to modify a string actually creates a new string object.
Example:
String s = "Hello";
s = s + " World"; // Creates a new string "Hello World"
The original "Hello"
string remains unchanged, and s
now points to the new string.
Here are some useful methods to work with strings:
.length()
Returns the number of characters in the string.
String text = "Java";
System.out.println(text.length()); // Output: 4
.charAt(int index)
Returns the character at the specified position (index starts at 0).
char c = text.charAt(1);
System.out.println(c); // Output: 'a'
.substring(int beginIndex, int endIndex)
Returns a substring from beginIndex
up to (but not including) endIndex
.
String sub = text.substring(1, 3);
System.out.println(sub); // Output: "av"
.indexOf(String str)
Returns the index of the first occurrence of the specified substring, or -1 if not found.
int pos = text.indexOf("va");
System.out.println(pos); // Output: 1
Using the +
operator to join strings is easy but can be inefficient if done repeatedly inside loops because it creates many temporary String objects.
StringBuilder
is a class designed to create and modify strings efficiently. Unlike String
, a StringBuilder
object is mutable, so you can append, insert, or delete characters without creating new objects each time.
StringBuilder sb = new StringBuilder("Hello");
sb.append(" World");
System.out.println(sb.toString()); // Output: Hello World
You can chain calls:
sb.append("!").append(" How are you?");
.append(String str)
– Adds text to the end..insert(int offset, String str)
– Inserts text at a specific position..replace(int start, int end, String str)
– Replaces a part of the string..delete(int start, int end)
– Deletes characters in a range..toString()
– Converts back to a regular String
.public class StringBuilderDemo {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder("Java");
sb.append(" is");
sb.append(" fun");
sb.insert(9, " really");
sb.replace(0, 4, "Programming");
System.out.println(sb.toString());
}
}
Output:
Programming is really fun
Feature | String | StringBuilder |
---|---|---|
Mutability | Immutable | Mutable |
Modification | Creates new object on change | Modifies same object |
Performance (repeated concatenation) | Slow (due to object creation) | Fast (efficient in loops) |
Thread safety | Thread-safe (immutable) | Not thread-safe |
Common use cases | Fixed or rarely changed text | Building/modifying text dynamically |
String
methods like .length()
, .charAt()
, .substring()
, and .indexOf()
help you inspect and extract parts of text.+
for string concatenation creates many objects and can hurt performance in loops.StringBuilder
is a mutable alternative, allowing efficient text building and modifications without creating new objects repeatedly.String
for fixed text, and StringBuilder
when you need to build or modify strings dynamically.Try experimenting with String
and StringBuilder
in your own programs to see how they behave differently and to improve the performance of your text-processing code.
Working with strings often requires comparing their content and manipulating their text. Java provides several ways to compare strings and methods to perform common string transformations. This section explains the differences between these approaches and shows practical examples.
.equals()
, .equalsIgnoreCase()
, and ==
.equals()
Comparing ContentThe .equals()
method compares the actual content of two strings:
String a = "Java";
String b = new String("Java");
System.out.println(a.equals(b)); // true, because content is the same
.equalsIgnoreCase()
Case-Insensitive ComparisonIf you need to compare strings ignoring uppercase or lowercase differences, use .equalsIgnoreCase()
:
String a = "Java";
String b = "java";
System.out.println(a.equalsIgnoreCase(b)); // true
==
Comparing References (Memory Locations)Using ==
checks if two variables point to the exact same object in memory, not if their contents match:
String a = "Java";
String b = new String("Java");
System.out.println(a == b); // false, different objects
Pitfall: Since many strings can have the same content but be different objects, ==
can give unexpected results when comparing strings.
.trim()
Removes leading and trailing spaces from a string.
String input = " Hello World ";
System.out.println("[" + input.trim() + "]"); // Output: [Hello World]
.split()
Splits a string into parts based on a delimiter, returning an array.
String csv = "apple,banana,orange";
String[] fruits = csv.split(",");
for (String fruit : fruits) {
System.out.println(fruit);
}
Output:
apple
banana
orange
.replace()
Replaces occurrences of a target substring with another string.
String text = "I like cats";
String newText = text.replace("cats", "dogs");
System.out.println(newText); // Output: I like dogs
A palindrome reads the same forwards and backwards, like "madam"
.
public static boolean isPalindrome(String str) {
str = str.toLowerCase().replaceAll("\\s+", ""); // Normalize: lowercase, remove spaces
int left = 0;
int right = str.length() - 1;
while (left < right) {
if (str.charAt(left) != str.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}
Example usage:
System.out.println(isPalindrome("Race car")); // true
System.out.println(isPalindrome("Hello")); // false
public class PalindromeChecker {
public static boolean isPalindrome(String str) {
str = str.toLowerCase().replaceAll("\\s+", ""); // Normalize: lowercase, remove spaces
int left = 0;
int right = str.length() - 1;
while (left < right) {
if (str.charAt(left) != str.charAt(right)) {
return false;
}
left++;
right--;
}
return true;
}
public static void main(String[] args) {
System.out.println(isPalindrome("Race car")); // true
System.out.println(isPalindrome("Hello")); // false
System.out.println(isPalindrome("A Santa at NASA")); // true
}
}
.equals()
to compare string content..equalsIgnoreCase()
for case-insensitive comparisons.==
for strings unless you want to check if both variables refer to the exact same object..trim()
, .split()
, and .replace()
.By understanding how to correctly compare and manipulate strings, you’ll avoid bugs and write cleaner, more effective Java programs.