ArrayList 和 LinkedList对比-Java
ArrayList 和 LinkedList 都是 Java 集合框架中的重要类,用来存储对象,它们实现了 List 接口,但在实现方式、性能和适用场景上有显著的差异。
1. 底层实现
ArrayList:- 基于动态数组实现。
- 当元素数量超过数组容量时,
ArrayList会重新分配更大的数组并复制原有数据,通常是原数组大小的 1.5 倍。 - 查找元素的时间复杂度是 O(1),即随机访问非常快。
LinkedList:- 基于双向链表实现。
- 每个元素都包含一个数据部分和指向前一个和下一个元素的引用。
- 查找元素的时间复杂度是 O(n),因为可能需要遍历链表。
2. 操作性能比较
| 访问元素(get) | O(1) | O(n) |
| 插入元素(add) | O(1)(在末尾) | O(1)(在末尾) |
| 删除元素(remove) | O(n) | O(1)(如果已知位置) |
| 插入/删除(中间) | O(n) | O(n) |
3. 内存消耗
ArrayList:只需要存储数据本身,内存开销较小。LinkedList:除了数据本身,还需要存储前后节点的引用(指针),因此内存开销较大。
4. 适用场景
-
ArrayList:- 适合频繁读取操作(访问元素)。
- 插入/删除操作(尤其是中间位置的插入/删除)较慢。
- 适用于元素较少变化的场景,或者当你只需要按顺序访问数据时。
-
LinkedList:- 适合频繁插入/删除操作,尤其是在列表的开头或中间。
- 不适合随机访问数据,因为访问某个元素需要遍历链表。
- 适用于元素频繁变化的场景。
5. 具体代码示例
例子 1:ArrayList 使用示例
import java.util.ArrayList;
public class ArrayListExample {
public static void main(String[] args) {
// 创建一个 ArrayList
ArrayList<String> arrayList = new ArrayList<>();
// 添加元素
arrayList.add("Apple");
arrayList.add("Banana");
arrayList.add("Cherry");
// 访问元素
System.out.println("First Element: " + arrayList.get(0)); // O(1)
// 删除元素
arrayList.remove("Banana"); // O(n)
// 输出 ArrayList
System.out.println("ArrayList: " + arrayList); // [Apple, Cherry]
}
}
例子 2:LinkedList 使用示例
import java.util.LinkedList;
public class LinkedListExample {
public static void main(String[] args) {
// 创建一个 LinkedList
LinkedList<String> linkedList = new LinkedList<>();
// 添加元素
linkedList.add("Apple");
linkedList.add("Banana");
linkedList.add("Cherry");
// 访问元素(需要遍历)
System.out.println("First Element: " + linkedList.get(0)); // O(n)
// 删除元素
linkedList.remove("Banana"); // O(n)
// 输出 LinkedList
System.out.println("LinkedList: " + linkedList); // [Apple, Cherry]
}
}
例子 3:ArrayList 和 LinkedList 性能对比
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class ListPerformanceTest {
public static void main(String[] args) {
// 测试元素个数
int size = 100000;
// 测试 ArrayList 性能
List<Integer> arrayList = new ArrayList<>();
long startTime = System.nanoTime();
for (int i = 0; i < size; i++) {
arrayList.add(i);
}
long endTime = System.nanoTime();
System.out.println("ArrayList Insert Time: " + (endTime - startTime) + "ns");
// 测试 LinkedList 性能
List<Integer> linkedList = new LinkedList<>();
startTime = System.nanoTime();
for (int i = 0; i < size; i++) {
linkedList.add(i);
}
endTime = System.nanoTime();
System.out.println("LinkedList Insert Time: " + (endTime - startTime) + "ns");
}
}
输出(可能的结果)
ArrayList Insert Time: 1357875ns
LinkedList Insert Time: 2877456ns
ArrayList:适合随机访问(O(1))和顺序插入。它的内存开销较小,但在中间插入和删除元素时比较慢。LinkedList:适合频繁的插入和删除操作,尤其是在开头或中间的插入/删除(O(1))。但由于需要遍历链表,随机访问性能较差(O(n))。
选择使用 ArrayList 还是 LinkedList,取决于应用场景的具体需求,尤其是对性能要求的不同。如果对插入/删除操作的性能要求更高,可以优先考虑 LinkedList;如果需要快速随机访问数据,则可以选择 ArrayList。
Java碎碎念 文章被收录于专栏
来一杯咖啡,聊聊Java的碎碎念呀
