Java Array Types Comparison: int[], ArrayList<>, and Array<>
![Java Array Types Comparison: int[], ArrayList<>, and Array<>](https://cdn.hashnode.com/res/hashnode/image/upload/v1751862331251/12d044a8-58c3-43e2-b8c3-a10f50cdf612.png)
I’m Anni Huang, an AI researcher-in-training currently at ByteDance, specializing in LLM training operations with a coding focus. I bridge the gap between engineering execution and model performance, ensuring the quality, reliability, and timely delivery of large-scale training projects.
Java Array Types Comparison: int[], ArrayList<>, and Array<>
Overview
Java provides different ways to work with collections of data. This document compares three approaches: primitive arrays (int[]), the ArrayList<> class, and generic arrays (Array<>).
Performance Comparison
| Operation | int[] | ArrayList | Integer[] |
| Access by index | O(1) - Fastest | O(1) - Good | O(1) - Good |
| Memory usage | Minimal | Higher (object overhead) | Moderate |
| Iteration | Fastest | Good | Good |
| Insertion/Deletion | N/A (fixed size) | O(n) average | N/A (fixed size) |
| Boxing/Unboxing | None | Required | Required |
Methods and Features Summary
| Feature/Method | int[] | ArrayList | Integer[] |
| Size Operations | |||
| Get size | array.length | list.size() | array.length |
| Fixed size | ✅ Yes | ❌ No | ✅ Yes |
| Dynamic resize | ❌ No | ✅ Yes | ❌ No |
| Access Operations | |||
| Get element | array[index] | list.get(index) | array[index] |
| Set element | array[index] = value | list.set(index, value) | array[index] = value |
| Modification Operations | |||
| Add element | ❌ N/A | list.add(value) | ❌ N/A |
| Insert at index | ❌ N/A | list.add(index, value) | ❌ N/A |
| Remove by index | ❌ N/A | list.remove(index) | ❌ N/A |
| Remove by value | ❌ N/A | list.remove(Object) | ❌ N/A |
| Clear all | ❌ N/A | list.clear() | ❌ N/A |
| Search Operations | |||
| Contains check | Manual loop | list.contains(value) | Manual loop |
| Find index | Manual loop | list.indexOf(value) | Manual loop |
| Last index | Manual loop | list.lastIndexOf(value) | Manual loop |
| Utility Operations | |||
| Copy/Clone | Arrays.copyOf() | new ArrayList<>(list) | Arrays.copyOf() |
| Sort | Arrays.sort() | Collections.sort() | Arrays.sort() |
| Fill with value | Arrays.fill() | Manual loop | Arrays.fill() |
| Convert to array | Already array | list.toArray() | Already array |
| Iteration Support | |||
| For-each loop | ✅ Yes | ✅ Yes | ✅ Yes |
| Iterator | ❌ No | ✅ Yes | ❌ No |
| ListIterator | ❌ No | ✅ Yes | ❌ No |
| Stream support | Arrays.stream() | list.stream() | Arrays.stream() |
| Other Features | |||
| Null values | ❌ No | ✅ Yes | ✅ Yes |
| Generics | ❌ No | ✅ Yes | ✅ Yes |
| Thread safety | ✅ Yes (immutable size) | ❌ No | ✅ Yes (immutable size) |
| Collections framework | ❌ No | ✅ Yes | ❌ No |
| Performance | |||
| Memory overhead | Minimal | Higher | Moderate |
| Access speed | Fastest | Good | Good |
| Boxing/Unboxing | None | Required | Required |
int[] - Primitive Array
Characteristics
- Type: Primitive array of integers
- Memory: Stored in contiguous memory locations
- Size: Fixed size, determined at creation time
- Performance: Fastest access and iteration
- Null values: Cannot store null (primitives only)
Syntax
// Declaration and initialization
int[] numbers = new int[5]; // Creates array of size 5
int[] values = {1, 2, 3, 4, 5}; // Initialize with values
int[] data = new int[]{10, 20, 30}; // Alternative initialization
// Access
int value = numbers[0]; // Get element
numbers[1] = 42; // Set element
int length = numbers.length; // Get size
Advantages
- Minimal memory overhead
- Fastest performance for access and iteration
- Direct memory access
- No boxing/unboxing overhead
Disadvantages
- Fixed size - cannot grow or shrink
- No built-in methods for common operations
- Manual bounds checking required
- Cannot use generic collection utilities
ArrayList<> - Dynamic Array
Characteristics
- Type: Generic collection class
- Memory: Backed by a resizable array
- Size: Dynamic - can grow and shrink
- Performance: Good performance with some overhead
- Null values: Can store null values
Syntax
// Declaration and initialization
ArrayList<Integer> numbers = new ArrayList<>();
ArrayList<Integer> values = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
ArrayList<Integer> data = new ArrayList<>(10); // Initial capacity
// Access and modification
numbers.add(42); // Add element
numbers.add(0, 10); // Insert at index
Integer value = numbers.get(0); // Get element
numbers.set(1, 100); // Set element
numbers.remove(0); // Remove by index
numbers.remove(Integer.valueOf(42)); // Remove by value
int size = numbers.size(); // Get size
Advantages
- Dynamic sizing - automatically grows/shrinks
- Rich API with many utility methods
- Type safety with generics
- Integrates with Java Collections Framework
- Supports enhanced for-loops and streams
Disadvantages
- Boxing/unboxing overhead for primitives
- Higher memory usage (object overhead)
- Slightly slower than primitive arrays
- Not thread-safe (use Collections.synchronizedList() or Vector)
Array<> - Generic Array (Note: Not a Standard Java Type)
Important Note
Array<> is not a standard Java type. Java doesn't support generic arrays in the traditional sense due to type erasure. However, there are several interpretations:
Possible Interpretations
1. Generic Array Creation (Problematic)
// This WON'T compile - Java doesn't allow generic array creation
// T[] array = new T[10]; // Compilation error
// Common workaround
@SuppressWarnings("unchecked")
T[] array = (T[]) new Object[10];
2. Object Arrays
// Object array - can hold any type
Object[] objects = new Object[5];
objects[0] = "String";
objects[1] = 42;
objects[2] = new ArrayList<>();
// Requires casting when retrieving
String str = (String) objects[0];
3. Wrapper Class Arrays
// Array of Integer objects (not primitives)
Integer[] numbers = new Integer[5];
numbers[0] = 42; // Autoboxing
Integer value = numbers[0]; // No casting needed
Use Case Recommendations
Use int[] when:
- Working with large datasets where performance is critical
- Size is known and fixed
- Memory usage must be minimized
- Doing intensive mathematical computations
Use ArrayList when:
- Size varies during runtime
- Need rich collection operations (add, remove, search)
- Using Java Collections Framework features
- Code readability and maintainability are priorities
- Working with smaller datasets where performance difference is negligible
Use Integer[] when:
- Need array semantics but want to store null values
- Interfacing with APIs that expect Object arrays
- Need array behavior with wrapper types
Code Examples
Performance Test Example
public class ArrayPerformanceTest {
public static void main(String[] args) {
int size = 1_000_000;
// Primitive array test
long start = System.nanoTime();
int[] primitiveArray = new int[size];
for (int i = 0; i < size; i++) {
primitiveArray[i] = i;
}
long primitiveTime = System.nanoTime() - start;
// ArrayList test
start = System.nanoTime();
ArrayList<Integer> arrayList = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
arrayList.add(i);
}
long arrayListTime = System.nanoTime() - start;
System.out.println("Primitive array: " + primitiveTime / 1_000_000 + " ms");
System.out.println("ArrayList: " + arrayListTime / 1_000_000 + " ms");
}
}
Conversion Between Types
// int[] to ArrayList<Integer>
int[] primitiveArray = {1, 2, 3, 4, 5};
ArrayList<Integer> arrayList = new ArrayList<>();
for (int value : primitiveArray) {
arrayList.add(value);
}
// Or using streams (Java 8+)
ArrayList<Integer> arrayList2 = Arrays.stream(primitiveArray)
.boxed()
.collect(Collectors.toCollection(ArrayList::new));
// ArrayList<Integer> to int[]
ArrayList<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
int[] array = list.stream().mapToInt(Integer::intValue).toArray();
Common Method Examples
int[] Methods
int[] arr = {1, 2, 3, 4, 5};
int length = arr.length; // Get size
int value = arr[0]; // Access
arr[1] = 10; // Modify
Arrays.sort(arr); // Sort
Arrays.fill(arr, 0); // Fill
int[] copy = Arrays.copyOf(arr, arr.length); // Copy
ArrayList Methods
ArrayList<Integer> list = new ArrayList<>();
list.add(10); // Add
list.add(0, 5); // Insert
list.set(1, 20); // Set
Integer value = list.get(0); // Get
list.remove(0); // Remove by index
list.remove(Integer.valueOf(20)); // Remove by value
boolean contains = list.contains(10); // Search
int index = list.indexOf(10); // Find index
Collections.sort(list); // Sort
list.clear(); // Clear all
Integer[] Methods
Integer[] arr = {1, 2, 3, 4, 5};
int length = arr.length; // Get size
Integer value = arr[0]; // Access
arr[1] = 10; // Modify
arr[2] = null; // Can store null
Arrays.sort(arr); // Sort
Arrays.fill(arr, 0); // Fill
Integer[] copy = Arrays.copyOf(arr, arr.length); // Copy
Summary
Choose your array type based on your specific needs:
- int[] for maximum performance and minimal memory usage
- ArrayList for flexibility and rich functionality
- Integer[] for specific use cases requiring null values or object arrays
The choice depends on your priorities: performance vs. flexibility, memory usage vs. convenience, and the specific requirements of your application.




