杰瑞科技汇

Java ArrayList和普通数组有何区别?

Of course! Let's dive deep into ArrayList in Java, from the basics to more advanced topics.

What is an ArrayList?

An ArrayList is a part of Java's Collection Framework. It's a resizable array, meaning it can grow or shrink in size dynamically. Unlike a standard array in Java (e.g., int[]), which has a fixed length once created, an ArrayList provides flexibility by allowing you to add or remove elements as needed.

Think of it like a shopping list. You can start with a few items, and as you think of more, you can add them to the list. If you cross an item off, the list gets shorter. You don't need to buy a whole new notepad just to add one more item.


Key Characteristics of ArrayList

  1. Resizable: Its size can be changed dynamically.
  2. Ordered: Elements are stored in the order they are added (insertion order).
  3. Allows Duplicates: You can add the same element multiple times.
  4. Index-Based: You can access elements using their numerical index (like a regular array), starting from 0.
  5. Not Synchronized: It is not thread-safe. If multiple threads try to modify an ArrayList simultaneously, it can lead to data inconsistency. For thread-safe operations, you should use Vector or CopyOnWriteArrayList.

How to Use an ArrayList

Here's a step-by-step guide with code examples.

Import the Class

First, you need to import the ArrayList class from the java.util package.

import java.util.ArrayList;

Declare and Initialize

You can declare and initialize an ArrayList in one line. It's a good practice to specify the type of data it will hold using Generics (e.g., <String>, <Integer>).

// Create an ArrayList of Strings
ArrayList<String> names = new ArrayList<>();
// Create an ArrayList of Integers
// Note: Use Integer, not int, for wrapper types in collections
ArrayList<Integer> numbers = new ArrayList<>();
// You can also provide an initial capacity
ArrayList<String> initialCapacityList = new ArrayList<>(20);

Common Methods

Here are the most frequently used methods with examples.

import java.util.ArrayList;
public class ArrayListExample {
    public static void main(String[] args) {
        // 1. Create an ArrayList
        ArrayList<String> fruits = new ArrayList<>();
        // 2. Add elements
        fruits.add("Apple");
        fruits.add("Banana");
        fruits.add("Orange");
        System.out.println("Initial list: " + fruits); // [Apple, Banana, Orange]
        // 3. Add an element at a specific index
        fruits.add(1, "Mango");
        System.out.println("After adding Mango at index 1: " + fruits); // [Apple, Mango, Banana, Orange]
        // 4. Get an element by index
        String fruit = fruits.get(1);
        System.out.println("Fruit at index 1: " + fruit); // Mango
        // 5. Set (replace) an element at a specific index
        fruits.set(2, "Grape");
        System.out.println("After replacing index 2 with Grape: " + fruits); // [Apple, Mango, Grape, Orange]
        // 6. Get the size of the ArrayList
        int size = fruits.size();
        System.out.println("Size of the list: " + size); // 4
        // 7. Check if an element exists
        boolean hasApple = fruits.contains("Apple");
        System.out.println("Does the list contain Apple? " + hasApple); // true
        // 8. Find the index of an element
        int indexOfMango = fruits.indexOf("Mango");
        System.out.println("Index of Mango: " + indexOfMango); // 1
        // 9. Remove an element by value
        fruits.remove("Orange");
        System.out.println("After removing Orange: " + fruits); // [Apple, Mango, Grape]
        // 10. Remove an element by index
        fruits.remove(0); // Removes "Apple"
        System.out.println("After removing index 0: " + fruits); // [Mango, Grape]
        // 11. Loop through the ArrayList
        System.out.println("\n--- Iterating with a for-each loop ---");
        for (String f : fruits) {
            System.out.println(f);
        }
        System.out.println("\n--- Iterating with a traditional for loop ---");
        for (int i = 0; i < fruits.size(); i++) {
            System.out.println(fruits.get(i));
        }
        // 12. Clear the entire ArrayList
        fruits.clear();
        System.out.println("\nAfter clearing the list: " + fruits); // []
        System.out.println("Is the list empty? " + fruits.isEmpty()); // true
    }
}

ArrayList vs. Standard Array ([])

This is a crucial point for understanding when to use which.

Feature ArrayList Standard Array (String[])
Size Dynamic. Can grow and shrink. Fixed. Size must be defined at creation.
Performance Slightly slower due to resizing overhead. Faster for direct element access.
Methods Rich set of built-in methods (add, remove, etc.). Very few methods (only length property).
Data Types Must use wrapper classes (Integer, Double) for primitives. Can use primitive types (int, double) directly.
Flexibility High. Easy to add/remove elements anywhere. Low. Adding/removing elements requires creating a new array.

Performance and Time Complexity

Understanding the performance characteristics is key to using ArrayList effectively.

  • add(element): O(1) amortized. Adding an element to the end is very fast. However, if the underlying array is full, it needs to be resized (a new, larger array is created and elements are copied), which is an O(n) operation. This resizing happens infrequently, so the average cost is considered O(1).
  • add(index, element): O(n). Inserting an element in the middle requires shifting all subsequent elements to the right to make space. This is a linear time operation.
  • get(index): O(1). Accessing an element by its index is extremely fast, just like a standard array.
  • remove(index): O(n). Removing an element from the middle requires shifting all subsequent elements to the left to fill the gap. This is a linear time operation.
  • remove(element): O(n). First, it has to search for the element (O(n)), and then potentially shift other elements (O(n)).

Rule of Thumb: Use ArrayList when you need fast random access and don't need to insert or delete elements from the middle frequently. If you need frequent insertions and deletions, especially from the beginning or middle, a LinkedList might be a better choice.


Common Pitfall: Type Erasure and Primitives

A very common mistake for beginners is trying to use primitive types directly in an ArrayList.

// THIS WILL COMPILE, BUT IT'S WRONG AND WILL CAUSE RUNTIME ERRORS!
// ArrayList<int> numbers = new ArrayList<>(); // COMPILE ERROR!

ArrayList is a generic class and cannot hold primitive types like int, double, or char. You must use their corresponding wrapper classes.

Primitive Type Wrapper Class
int Integer
double Double
char Character
boolean Boolean
long Long
// CORRECT WAY
ArrayList<Integer> numbers = new ArrayList<>();
numbers.add(10);
numbers.add(20);

This is because generics in Java work with objects, not primitives. The Java compiler automatically converts between a primitive and its wrapper class; this is called autoboxing (primitive to wrapper) and unboxing (wrapper to primitive).


Advanced Topic: Sorting an ArrayList

You can easily sort an ArrayList using the Collections utility class.

import java.util.ArrayList;
import java.util.Collections;
public class SortingExample {
    public static void main(String[] args) {
        ArrayList<String> names = new ArrayList<>();
        names.add("Charlie");
        names.add("Alice");
        names.add("Bob");
        System.out.println("Before sorting: " + names); // [Charlie, Alice, Bob]
        // Sort in natural order (alphabetical for Strings, numerical for Integers)
        Collections.sort(names);
        System.out.println("After sorting: " + names); // [Alice, Bob, Charlie]
        ArrayList<Integer> numbers = new ArrayList<>();
        numbers.add(50);
        numbers.add(10);
        numbers.add(30);
        System.out.println("\nBefore sorting: " + numbers); // [50, 10, 30]
        Collections.sort(numbers);
        System.out.println("After sorting: " + numbers); // [10, 30, 50]
    }
}
分享:
扫描分享到社交APP
上一篇
下一篇