LinkedList竟然比ArrayList慢了1000多倍?(动图+性能评测)
wxin55 2025-05-11 02:02 2 浏览 0 评论
数组和链表是程序中常用的两种数据结构,也是面试中常考的面试题之一。然而对于很多人来说,只是模糊的记得二者的区别,可能还记得不一定对,并且每次到了面试的时候,都得把这些的概念拿出来背一遍才行,未免有些麻烦。而本文则会从执行过程图以及性能评测等方面入手,让你更加深入的理解和记忆二者的区别,有了这次深入的学习之后,相信会让你记忆深刻。
数组
在开始(性能评测)之前我们先来回顾一下,什么是数组?
数组的定义如下:
数组(Array)是由相同类型的元素(element)的集合所组成的数据结构,分配一块连续的内存来存储。利用元素的索引(index)可以计算出该元素对应的存储地址。
最简单的数据结构类型是一维数组。例如,索引为 0 到 9 的 32 位整数数组,可作为在存储器地址 2000,2004,2008,...2036 中,存储 10个 变量,因此索引为 i 的元素即在存储器中的 2000+4×i 地址。数组第一个元素的存储器地址称为第一地址或基础地址。
简单来说,数组就是由一块连续的内存组成的数据结构。这个概念中有一个关键词“连续”,它反映了数组的一大特点,就是它必须是由一个连续的内存组成的。
数组的数据结构,如下图所示:
数组添加的过程,如下图所示:
数组的优点
数组的“连续”特征决定了它的访问速度很快,因为它是连续存储的,所以这就决定了它的存储位置就是固定的,因此它的访问速度就很快。比如现在有 10 个房间是按照年龄顺序入住的,当我们知道第一房子住的是 20 岁的人之后,那么我们就知道了第二个房子是 21 岁的人,第五个房子是 24 岁的人......等等。
数组的缺点
祸兮福所倚,福兮祸所伏。数组的连续性既有优点又有缺点,优点上面已经说了,而缺点它对内存的要求比较高,必须要找到一块连续的内存才行。
数组的另一个缺点就是插入和删除的效率比较慢,假如我们在数组的非尾部插入或删除一个数据,那么就要移动之后的所有数据,这就会带来一定的性能开销,删除的过程如下图所示:
数组还有一个缺点,它的大小固定,不能动态拓展。
链表
链表是和数组互补的一种数据结构,它的定义如下:
链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。由于不必须按顺序存储,链表在插入的时候可以达到 O(1) 的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要 O(n) 的时间,而顺序表相应的时间复杂度分别是 O(logn) 和 O(1)。
也就说链表是一个无需连续内存存储的数据结构,链表的元素有两个属性,一个是元素的值,另一个是指针,此指针标记了下一个元素的地址。
链表的数据结构,如下图所示:
链表添加的过程,如下图所示:
链表删除的过程,如下图所示:
链表分类
链表主要分为以下几类:
- 单向链表
- 双向链表
- 循环链表
单向链表
单向链表中包含两个域,一个信息域和一个指针域。这个链接指向列表中的下一个节点,而最后一个节点则指向一个空值,我们上面所展示的链表就是单向链表。
双向链表
双向链表也叫双链表,双向链表中不仅有指向后一个节点的指针,还有指向前一个节点的指针,这样可以从任何一个节点访问前一个节点,当然也可以访问后一个节点,以至整个链表。
双向链表的结构如下图所示:
循环链表
循环链表中第一个节点之前就是最后一个节点,反之亦然。循环链表的无边界使得在这样的链表上设计算法会比普通链表更加容易。
循环链表的结构如下图所示:
为什么会有单、双链表之分?
有人可能会问,既然已经有单向链表了,那为什么还要双向链表呢?双向链表有什么优势呢?
这个就要从链表的删除说起了,如果单向链表要删除元素的话,不但要找到删除的节点,还要找到删除节点的上一个节点(通常称之为前驱),因为需要变更上一个节点中 next 的指针,但又因为它是单向链表,所以在删除的节点中并没有存储上一个节点的相关信息,那么我们就需要再查询一遍链表以找到上一个节点,这样就带来了一定的性能问题,所以就有了双向链表。
链表优点
链表的优点大致可分为以下三个:
- 链表对内存的利用率比较高,无需连续的内存空间,即使有内存碎片,也不影响链表的创建;
- 链表的插入和删除的速度很快,无需像数组一样需要移动大量的元素;
- 链表大小不固定,可以很方便的进行动态扩展。
链表缺点
链表的主要缺点是不能随机查找,必须从第一个开始遍历,查找效率比较低,链表查询的时间复杂度是 O(n)。
性能评测
了解了数组和链表的基础知识之后,接下来我们正式进入性能评测环节。
在正式开始之前,我们先来明确一下测试目标,我们需要测试的点其实只有 6 个:
- 从头部/中间部分/尾部进行添加操作的性能测试;
- 从头部/中间部分/尾部开始查询的性能测试。
因为添加操作和删除操作在执行时间层面基本是一致的,比如数组添加需要移动后面的元素,删除也同样是移动后面的元素;而链表也是如此,添加和删除都是改变自身和相连节点的信息,因此我们就把添加和删除的测试合二为一,用添加操作来进行测试。
测试说明:
- 在 Java 语言中,数组的代表为 ArrayList,而链表的代表为 LinkedList,因此我们就用这两个对象来进行测试;
- 本文我们将使用 Oracle 官方推荐 JMH 框架来进行测试,点击查看更多关于 JMH 的内容;
- 本文测试环境是 JDK 1.8、MacMini、Idea 2020.1。
1.头部添加性能测试
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime) // 测试完成时间
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS) // 预热次数和时间
@Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS) // 测试次数和时间
@Fork(1) // fork 1 个线程
@State(Scope.Thread)
public class ArrayOptimizeTest {
private static final int maxSize = 1000; // 测试循环次数
private static final int operationSize = 100; // 操作次数
private static ArrayList<Integer> arrayList;
private static LinkedList<Integer> linkedList;
public static void main(String[] args) throws RunnerException {
// 启动基准测试
Options opt = new OptionsBuilder()
.include(ArrayOptimizeTest.class.getSimpleName()) // 要导入的测试类
.build();
new Runner(opt).run(); // 执行测试
}
@Setup
public void init() {
// 启动执行事件
arrayList = new ArrayList<Integer>();
linkedList = new LinkedList<Integer>();
for (int i = 0; i < maxSize; i++) {
arrayList.add(i);
linkedList.add(i);
}
}
@Benchmark
public void addArrayByFirst(Blackhole blackhole) {
for (int i = 0; i < +operationSize; i++) {
arrayList.add(i, i);
}
// 为了避免 JIT 忽略未被使用的结果计算
blackhole.consume(arrayList);
}
@Benchmark
public void addLinkedByFirst(Blackhole blackhole) {
for (int i = 0; i < +operationSize; i++) {
linkedList.add(i, i);
}
// 为了避免 JIT 忽略未被使用的结果计算
blackhole.consume(linkedList);
}
}
从以上代码可以看出,在测试之前,我们先将 ArrayList 和 LinkedList 进行数据初始化,再从头部开始添加 100 个元素,执行结果如下:
从以上结果可以看出,LinkedList 的平均执行(完成)时间比 ArrayList 平均执行时间快了约 216 倍。
2.中间添加性能测试
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime) // 测试完成时间
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS) // 预热次数和时间
@Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS) // 测试次数和时间
@Fork(1) // fork 1 个线程
@State(Scope.Thread)
public class ArrayOptimizeTest {
private static final int maxSize = 1000; // 测试循环次数
private static final int operationSize = 100; // 操作次数
private static ArrayList<Integer> arrayList;
private static LinkedList<Integer> linkedList;
public static void main(String[] args) throws RunnerException {
// 启动基准测试
Options opt = new OptionsBuilder()
.include(ArrayOptimizeTest.class.getSimpleName()) // 要导入的测试类
.build();
new Runner(opt).run(); // 执行测试
}
@Setup
public void init() {
// 启动执行事件
arrayList = new ArrayList<Integer>();
linkedList = new LinkedList<Integer>();
for (int i = 0; i < maxSize; i++) {
arrayList.add(i);
linkedList.add(i);
}
}
@Benchmark
public void addArrayByMiddle(Blackhole blackhole) {
int startCount = maxSize / 2; // 计算中间位置
// 中间部分进行插入
for (int i = startCount; i < (startCount + operationSize); i++) {
arrayList.add(i, i);
}
// 为了避免 JIT 忽略未被使用的结果计算
blackhole.consume(arrayList);
}
@Benchmark
public void addLinkedByMiddle(Blackhole blackhole) {
int startCount = maxSize / 2; // 计算中间位置
// 中间部分进行插入
for (int i = startCount; i < (startCount + operationSize); i++) {
linkedList.add(i, i);
}
// 为了避免 JIT 忽略未被使用的结果计算
blackhole.consume(linkedList);
}
}
从以上代码可以看出,在测试之前,我们先将 ArrayList 和 LinkedList 进行数据初始化,再从中间开始添加 100 个元素,执行结果如下:
从上述结果可以看出,LinkedList 的平均执行时间比 ArrayList 平均执行时间快了约 54 倍。
3.尾部添加性能测试
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime) // 测试完成时间
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS) // 预热次数和时间
@Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS) // 测试次数和时间
@Fork(1) // fork 1 个线程
@State(Scope.Thread)
public class ArrayOptimizeTest {
private static final int maxSize = 1000; // 测试循环次数
private static final int operationSize = 100; // 操作次数
private static ArrayList<Integer> arrayList;
private static LinkedList<Integer> linkedList;
public static void main(String[] args) throws RunnerException {
// 启动基准测试
Options opt = new OptionsBuilder()
.include(ArrayOptimizeTest.class.getSimpleName()) // 要导入的测试类
.build();
new Runner(opt).run(); // 执行测试
}
@Setup
public void init() {
// 启动执行事件
arrayList = new ArrayList<Integer>();
linkedList = new LinkedList<Integer>();
for (int i = 0; i < maxSize; i++) {
arrayList.add(i);
linkedList.add(i);
}
}
@Benchmark
public void addArrayByEnd(Blackhole blackhole) {
int startCount = maxSize - 1 - operationSize;
for (int i = startCount; i < (maxSize - 1); i++) {
arrayList.add(i, i);
}
// 为了避免 JIT 忽略未被使用的结果计算
blackhole.consume(arrayList);
}
@Benchmark
public void addLinkedByEnd(Blackhole blackhole) {
int startCount = maxSize - 1 - operationSize;
for (int i = startCount; i < (maxSize - 1); i++) {
linkedList.add(i, i);
}
// 为了避免 JIT 忽略未被使用的结果计算
blackhole.consume(linkedList);
}
}
以上程序的执行结果为:
从上述结果可以看出,LinkedList 的平均执行时间比 ArrayList 平均执行时间快了约 32 倍。
4.头部查询性能评测
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime) // 测试完成时间
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS) // 预热次数和时间
@Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS) // 测试次数和时间
@Fork(1) // fork 1 个线程
@State(Scope.Thread)
public class ArrayOptimizeTest {
private static final int maxSize = 1000; // 测试循环次数
private static final int operationSize = 100; // 操作次数
private static ArrayList<Integer> arrayList;
private static LinkedList<Integer> linkedList;
public static void main(String[] args) throws RunnerException {
// 启动基准测试
Options opt = new OptionsBuilder()
.include(ArrayOptimizeTest.class.getSimpleName()) // 要导入的测试类
.build();
new Runner(opt).run(); // 执行测试
}
@Setup
public void init() {
// 启动执行事件
arrayList = new ArrayList<Integer>();
linkedList = new LinkedList<Integer>();
for (int i = 0; i < maxSize; i++) {
arrayList.add(i);
linkedList.add(i);
}
}
@Benchmark
public void findArrayByFirst() {
for (int i = 0; i < operationSize; i++) {
arrayList.get(i);
}
}
@Benchmark
public void findLinkedyByFirst() {
for (int i = 0; i < operationSize; i++) {
linkedList.get(i);
}
}
}
以上程序的执行结果为:
从上述结果可以看出,从头部查询 100 个元素时 ArrayList 的平均执行时间比 LinkedList 平均执行时间快了约 1990 倍。
5.中间查询性能评测
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime) // 测试完成时间
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS) // 预热次数和时间
@Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS) // 测试次数和时间
@Fork(1) // fork 1 个线程
@State(Scope.Thread)
public class ArrayOptimizeTest {
private static final int maxSize = 1000; // 测试循环次数
private static final int operationSize = 100; // 操作次数
private static ArrayList<Integer> arrayList;
private static LinkedList<Integer> linkedList;
public static void main(String[] args) throws RunnerException {
// 启动基准测试
Options opt = new OptionsBuilder()
.include(ArrayOptimizeTest.class.getSimpleName()) // 要导入的测试类
.build();
new Runner(opt).run(); // 执行测试
}
@Setup
public void init() {
// 启动执行事件
arrayList = new ArrayList<Integer>();
linkedList = new LinkedList<Integer>();
for (int i = 0; i < maxSize; i++) {
arrayList.add(i);
linkedList.add(i);
}
}
@Benchmark
public void findArrayByMiddle() {
int startCount = maxSize / 2;
int endCount = startCount + operationSize;
for (int i = startCount; i < endCount; i++) {
arrayList.get(i);
}
}
@Benchmark
public void findLinkedyByMiddle() {
int startCount = maxSize / 2;
int endCount = startCount + operationSize;
for (int i = startCount; i < endCount; i++) {
linkedList.get(i);
}
}
}
以上程序的执行结果为:
从上述结果可以看出,从中间查询 100 个元素时 ArrayList 的平均执行时间比 LinkedList 平均执行时间快了约 28089 倍,真是恐怖。
6.尾部查询性能评测
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime) // 测试完成时间
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS) // 预热次数和时间
@Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS) // 测试次数和时间
@Fork(1) // fork 1 个线程
@State(Scope.Thread)
public class ArrayOptimizeTest {
private static final int maxSize = 1000; // 测试循环次数
private static final int operationSize = 100; // 操作次数
private static ArrayList<Integer> arrayList;
private static LinkedList<Integer> linkedList;
public static void main(String[] args) throws RunnerException {
// 启动基准测试
Options opt = new OptionsBuilder()
.include(ArrayOptimizeTest.class.getSimpleName()) // 要导入的测试类
.build();
new Runner(opt).run(); // 执行测试
}
@Setup
public void init() {
// 启动执行事件
arrayList = new ArrayList<Integer>();
linkedList = new LinkedList<Integer>();
for (int i = 0; i < maxSize; i++) {
arrayList.add(i);
linkedList.add(i);
}
}
@Benchmark
public void findArrayByEnd() {
for (int i = (maxSize - operationSize); i < maxSize; i++) {
arrayList.get(i);
}
}
@Benchmark
public void findLinkedyByEnd() {
for (int i = (maxSize - operationSize); i < maxSize; i++) {
linkedList.get(i);
}
}
}
以上程序的执行结果为:
从上述结果可以看出,从尾部查询 100 个元素时 ArrayList 的平均执行时间比 LinkedList 平均执行成时间快了约 1839 倍。
7.扩展添加测试
接下来我们再来测试一下,正常情况下我们从头开始添加数组和链表的性能对比,测试代码如下:
import org.openjdk.jmh.annotations.*;
import org.openjdk.jmh.infra.Blackhole;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
@BenchmarkMode(Mode.AverageTime) // 测试完成时间
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS) // 预热次数和时间
@Measurement(iterations = 5, time = 5, timeUnit = TimeUnit.SECONDS) // 测试次数和时间
@Fork(1) // fork 1 个线程
@State(Scope.Thread)
public class ArrayOptimizeTest {
private static final int maxSize = 1000; // 测试循环次数
private static ArrayList<Integer> arrayList;
private static LinkedList<Integer> linkedList;
public static void main(String[] args) throws RunnerException {
// 启动基准测试
Options opt = new OptionsBuilder()
.include(ArrayOptimizeTest.class.getSimpleName()) // 要导入的测试类
.build();
new Runner(opt).run(); // 执行测试
}
@Benchmark
public void addArray(Blackhole blackhole) { // 中间删数组表
arrayList = new ArrayList<Integer>();
for (int i = 0; i < maxSize; i++) {
arrayList.add(i);
}
// 为了避免 JIT 忽略未被使用的结果计算
blackhole.consume(arrayList);
}
@Benchmark
public void addLinked(Blackhole blackhole) { // 中间删除链表
linkedList = new LinkedList<Integer>();
for (int i = 0; i < maxSize; i++) {
linkedList.add(i);
}
// 为了避免 JIT 忽略未被使用的结果计算
blackhole.consume(linkedList);
}
}
以上程序的执行结果为:
接下来,我们将添加的次数调至 1w,测试结果如下:
最后,我们再将添加次数调至 10w,测试结果如下:
从以上结果可以看出在正常情况下,从头部依次开始添加元素时,他们性能差别不大。
总结
本文我们介绍了数组的概念以及它的优缺点,同时还介绍了单向链表、双向链表及循环链表的概念以及链表的优缺点。我们在最后的评测中可以看出,当我们正常从头部依次添加元素时,链表和数组的性能差不不大。但当数据初始化完成之后,我们再进行插入操作时,尤其是从头部插入时,因为数组要移动之后的所有元素,因此性能要比链表低很多;但在查询时性能刚好相反,因为链表要遍历查询,并且 LinkedList 是双向链表,所以在中间查询时性能要比数组查询慢了上万倍(查询 100 个元素),而两头查询(首部和尾部)时,链表也比数组慢了将近 1000 多倍(查询 100 个元素),因此在查询比较多的场景中,我们要尽量使用数组,而在添加和删除操作比较多时,我们应该使用链表结构。
数组和链表的操作时间复杂度,如下表所示:
数组 链表 查询 O(1) O(n) 插入 O(n) O(1) 删除 O(n) O(1)
用心写好每篇文章,若能看出来,请给我一个「赞」鼓励吧。
相关推荐
- Java中List 和 Map、Set 的区别(list和set和map)
-
hello,大家好,我是霖仔java集合的大家了解,我再给大家说一下他们的区别,希望能够帮助到大家结构特点:List和Set是存储单列数据的集合,Map是存储键和值这样的双列数据的集合;Lis...
- Java 集合框架全面解析:选对数据结构,提升开发效率
-
上一章我们详细介绍了各种常用的数据结构情况(参考:数据结构复杂度全览:如何选择最优结构?),本文结合关键数据结构,从列表(List)、队列(Queue)、集合(Set)、映射(Map)四个维度,深入解...
- LinkedList竟然比ArrayList慢了1000多倍?(动图+性能评测)
-
数组和链表是程序中常用的两种数据结构,也是面试中常考的面试题之一。然而对于很多人来说,只是模糊的记得二者的区别,可能还记得不一定对,并且每次到了面试的时候,都得把这些的概念拿出来背一遍才行,未免有些麻...
- LinkedList 底层源码深度解析(linkedlist底层数据结构)
-
目录1.引言2.LinkedList概述2.1类继承体系图2.2各个接口作用3.与ArrayList的对比4.底层数据结构5.核心方法源码解析5.1add()方法5.2a...
- List的用法和实例详解——Java进阶知识讲义系列(四)
-
序欢迎来到全网最完整的Java进阶知识系列教程!!!每天定时更新!!!本期是Java进阶知识系列的第四讲,将分享Java常用的数据容器——集合类。集合类也分很多类型,比如:List、Set、Map、Q...
- Rust高效集合操作(rust基本操作)
-
集合的分类Rust的集合类型主要分布在标准库的std::collections模块中,同时也包括语言内置的数组和字符串类型序列容器序列容器维护元素的顺序,适合需要按索引访问或顺序遍历的场景向量(...
- Java八股文:核心知识点梳理(java八股文是啥)
-
一、Java基础1.Java基本数据类型8种基本类型:整型:byte(1),short(2),int(4),long(8)浮点型:float(4),double(8)字符型:char(2)布...
- 为什么我不推荐研发人员使用 LinkedList?
-
在Java集合框架中,LinkedList作为List的实现之一,经常被认为是ArrayList的替代方案。然而,在大多数实际场景下,我们并不推荐使用LinkedList,原因主要集中...
- ArrayList 、 LinkedList、Vector的区别
-
ArrayList、LinkedList、Vector的区别如下:ArrayListLinkedListVector结构动态数组双向链表动态数组是否线程安全否否是效率遍历查找快,插入删除慢插入删除...
- (2020 )Java最新面试笔试题答案解析(一)
-
Java中的集中基本数据类型是什么?各占用多少字节?【数值型】—(整数类型)byte(1字节)short(2字节)int(4字节)long(8字节)拓展:Java中的数据类型除了上面的基本...
- 超简单五步实现Linux虚拟机CentOS 7系统Root密码忘记重置
-
环境:CentOS7.5重置root密码:1.CentOS7虚拟机开机,将鼠标光标移动至虚拟机内。2.在虚拟机中使用键盘上↑和↓键将选择行设置为第一行(背景高亮即为选中),按下键盘上的e,进...
- 吊轨门和推拉门哪个好?北京今朝区别介绍看完不入坑
-
厨房到底使用什么门好?相信这是大多数业主都比较抓狂的事情,其实在装修中材料的选择最终还是要依据空间而定,那么吊轨门和推拉门哪个好呢?下面就跟随北京装修网一起来看看吧!吊轨门与推拉门介绍吊轨门吊轨门的特...
- 〖省钱宝典〗不花冤枉钱,少走弯路!居家中推拉门如何设计?
-
想要空间最大程度的显大?想要充足的光线?又想拥有合理的区域划分?那么推拉门是你绝对不能错过的好选择。推拉门的设计轻盈简洁,绝对是室内每个空间的福音。它不仅可以最大化地节省空间,方便了居室的功能划分和利...
- 吊趟门与推拉门有什么区别?(吊趟门贵还是推拉门贵)
-
吊趟门与推拉门的区别很多人在购买的时候并不清楚,有些客人甚至根本分不清吊趟门和推拉门,今天小编就给大家讲讲吊趟门与推拉门的相关内容,看看吊趟门与推拉门的区别有哪些?1、推拉门采用以门扇下滑轮为主支撑点...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- Java中List 和 Map、Set 的区别(list和set和map)
- Java 集合框架全面解析:选对数据结构,提升开发效率
- LinkedList竟然比ArrayList慢了1000多倍?(动图+性能评测)
- LinkedList 底层源码深度解析(linkedlist底层数据结构)
- List的用法和实例详解——Java进阶知识讲义系列(四)
- Rust高效集合操作(rust基本操作)
- Java八股文:核心知识点梳理(java八股文是啥)
- 面试题:ArrayList和LinkedList有什么区别?
- 为什么我不推荐研发人员使用 LinkedList?
- ArrayList 、 LinkedList、Vector的区别
- 标签列表
-
- hive行转列函数 (63)
- sourcemap文件是什么 (54)
- display none 隐藏后怎么显示 (56)
- 共享锁和排他锁的区别 (51)
- httpservletrequest 获取参数 (64)
- jstl包 (64)
- qsharedmemory (50)
- watch computed (53)
- java中switch (68)
- date.now (55)
- git-bash (56)
- 盒子垂直居中 (68)
- npm是什么命令 (62)
- python中+=代表什么 (70)
- fsimage (51)
- nginx break (61)
- mysql分区表的优缺点 (53)
- centos7切换到图形界面 (55)
- 前端深拷贝 (62)
- kmp模式匹配算法 (57)
- jsjson字符串转json对象 (53)
- jdbc connection (61)
- javascript字符串转换为数字 (54)
- mybatis 使用 (73)
- 安装mysql数据库 (55)