让星星⭐月亮告诉你,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);
    }

}
目录
相关文章
|
8月前
|
测试技术 持续交付 开发者
Logic Error: 如何识别和修复逻辑错误
识别和修复逻辑错误是软件开发中的重要技能。通过理解程序需求、使用调试工具、打印日志和编写单元测试,可以有效地识别逻辑错误。修复逻辑错误时,需仔细阅读代码,回溯错误来源,并进行全面的重新测试。遵循最佳实践,如保持代码简洁、进行代码审查和使用持续集成,可以进一步减少逻辑错误的发生,提高代码质量。希望本文能帮助开发者更好地识别和修复逻辑错误,编写出高质量的软件。
666 16
|
12月前
|
SQL 数据可视化 数据库
多维度解析低代码:从技术架构到插件生态
本文深入解析低代码平台,涵盖技术架构、插件生态及应用价值。通过图形化界面和模块化设计,低代码平台降低开发门槛,提升效率,支持企业快速响应市场变化。重点分析开源低代码平台的优势,如透明架构、兼容性与扩展性、可定制化开发等,探讨其在数据处理、功能模块、插件生态等方面的技术特点,以及未来发展趋势。
|
存储 设计模式 监控
运用Unity Profiler定位内存泄漏并实施对象池管理优化内存使用
【7月更文第10天】在Unity游戏开发中,内存管理是至关重要的一个环节。内存泄漏不仅会导致游戏运行缓慢、卡顿,严重时甚至会引发崩溃。Unity Profiler作为一个强大的性能分析工具,能够帮助开发者深入理解应用程序的内存使用情况,从而定位并解决内存泄漏问题。同时,通过实施对象池管理策略,可以显著优化内存使用,提高游戏性能。本文将结合代码示例,详细介绍如何利用Unity Profiler定位内存泄漏,并实施对象池来优化内存使用。
1338 0
|
存储 Java 程序员
Java面试加分点!一文读懂HashMap底层实现与扩容机制
本文详细解析了Java中经典的HashMap数据结构,包括其底层实现、扩容机制、put和查找过程、哈希函数以及JDK 1.7与1.8的差异。通过数组、链表和红黑树的组合,HashMap实现了高效的键值对存储与检索。文章还介绍了HashMap在不同版本中的优化,帮助读者更好地理解和应用这一重要工具。
694 5
|
SQL 存储 关系型数据库
【mysql】将逗号分割的字段内容转换为多行并group by
【mysql】将逗号分割的字段内容转换为多行并group by
|
自然语言处理 Java 数据处理
Java IO流全解析:字节流和字符流的区别与联系!
【6月更文挑战第26天】Java IO流涵盖字节流与字符流。字节流(InputStream/OutputStream)处理数据单位为字节,适用于二进制和文本,而字符流(Reader/Writer)专注于文本,处理单位为字符,处理编码转换。字符流在字节流基础上添加编码处理,以装饰器模式实现。文件复制示例展示了两者区别:字节流直接复制所有数据,字符流处理字符编码。理解并选择适当流类型对优化程序至关重要。
400 0
|
消息中间件 Java Kafka
使用Spring Boot和Kafka实现高效消息队列
使用Spring Boot和Kafka实现高效消息队列
|
存储 图形学
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版11(附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版11(附带项目源码)
390 0
|
图形学 开发者
【制作100个unity游戏之26】unity2d横版卷轴动作类游11(附带项目源码)
【制作100个unity游戏之26】unity2d横版卷轴动作类游11(附带项目源码)
309 0
|
存储 JSON 自然语言处理
【制作100个unity游戏之26】unity2d横版卷轴动作类游12(附带项目源码)
【制作100个unity游戏之26】unity2d横版卷轴动作类游12(附带项目源码)
299 0