Java Array Types Comparison: int[], ArrayList<>, and Array<>


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.
Subscribe to my newsletter
Read articles from Anni Huang directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Anni Huang
Anni Huang
I am Anni HUANG, a software engineer with 3 years of experience in IDE development and Chatbot.