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 am Anni HUANG, a software engineer with 3 years of experience in IDE development and Chatbot.