Lecture from: 11.10.2024 | Video: Videos ETHZ

Sequences

Sequences are ordered collections of data elements, where each element can be accessed by its index. Java provides various sequence types, each with its own strengths and characteristics.

Strings

Strings in Java represent sequences of characters and behave as objects rather than arrays. While they appear similar to arrays, their immutability sets them apart. Once a string is created, its contents cannot be changed directly. Any manipulation results in the creation of a new string object.

Key Features

  • Immutability: Strings are immutable; attempting to modify a string creates a new one. This characteristic contributes to Java’s safety and predictability.
  • Object-Oriented Nature: Strings are objects, inheriting properties and behaviors from the Object class. They can be passed as arguments to methods, stored in variables of type String, and manipulated using object-oriented techniques.

Methods for String Manipulation

Java’s standard library offers a rich set of methods for working with strings. Some common examples include:

  • substring(int start, int end): Returns a new string containing the characters from the specified start index (inclusive) to the end index (exclusive).
  • toLowerCase() and toUpperCase(): Convert the entire string to lowercase or uppercase respectively, returning a new string.
  • strip(), stripLeading(), stripTrailing(): Remove leading, trailing, or both whitespace characters from the string, returning a new string.

Length of a String

The length() method returns an integer representing the number of characters in a string.

String message = "Hello, world!";
int length = message.length(); // length will be 13

Characters and Indices:

Strings are zero-indexed, meaning the first character has an index of 0. The charAt(int index) method retrieves the character at a specific index.

char firstLetter = message.charAt(0); // firstLetter will be 'H'

Counting characters

Common String Methods Returning Strings

substring(n, n+1) vs charAt(n)

Lets look at the difference between substring(0, 1) and charAt(0). While both methods aim to extract the first character of a string, they do so in distinct ways.

charAt(0) directly returns the character at index 0 as a primitive char data type. Think of it as grabbing a single building block from the string.

On the other hand, substring(0, 1) constructs a new String object containing that single character. It essentially creates a mini-string encompassing just the first character. This might seem minor, but remember that strings in Java are immutable – once created, they cannot be changed directly. Using substring leads to the creation of a new object in memory, whereas charAt simply provides a reference to the original string’s character at the specified index.

String methods, returning int

String methods returning boolean

Arrays

Arrays are fundamental data structures providing contiguous storage for elements of the same type. They offer efficient access to individual elements via their index, allowing for fast traversal and manipulation of data.

Declaration

In Java, array declaration establishes its structure but doesn’t allocate memory for elements until initialization. The syntax is concise:

dataType[] arrayName;
  • dataType: Specifies the type of each element within the array (e.g., int, String, double). Ensuring data homogeneity is crucial for type safety and efficient operations.

Example Declarations:

int[] integers = new int[10]; // Declares an array of 10 integers named 'integers'
String[] names = new String[5]; // Declares an array of 5 Strings named 'names'
double[] prices = {29.99, 49.95, 19.90}; // Declaration and initialization simultaneously
 
  • Size: The size of an array is fixed at declaration (e.g., int[] numbers = new int[10];). This contrasts with dynamic data structures like ArrayLists which can resize as needed.
  • Initialization: While we declare the structure, we don’t automatically assign values to elements during declaration. We must explicitly initialize them using assignment statements or constructor expressions.

When working with arrays, it’s crucial to remember that each element has a specific index within its bounds. Accessing an array element outside these legal indices leads to ArrayIndexOutOfBoundsExceptions, halting your program abruptly.

Data Passing

While many data types in Java are passed by value (a copy is made), arrays behave differently.

In this swap function you’ll see that swap1 will only swap the variables within it’s scope and not in the parent scope. However swap2 is able to swap since data is passed by reference and not by value.

See: Reference Semantics Sharing the Address for more info.

Null Pointers

In Java, null signifies the absence of an object reference. Imagine it as an empty pointer – it doesn’t point to anything in memory.

Why Does This Matter?

  • You cannot directly access or manipulate data through a null reference. Attempting to do so triggers a NullPointerException (NPE) – a runtime error halting your program abruptly.
Unreachable Objects and Garbage Collection

Objects in Java are allocated memory when created. They become “unreachable” if there are no longer any references pointing to them.

The garbage collector, a background process in Java, periodically identifies unreachable objects and reclaims their memory for reuse. This helps prevent memory leaks – situations where your program hoards unused memory over time.

Continue here: 08 Array Operations, Recursion