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双向链表的特征:

private static class Node<E> {
E item;
LinkedList.Node<E> next;
LinkedList.Node<E> prev; Node(LinkedList.Node<E> prev, E element, LinkedList.Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}

Vector(不常用)

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

Vector源码分析

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

三者异同

相同点

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

不同点

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

List接口中常用的方法

Collection中的方法都可用

  1. add(int index , Object eles)

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

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

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

    ArrayList list = new ArrayList();
    list.add(123);
    list.add("Ann");
    list.add(new Students("Tom",18,90));
    list.add(987); ArrayList arrayList = new ArrayList();
    arrayList.add(123);
    arrayList.add("Lisa"); list.addAll(arrayList);
    System.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位置元素,并返回此元素

    System.out.println(list.remove(1));//Ann
    System.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

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

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

    System.out.println(list);//[123, Students{name='Tom', age=18, grade=90.0}, 789, 123, Lisa]
    System.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))

List接口(动态数组)的更多相关文章

  1. Delphi内存管理(Integer、Boolean、Record、枚举等都是在作用域内编译器自动申请内存,出了作用域自动释放;另外,字符串、Variant、动态数组、接口也是由Delphi自动管理)

    一.什么是堆.栈? 程序需要的内存空间分为 heap(堆) 和 stack(栈),heap 是自由存储区, stack 是自动存储区,使用 heap 需要手动申请.手动释放, stack 是自动申请. ...

  2. ArrayList类源码解析——ArrayList动态数组的实现细节(基于JDK8)

    一.基本概念 ArrayList是一个可以添加对象元素,并进行元素的修改查询删除等操作的容器类.ArrayList底层是由数组实现的,所以和数组一样可以根据索引对容器对象所包含的元素进行快速随机的查询 ...

  3. C++语言------顺序表实现,用动态数组的方法

    C++ 中常用的一些东西,通过使用动态数组来实现顺序表, 掌握了一下知识点: 1.预处理有三中方法 宏定义,文件包含,条件编译 2.使用同名的变量时,可以在外层使用命名空间 类解决变量名重定义的错误 ...

  4. C基础 万能动态数组

    引言 - 动态数组切入 开发中动态类型无外乎list 或者 vector, 这里就是在C中实现vector结构容器部分. 对于C中使用的数据结构, 可以参照下面感觉很不错框架源码学习 , 感觉是< ...

  5. STL之顺序容器 deque 动态数组

    deque是一个动态数组,deque与vector非常类似,vector是一个单向开口的连续线性空间,deque则是双向开口的连续线性空间.两者唯一的区别是deque可以在数组的开头和末尾插入和删除数 ...

  6. C和Fortran互相传递动态数组

    C和Fortran的相互调用传递数值的方法有很多,但是F03标准的出笼,使用ISO_C_BINDING进行C和Fortran的互相调用有着更显著的优势: 1.与编译器和平台无关: 2.Fortran中 ...

  7. C++学习之动态数组类的封装

    动态数组(Dynamic Array)是指动态分配的.可以根据需求动态增长占用内存的数组.为了实现一个动态数组类的封装,我们需要考虑几个问题:new/delete的使用.内存分配策略.类的四大函数(构 ...

  8. 数据结构(1) 第一天 算法时间复杂度、线性表介绍、动态数组搭建(仿Vector)、单向链表搭建、企业链表思路

    01 数据结构基本概念_大O表示法 无论n是多少都执行三个具体步骤 执行了12步 O(12)=>O(1) O(n) log 2 N = log c N / log c N (相当于两个对数进行了 ...

  9. 纯数据结构Java实现(1/11)(动态数组)

    我怕说这部分内容太简单后,突然蹦出来一个大佬把我虐到哭,还是悠着点,踏实写 大致内容有: 增删改查,泛型支持,扩容支持,复杂度分析.(铺垫: Java语言中的数组) 基础铺垫 其实没啥好介绍的,顺序存 ...

随机推荐

  1. NodeMCU手把手入门:配置NodeMCU ESP8266开发板环境及点亮LED灯

    之前一直在玩树莓派,最近实验室买了些NodeMCU就想着玩一玩,没想到挺有意思的.其实树莓派能实现的功能,它大部分也可以,价格比派也便宜不少,舍不得买派的同学可以先买这个开发板玩一玩. 本文主要介绍了 ...

  2. 【差分】Tallest Cow

    题目 FJ's N(1≤N≤10,000) cows conveniently indexed 1..N are standing in a line. Each cow has a positive ...

  3. NOIp ( on line ) 提高组 2020 总结

    T1 : 序列 题意: 一共有T组数据,每组数据有两个长度为n的序列a,b,m个操作,问a序列是否可以转换成b,是输出YES,否的话输出NO. m个操作分别为ti,xi,yi,若t为1,则x和y上的数 ...

  4. redis.cluster/memcached.cluster/wmware esxi

    1. 安装配置redis的cluster 集群 redis 集群高可用 实验环境 192.168.198.131 openvpn-server #42-Ubuntu SMP Mon Jun 8 14: ...

  5. Java实现 第十一届蓝桥杯——超级胶水(渴望有题目的大佬能给小编提供一下题目,讨论群:99979568)

    PS: 好久没写过算法题了,总感觉自己写的思路没问题,但是结果就是不对,希望哪位大佬有时间能给找找问题 超级胶水 小明有n颗石子,按顺序摆成一排,他准备用胶水将这些石子黏在一起. 梅克什字有自己的重量 ...

  6. web3.js支持SimpleChain跨链调用

    SimpleChain的跨链协议已经对外开放很久了,很多应用也已经慢慢支持Simplechain的跨链.最近社区开发者web3.js中集成了Simplechain的跨链接口,开发者只需用npm安装包文 ...

  7. MyBatis源码分析(一)

    MyBatis故事: 官方网站:http://www.mybatis.org 官方文档:http://www.mybatis.org/mybatis-3/ GitHub:https://github. ...

  8. java IO流 (一) File类的使用

    1.File类的理解* 1. File类的一个对象,代表一个文件或一个文件目录(俗称:文件夹)* 2. File类声明在java.io包下* 3. File类中涉及到关于文件或文件目录的创建.删除.重 ...

  9. 数据可视化之powerBI基础(四)深入了解PowerBI的工具提示功能

    https://zhuanlan.zhihu.com/p/36804592 在PowerBI上个月的更新中,增加了工具提示功能,这项功能允许您将自己的可视化作品放置到工具提示中,通过鼠标悬停的方式来展 ...

  10. redis(七):Redis 字符串(String)(python)

    # -*- coding: utf-8 -*- import redis #这个redis不能用,请根据自己的需要修改 r =redis.Redis(host="123.516.74.190 ...