Unit Testing

Approach in test-driven development, characterized by writing tests before writing implementations, where the functionality of a single “unit” (typically a standalone method) of code is tested.

import static com.google.common.truth.Truth.assertThat;
import org.junit.jupiter.api.Test;

@Test
public void test() {
		T actual = ...;
		T expected = ...;
		assertThat(actual).isEqualTo(expected);
}

The @Test annotation has no syntactic meaning and serves as a marker for which a routine in Java’s reflections library will iterate through all methods with this annotation and run them.


ArrayList

One of 2 implementations of the List ADT shown in this class. Linked lists are slow when retrieving items from long lists, ArrayLists work around this by using a “backing” array, which stores its items and allows for $O(1)$ retrieval (for sufficiently small arrays).

image.png

General Structure

An ArrayList is instantiated with an items array of some arbitrary initial size. To make adding a constant time operation, we store nextFirst and nextLast pointers, which point to the indices in items where the next first or last item, respectively, would go. This requires a circular topology, with these indices “wrapping around” the array to avoid out of bounds errors.

Resizing

Whenever the backing array items gets too big or too small, we need to resize it. This is done by defining a usage ratio, which is the number of elements in items divided by its total length. Whenever this ratio is less than 0.25, we half the total length of items, and whenever it is 1.0, we multiply the total length by a resizing factor, usually 2.

public void resize(capacity) {
		// ...
}

Interfaces

Dictate what any implementations do without specifying how they do it.

public interface A {
		public void method1(...);
		public void method2(...);
		// ...
}
public class A_implementation implements A {
		@Override
		public void method1(...) {
				// implementation
		}
		
		@Override
		public void method2(...) {
				// implementation
		}
}