ArrayList 与 LinkedList 的方法及其区别

写在前面: 我是「扬帆向海」,这个昵称来源于我的名字以及女朋友的名字。我热爱技术、热爱开源、热爱编程。技术是开源的、知识是共享的。

这博客是对自己学习的一点点总结及记录,如果您对 Java算法 感兴趣,可以关注我的动态,我们一起学习。

用知识改变命运,让我们的家人过上更好的生活

一、聊聊 LinkedList

1.LinkedList 的底层源码

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable

双链表实现了 List 和Deque接口。 实现所有可选列表操作,并允许所有元素(包括null )。
所有的操作都能像双向列表一样。 索引到列表中的操作将从开始或结束遍历列表,以更接近指定的索引为准。

2.LinkedList 的构造方法

  • LinkedList() 构造一个空列表。
  • LinkedList(Collection<? extends E> c) 构造一个包含指定集合的元素的列表,按照它们由集合的迭代器返回的顺序。

3.LinkedList 的常用方法

  • boolean add(E e) 将指定的元素追加到此列表的末尾
  • int size() 返回此列表中的元素数
  • E get(int index) 返回此列表中指定位置的元素
  • E remove(int index) 删除该列表中指定位置的元素
  • void addFirst(E e) 在该列表开头插入指定的元素
  • void addLast(E e) 将指定的元素追加到此列表的末尾
  • E getFirst() 返回此列表中的第一个元素
  • E getLast() 返回此列表中的最后一个元素
  • void push(E e) 将元素推送到由此列表表示的堆栈上
  • E pop() 从此列表表示的堆栈中弹出一个元素

测试代码:

public class LinkedListTest {
    public static void main(String[] args) {

        LinkedList<String> list = new LinkedList<String>();
        // boolean add(E e) 将指定的元素追加到此列表的末尾。
        list.add("aaa");
        list.add("ddd");
        list.add("ccc");
        list.add("111");
        list.add("aaa");
        list.add("eee");

        // int size() 返回此列表中的元素数
        System.out.println(list.size()); // 6
        System.out.println(list); // [aaa, ddd, ccc, 111, aaa, eee]

        // E get(int index) 返回此列表中指定位置的元素。
        System.out.println(list.get(0)); // aaa
        System.out.println(list.get(list.size() - 1)); // eee

        System.out.println("*****************************");
        // E remove(int index) 删除该列表中指定位置的元素
        System.out.println(list.remove(3)); //  111

        System.out.println("*****************************");
        // void addFirst(E e) 在该列表开头插入指定的元素
        list.addFirst("111");
        System.out.println(list); //  [111, aaa, ddd, ccc, aaa, eee]

        // void addLast(E e) 将指定的元素追加到此列表的末尾。
        list.addLast("666");
        System.out.println(list); // [111, aaa, ddd, ccc, aaa, eee, 666]

        // E getFirst() 返回此列表中的第一个元素
        System.out.println(list.getFirst()); // 111

        // E getLast() 返回此列表中的最后一个元素。
        System.out.println(list.getLast()); // 666

        System.out.println("*****************************");
        // void push(E e) 将元素推送到由此列表表示的堆栈上
        list.push("888");
        System.out.println(list); //  [888, 111, aaa, ddd, ccc, aaa, eee, 666]

        // E pop() 从此列表表示的堆栈中弹出一个元素
        String pop = list.pop();
        System.out.println(pop); // 888

        System.out.println("****************************");

        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        System.out.println("****************************");
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

测试结果:

6
[aaa, ddd, ccc, 111, aaa, eee]
aaa
eee
*****************************
111
*****************************
[111, aaa, ddd, ccc, aaa, eee]
[111, aaa, ddd, ccc, aaa, eee, 666]
111
666
*****************************
[888, 111, aaa, ddd, ccc, aaa, eee, 666]
888
****************************
111
aaa
ddd
ccc
aaa
eee
666
****************************
111
aaa
ddd
ccc
aaa
eee
666

二、聊聊 ArrayList

1. ArrayList 的底层源码

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

ArrayList 是从JDK1.2 引入的。

它是可调整大小的数组,实现了List接口。 实现所有可选列表操作,并允许所有元素包括null 。 除了实现List 接口之外,该类还提供了一些方法来操纵内部使用的存储列表的数组的大小。 (这个类是大致相当于Vector,不同之处在于它是不同步的)。

内部封装一个数组,用数组来存储数据。内部数组的默认初始容量 10,存满后 1.5 倍增长

从 JDK1.8开始, ArrayList 一开始创建一个长度为 0 的数组,当添加第一个元素时再创建一个始容量为 10 的 数组。

2. ArrayList 的构造方法

  • ArrayList() 构造一个初始容量为十的空列表。
  • ArrayList(Collection<? extends E> c) 构造一个包含指定集合的元素的列表,按照它们由集合的迭代器返回的顺序。
  • ArrayList(int initialCapacity) 构造具有指定初始容量的空列表。

3. ArrayList 的常用方法

ArrayList 的方法和 LinkedList 相同,但它没有两端操作数据的方法

  • boolean add(E e) 将指定的元素追加到此列表的末尾
  • int size() 返回此列表中的元素个数
  • E get(int index) 返回此列表中指定位置的元素
  • E remove(int index) 删除该列表中指定位置的元素
  • boolean remove(Object o) 从列表中删除指定元素的第一个出现(如果存在)
  • boolean contains(Object o) 如果此列表包含指定的元素,则返回 true
  • boolean addAll(int index, Collection<? extends E> c) 将指定集合中的所有元素插入到此列表中,从指定的位置开始
    - void clear() 从列表中删除所有元素
  • for / iterator 集合遍历

测试代码:

public class ArrayListTest {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        // boolean add(E e) 将指定的元素追加到此列表的末尾
        list.add(111);
        list.add(666);
        list.add(333);
        list.add(888);
        list.add(111);
        list.add(999);
        // int size() 返回此列表中的元素个数
        System.out.println(list.size()); // 6
        System.out.println(list); // [111, 666, 333, 888, 111, 999]

        // E get(int index) 返回此列表中指定位置的元素
        System.out.println(list.get(3)); // 888

        // E remove(int index) 删除该列表中指定位置的元素。
        list.remove(3);
        System.out.println(list); // [111, 666, 333, 111, 999]

        // boolean remove(Object o) 从列表中删除指定元素的第一个出现(如果存在)
        System.out.println(list.remove(Integer.valueOf(111))); // true
        System.out.println(list); // [666, 333, 111, 999]

        System.out.println("******************************");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        // 用三种方式遍历集合
        System.out.println("******************************");
        Iterator<Integer> it = list.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }

        System.out.println("******************************");
        for (Integer integer : list) {
            System.out.println(integer);
        }

        System.out.println("******************************");
        // boolean contains(Object o) 如果此列表包含指定的元素,则返回 true
        boolean contains = list.contains(666);
        System.out.println(contains); // true

        System.out.println("******************************");
        ArrayList<Integer> list1 = new ArrayList<Integer>();
        list1.add(123);
        list1.add(456);
        //  boolean addAll(int index, Collection<? extends E> c)
        //  将指定集合中的所有元素插入到此列表中,从指定的位置开始。
        list.addAll(1, list1);
        System.out.println(list); // [666, 123, 456, 333, 111, 999]
        System.out.println(list1); // [123, 456]

        // void clear() 从列表中删除所有元素
        list1.clear();
        System.out.println(list1); // []
    }
}

测试结果:

6
[111, 666, 333, 888, 111, 999]
888
[111, 666, 333, 111, 999]
true
[666, 333, 111, 999]
******************************
666
333
111
999
******************************
666
333
111
999
******************************
666
333
111
999
******************************
true
******************************
[666, 123, 456, 333, 111, 999]
[123, 456]
[]

三、两者与 Vector 的区别

1.ArrayList 和 LinkedList 的区别

二者都线程不安全,但是效率比 Vector 的高

  • ArrayList 底层是以 数组 的形式保存数据,随机访问集合中的元素比LinkedList 快(原因是 LinkedList 要移动指针);
  • LinkedList 内部以 链表 的形式保存集合里面数据,它随机访问集合中的元素性能比较慢,但是新增和删除时速度比 ArrayList 快(原因是 ArrayList 要移动数据)。

2.ArrayList 和 Vector 的区别

  • ArrayList 和 Vector 底层都是 数组
  • ArrayList 每次扩容的情况下扩容为原来的1.5 倍。线程不安全,当多个线程同时访问同一个ArrayList 集合时,如果两个或两个以上的线程修改了 ArrayList 集合,则必须手动保证该集合的同步性。
  • Vector 是同步类,其线程安全,但是它的访问比较慢。Vector 每次扩容为其空间大小的 2 倍。
  • 15
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
1.1 Java语言发展简史2 1.2 认识Java语言3 1.2.1 Java语言特性3 1.2.2 JavaApplet4 1.2.3 丰富的类库4 1.2.4 Java的竞争对手5 1.2.5 Java在应用领域的优势7 1.3 Java平台的体系结构7 1.3.1 JavaSE标准版8 1.3.2 JavaEE企业版10 1.3.3 JavaME微型版11 1.4 JavaSE环境安装和配置12 1.4.1 什么是JDK12 1.4.2 JDK安装目录和实用命令工具介绍12 1.4.3 设置环境变量13 1.4.4 验证配置的正确性14 1.5 MyEcilpse工具介绍JavaSE环境安装和配置15 1.6 本章练习16 第2章 2.1 什么是程序18 2.2 计算机中的程序18 2.3 Java程序19 2.3.1 Java程序中的类型19 2.3.2 Java程序开发三步曲21 2.3.3 开发Java第一个程序21 2.3.4 Java代码中的注释23 2.3.5 常见错误解析24 2.4 Java类库组织结构和文档27 2.5 Java虚拟机简介28 2.6 Java技术两种核心运行机制29 2.7 上机练习30 第3章 3.1 变量32 3.1.1 什么是变量32 3.1.2 为什么需要变量32 3.1.3 变量的声明和赋值33 3.1.4 变量应用实例33 3.2 数据的分类34 3.2.1 Java中的八种基本数据类型34 3.2.2 普及二进制36 3.2.3 进制间转换37 3.2.4 基本数据类型间转换38 3.2.5 数据类型应用实例38 3.2.6 引用数据类型39 3.3 关键字.标识符.常量39 3.3.1 变量命名规范39 3.3.2 经验之谈-常见错误的分析与处理40 3.3.3 Java标识符命名规则41 3.3.4 关键字42 3.3.5 常量42 3.4 运算符43 3.4.1 算术运算符43 3.4.2 赋值操作符45 3.4.3 关系操作符47 3.4.4 逻辑操作符48 3.4.5 位操作符49 3.4.6 移位运算符49 3.4.7 其他操作符50 3.5 表达式52 3.5.1 表达式简介52 3.5.2 表达式的类型和值52 3.5.3 表达式的运算顺序52 3.5.4 优先级和结合性问题52 3.6 选择结构54 3.6.1 顺序语句54 3.6.2 选择条件语句54 3.6.3 switch结构59 3.6.4 经验之谈-常见错误的分析与处理65 3.6.5 Switch和多重if结构比较66 3.7 循环语句66 3.7.1 While循环67 3.7.2 经验之谈-常见while错误70 3.7.3 do-while循环72 3.7.4 for循环74 3.7.5 经验之谈-for常见错误76 3.7.6 循环语句小结78 3.7.7 break语句79 3.7.8 continue语句82 3.8 JavaDebug技术84 3.9 本章练习85 第4章 4.1 一维数组90 4.1.1 为什么要使用数组90 4.1.2 什么是数组91 4.1.3 如何使用数组92 4.1.4 经验之谈-数组常见错误97 4.2 常用算法98 4.2.1 平均值,最大值,最小值98 4.2.3 数组排序102 4.2.3 数组复制103 4.3 多维数组105 4.3.1 二重循环105 4.3.2 控制流程进阶107 4.3.3 二维数组111 4.4 经典算法113 4.4.1 算法-冒泡排序113 4.4.2 插入排序115 4.5 增强for循环116 4.6 本章练习117 第5章 5.1 面向过程的设计思想120 5.2 面向对象的设计思想120 5.3 抽象121 5.3.1 对象的理解121 5.3.2 Java抽象思想的实现122 5.4 封装124 5.4.1 对象封装的概念理解124 5.4.2 类的理解125 5.4.3 Java类模板创建125 5.4.4 Java中对象的创建和使用127 5.5 属性130 5.5.1 属性的定义130 5.5.2 变量131 5.6 方法132 5.6.1 方法的定义132 5.6.2 构造方法135 5.6.4 方法重载138 5.6.5 自定义方法138 5.6.6 系统提供方法139 5.6.7 方法调用140 5.6.8 方法参数及其传递问题144 5.6.9 理解main方法语法及命令行参数147 5.6.1 0递归算法147 5.7 this关键字148 5.8 JavaBean149 5.9 包150 5.9.1 为什么需要包?150 5.9.2 如何创建包151 5.9.3 编译并生成包:151

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值