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

Anni HuangAnni Huang
7 min read

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

Operationint[]ArrayListInteger[]
Access by indexO(1) - FastestO(1) - GoodO(1) - Good
Memory usageMinimalHigher (object overhead)Moderate
IterationFastestGoodGood
Insertion/DeletionN/A (fixed size)O(n) averageN/A (fixed size)
Boxing/UnboxingNoneRequiredRequired

Methods and Features Summary

Feature/Methodint[]ArrayListInteger[]
Size Operations
Get sizearray.lengthlist.size()array.length
Fixed size✅ Yes❌ No✅ Yes
Dynamic resize❌ No✅ Yes❌ No
Access Operations
Get elementarray[index]list.get(index)array[index]
Set elementarray[index] = valuelist.set(index, value)array[index] = value
Modification Operations
Add element❌ N/Alist.add(value)❌ N/A
Insert at index❌ N/Alist.add(index, value)❌ N/A
Remove by index❌ N/Alist.remove(index)❌ N/A
Remove by value❌ N/Alist.remove(Object)❌ N/A
Clear all❌ N/Alist.clear()❌ N/A
Search Operations
Contains checkManual looplist.contains(value)Manual loop
Find indexManual looplist.indexOf(value)Manual loop
Last indexManual looplist.lastIndexOf(value)Manual loop
Utility Operations
Copy/CloneArrays.copyOf()new ArrayList<>(list)Arrays.copyOf()
SortArrays.sort()Collections.sort()Arrays.sort()
Fill with valueArrays.fill()Manual loopArrays.fill()
Convert to arrayAlready arraylist.toArray()Already array
Iteration Support
For-each loop✅ Yes✅ Yes✅ Yes
Iterator❌ No✅ Yes❌ No
ListIterator❌ No✅ Yes❌ No
Stream supportArrays.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 overheadMinimalHigherModerate
Access speedFastestGoodGood
Boxing/UnboxingNoneRequiredRequired

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.

0
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’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.