List接口(动态数组)

List接口(动态数组)

List集合类中元素_有序且可重复_

ArrayList(重要)

  • 作为List接口的主要实现类
  • 线程不安全的,效率高
  • 底层使用Object[] elementData数组存储

ArrayList的源码分析

jdk7

  1. 构造器

    ArrayList list = new ArrayList();

    • 底层创建了长度为10的Object[]数组elementData
  2. 添加数据

    list.add(123)

    • 相当于elementData[0] = new Integer(123)
    • 底层的数组长度为10,添加元素个数小于10时,正常添加元素
    • 添加的元素个数大于10后(底层elementData数组容量不够),则需要扩容,默认扩容为原来容量的1.5倍(相当于新造一个数组,长度为原来长度的1.5倍)。同时需要将原来数组的数据复制到新的数组中

结论:建议使用带参的构造器(避免在中间时扩容)

ArrayList list = new ArrayList(int capacity)

jdk8

  1. 构造器

    ArrayList list = new ArrayList();

    • 底层Object[] elementData初始化为{},并没有创建长度为10的数组
  2. 添加数据

    list.add(123)

    • 第一次add()时,底层才创建了长度为10的数组,并将数据123添加到elementData[0]位置上
    • 后续的添加与扩容操作与jdk7相同

结论

  • jdk7中的ArrayList的对象的创建类似于单例模式中的饿汉式
  • jdk8中的ArrayList的对象的创建类似于单例模式中的懒汉式。延迟了数组的创建,节省内存

LinkedList

  • 对于频繁的插入、删除操作,使用此类效率比ArrayList高
  • 底层使用双向链表存储

LinkedList的源码分析

LinkedList list = new LinkedList();

内部声明了Node类型的first和last属性,默认值为null

list.add(123);

将123封装到Node中,创建了Node对象

其中Node定义为(源码),体现了LinkedList双向链表的特征:

1private static class Node<E> { 2 E item; 3 LinkedList.Node<E> next; 4 LinkedList.Node<E> prev; 5 6 Node(LinkedList.Node<E> prev, E element, LinkedList.Node<E> next) { 7 this.item = element; 8 this.next = next; 9 this.prev = prev; 10 } 11 }

Vector(不常用)

  • 作为List接口的古老实现类
  • 线程安全的、效率低
  • 底层使用Object[] elementData数组存储

Vector源码分析

  • jdk7和jdk8中通过Vector()构造器创建对象时,底层都创建了长度为10的数组
  • 默认扩容为原来数组长度的2倍

三者异同

相同点

三个类都实现了List接口,存储数据的特点相同(有序、可重复的数据)

不同点

  • 底层不同
  • 不同情况下效率不同
  • 线程安全问题

List接口中常用的方法

Collection中的方法都可用

  1. add(int index , Object eles)

    在index位置开始,将eles中的所有元素添加进来

    1ArrayList list = new ArrayList(); 2list.add(123); 3list.add("Ann"); 4list.add(new Students("Tom",18,90)); 5list.add(987); 6 7list.add(3,"AA"); 8System.out.println(list);//[123, Ann, Students{name='Tom', age=18, grade=90.0}, AA, 987]
  2. addAll(int index , Collection eles)

    从index位置开始将eles中的所有元素添加进来

    1ArrayList list = new ArrayList(); 2list.add(123); 3list.add("Ann"); 4list.add(new Students("Tom",18,90)); 5list.add(987); 6 7ArrayList arrayList = new ArrayList(); 8arrayList.add(123); 9arrayList.add("Lisa"); 10 11list.addAll(arrayList); 12System.out.println(list);//[123, Ann, Students{name='Tom', age=18, grade=90.0}, 987, 123, Lisa]

注意使用的是add()还是addAll():

  • add()方法中将添加的元素看成一个整体,无论eles中有多少个元素,添加后的元素个数就是+1
  • addAll()方法中eles中有多少个元素,添加后就多多少个元素
  1. get(int index)

    获取指定index位置的元素

    System.out.println(list.get(1));//Ann
    
  2. indexOf(Object obj)

    返回obj在当前集合中首次出现的位置

    System.out.println(list.indexOf(123));//0
    
    • 若存在该元素,返回其第一次出现的位置
    • 若不存在该元素,返回-1
  3. lastIndexOf(Object obj)

    返回obj在当前集合中最后一次出现的位置

    System.out.println(list.lastIndexOf(123));//4
    
    • 若存在该元素,返回其最后一次出现的位置
    • 若不存在该元素,返回-1
  4. remove(int index)

    移除指定index位置元素,并返回此元素

    1System.out.println(list.remove(1));//Ann 2System.out.println(list);//[123, Students{name='Tom', age=18, grade=90.0}, 987, 123, Lisa]

    注意和Collection接口中的remove方法区分

  5. set(int index , Object ele)

    设置指定index位置的元素为ele

    1System.out.println(list);//[123, Students{name='Tom', age=18, grade=90.0}, 987, 123, Lisa] 2list.set(2,789); 3System.out.println(list);//[123, Students{name='Tom', age=18, grade=90.0}, 789, 123, Lisa]
  6. subList(int fromIndex , int toIndex)

    返回从fromIndex到toIndex位置的子集合(左闭右开)

    1System.out.println(list);//[123, Students{name='Tom', age=18, grade=90.0}, 789, 123, Lisa] 2System.out.println(list.subList(1, 3));//[Students{name='Tom', age=18, grade=90.0}, 789]

总结

  • 增:add(Object obj)

  • 删:remove(int index)、remove(Object obj)

  • 改:set(int index , Object obj)

  • 查:get(int index)

  • 插:add(int index , Object obj)

  • 长度:size()

  • 遍历

    ① Iterator迭代器方式

    ②增强for循环

    ③普通循环

注:区分remove方法(形参)

  • List接口中remove方法要求里面的形参是int类型
  • Collection接口中remove方法要求里面的形参是对象
  • 若list中元素为1,2,3;remove(2)表明移除位置为2的元素;若想要移除元素2,需要remove(new Integer(2))
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

java将前端的json数组字符串转换为列表

记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang

java集合框架

ArrayList简介ArrayList是list接口的可变数组的实现。与一般数组不同的是,它的容量可以动态增长。ArrayList继承了AbstractList抽象类,实现了List,RandomAccess,Cloneable,java.io.Serializable接口,根据实现的接口看,它支持随机访问,支持克隆,支持序列化

java16

1:List的子类(掌握)(1)List的子类特点ArrayList:底层数据结构是数组,查询快,增删慢线程不安全,效率高Vector:底层数据结构是数组,查询快,增删慢线程安全,效率低LinkedList:底层数据结构是链表,查询慢,增删快线程不安全,效率高(2)ArrayListA: