让星星⭐月亮告诉你,LinkedList和ArrayList(指定位置/头尾增加删除)

简介: 这段代码通过对比 `ArrayList` 和 `LinkedList` 在不同位置插入和删除数据的性能,展示了两者在不同操作下的优劣。`LinkedList` 在头部插入数据时效率高,但在尾部插入或指定位置插入时耗时较多,因为需要移动指针。`ArrayList` 则在任何位置插入数据时耗时相对稳定,但头部插入需要移动大量数据。删除操作中,`LinkedList` 在指定位置删除数据时耗时较少,而 `ArrayList` 需要移动数据。代码中通过多次插入和删除操作,统计并输出了具体的耗时情况。

⭐⭐⭐代码执行结论🌙🌙🌙:

/*
现象:LinkedList在指定位置采用add(index,data)方式增加数据时,位置越靠前耗时越少,越靠后耗时越多(而ArrayList采用add(index,data)方式的耗时跟位置关系不大);
原因:虽说LinkedList底层属于链表数据结构,不需要开辟一块连续的内存地址空间,逻辑上连续即可,在新增、插入和删除操作上占优势(只需要修改节点的前后指向即可,不需要移动数据);
但是因为LinkedList在插入时需要先移动指针到指定节点, 才能开始插入,一旦要插入的位置比较远,LinkedList就需要一步一步的移动指针, 直到移动到插入位置;
这就解释了, 为什么节点所在位置越靠后, 耗时越长, 因为指针移动需要时间。而ArrayList是数组结构, 可以根据下标直接获得位置, 这就省去了查找特定节点的时间,所以对ArrayList的影响不是特别大。

现象:LinkedList在头部add数据时(采用add(0,data)和addFirst(data)两种方式耗时差不多,都很少),耗时远远低于ArrayList(采用add(0,data));
原因:不像指定位置一样不需要移动指针,也不需要像ArrayList一样由于连续地址的原因移动数据。

现象:LinkedList在尾部add数据时采用指定位置add(lastIndex,data)的方式,ArrayList在尾部add数据时采用指定位置add(index,data)的方式,则LinkedList耗时远远高于ArrayList;
原因:跟在指定位置add(index,data)数据类似,越靠后LinkedList需要移动指针所花费的时间越多,而ArrayList查找效率本身就很高。

现象:LinkedList在尾部add数据时,如果采用addLast(data)的方式,ArrayList在尾部add数据时采用add(i)的方式,则LinkedList与ArrayList的耗时差不多;且两者的效率都比使用指定位置的方式有了极大提升
原因:LinkedList不像指定位置的方式那样,不再需要移动指针到指定位置;ArrayList不再像指定位置的方式那样,不再需要查询索引位置。

现象:LinkedList在remove(index)指定位置的数据时,位置越靠前耗时越少,越靠后耗时越多;
原因:跟在指定位置插入数据类似,越靠后移动指针所花费的时间越多。

现象:LinkedList在remove(Object)指定的数据时,耗时远少于ArrayList;
原因:不像指定位置一样不需要移动指针,也不需要像ArrayList一样由于连续地址的原因移动数据。
*/

public class TestArrayList {
   
    private static final int index = 100000;
    static List<Integer> list = null;
    public static void main(String[] args) {
   
        //测试ArrayList和LinkedList的插入效率
        addElementInList(list, "ArrayList");
        addElementInList(list, "LinkedList");
        //测试ArrayList和LinkedList的查询效率

    }

    private static void addElementInList(List<Integer> list, String type){
   
        if(type == "ArrayList"){
   
            list = new ArrayList();
            for(int i = 0; i < index; i++){
   
                list.add(i);
            }
        }
        if(type == "LinkedList"){
   
            list = new LinkedList();
            for(int i = 0; i < index; i++){
   
                list.add(i);
            }
        }
        long begin = System.currentTimeMillis();
//        int n = 20000;
        int n = index;
//        int n = 0;
        for(int i = 0; i < index; i++){
   
            if(type == "LinkedList"){
   
                list.add(n,i);
//                ((LinkedList)list).addLast(i);
//                ((LinkedList)list).addFirst(i);
            }else{
   
                list.add(n,i);
//                list.add(i);
            }
        }

        long end = System.currentTimeMillis();
        System.out.printf("在%s集合的索引为%d的位置插入%d条数据,总耗时为%d毫秒\n", type,n, index, end - begin);


        /*long begin2 = System.currentTimeMillis();
        for(int i = 0; i < index/6; i++){
            if(type == "LinkedList"){
                ((LinkedList)list).remove(i);
//                ((LinkedList)list).remove((Object)i);
//                ((LinkedList)list).remove();
            }else{
                ((ArrayList)list).remove(i);
//                ((ArrayList)list).remove((Object)i);
            }
        }
        long end2 = System.currentTimeMillis();
        System.out.printf("在%s集合remove(index)%d条数据,总耗时为%d毫秒\n", type, index, end2 - begin2);*/

        long begin2 = System.currentTimeMillis();
        for(int i = 0; i < index; i++){
   
            if(type == "LinkedList"){
   
//                ((LinkedList)list).remove(i);
                ((LinkedList)list).remove((Object)i);
//                ((LinkedList)list).remove();
            }else{
   
//                ((ArrayList)list).remove(i);
                ((ArrayList)list).remove((Object)i);
            }
        }
        long end2 = System.currentTimeMillis();
        System.out.printf("在%s集合remove(Object)%d条数据,总耗时为%d毫秒\n", type, index, end2 - begin2);
    }

}
目录
相关文章
|
JavaScript
vscode中通过快捷键`vh`将vue初始化代码结构自动输出
vscode中通过快捷键`vh`将vue初始化代码结构自动输出
523 0
vscode中通过快捷键`vh`将vue初始化代码结构自动输出
|
9月前
|
数据可视化 Java
让星星月亮告诉你,通过反射创建类的实例对象,并通过Unsafe theUnsafe来修改实例对象的私有的String类型的成员属性的值
本文介绍了如何使用 Unsafe 类通过反射机制修改对象的私有属性值。主要包括: 1. 获取 Unsafe 的 theUnsafe 属性:通过反射获取 Unsafe类的私有静态属性theUnsafe,并放开其访问权限,以便后续操作 2. 利用反射创建 User 类的实例对象:通过反射创建User类的实例对象,并定义预期值 3. 利用反射获取实例对象的name属性并修改:通过反射获取 User类实例对象的私有属性name,使用 Unsafe`的compareAndSwapObject方法直接在内存地址上修改属性值 核心代码展示了详细的步骤和逻辑,确保了对私有属性的修改不受 JVM 访问权限的限制
138 4
|
9月前
|
存储 Java 程序员
Java面试加分点!一文读懂HashMap底层实现与扩容机制
本文详细解析了Java中经典的HashMap数据结构,包括其底层实现、扩容机制、put和查找过程、哈希函数以及JDK 1.7与1.8的差异。通过数组、链表和红黑树的组合,HashMap实现了高效的键值对存储与检索。文章还介绍了HashMap在不同版本中的优化,帮助读者更好地理解和应用这一重要工具。
270 5
|
存储 设计模式 监控
运用Unity Profiler定位内存泄漏并实施对象池管理优化内存使用
【7月更文第10天】在Unity游戏开发中,内存管理是至关重要的一个环节。内存泄漏不仅会导致游戏运行缓慢、卡顿,严重时甚至会引发崩溃。Unity Profiler作为一个强大的性能分析工具,能够帮助开发者深入理解应用程序的内存使用情况,从而定位并解决内存泄漏问题。同时,通过实施对象池管理策略,可以显著优化内存使用,提高游戏性能。本文将结合代码示例,详细介绍如何利用Unity Profiler定位内存泄漏,并实施对象池来优化内存使用。
908 0
|
SQL 存储 关系型数据库
【mysql】将逗号分割的字段内容转换为多行并group by
【mysql】将逗号分割的字段内容转换为多行并group by
|
人工智能 架构师 搜索推荐
AI Agent【项目实战】:MetaGPT遇上元编程,重塑复杂多智能体协作的边界
【7月更文挑战第4天】AI Agent【项目实战】:MetaGPT遇上元编程,重塑复杂多智能体协作的边界
AI Agent【项目实战】:MetaGPT遇上元编程,重塑复杂多智能体协作的边界
|
自然语言处理 Java 数据处理
Java IO流全解析:字节流和字符流的区别与联系!
【6月更文挑战第26天】Java IO流涵盖字节流与字符流。字节流(InputStream/OutputStream)处理数据单位为字节,适用于二进制和文本,而字符流(Reader/Writer)专注于文本,处理单位为字符,处理编码转换。字符流在字节流基础上添加编码处理,以装饰器模式实现。文件复制示例展示了两者区别:字节流直接复制所有数据,字符流处理字符编码。理解并选择适当流类型对优化程序至关重要。
275 0
|
存储 图形学
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版11(附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版11(附带项目源码)
246 0
|
存储 JSON 自然语言处理
【制作100个unity游戏之26】unity2d横版卷轴动作类游12(附带项目源码)
【制作100个unity游戏之26】unity2d横版卷轴动作类游12(附带项目源码)
172 0
|
图形学 开发者
【制作100个unity游戏之26】unity2d横版卷轴动作类游11(附带项目源码)
【制作100个unity游戏之26】unity2d横版卷轴动作类游11(附带项目源码)
215 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等