首页 > 编程语言 >Java中List接口的学习

Java中List接口的学习

时间:2024-09-20 10:23:37浏览次数:7  
标签:Java ArrayList 元素 List 指定 接口 列表 Vector 线程

List接口


目录

ArrayList

ArrayList就是 动态数组,它提供了
①动态的增加和减少元素
②实现了ICollection和IList接口
③灵活的设置数组的大小

ArrayList是一个其容量能够动态增长的动态数组。它继承了AbstractList,实现了List、RandomAccess, Cloneable, java.io.Serializable。
基本的ArrayList,长于随机访问元素,但是在List中间插入和移除元素时较慢。同时,ArrayList的操作不是线程安全的!
一般在单线程中才使用ArrayList,而在多线程中一般使用Vector或者CopyOnWriteArrayList。

特点

  1. 动态数组:ArrayList是Java中的一个可调整大小的数组实现。它能够根据需要自动扩展其容量,因此被称为动态数组。

  2. 线程不安全:ArrayList不是线程安全的,这意味着如果多个线程同时访问同一个ArrayList实例,并且至少有一个线程从结构上修改了列表,那么它必须保持外部同步。

  3. 基于索引的快速访问:ArrayList实现了List接口,允许基于索引的快速访问,包括随机访问。这意味着,无论列表有多大,通过索引访问任何元素的速度都很快。

  4. 允许空值和重复值:ArrayList可以包含null元素,并且同一个值可以在列表中重复多次。

  5. 自动扩容:当ArrayList中的元素数量超过其当前容量时,它会自动扩容以容纳更多的元素。默认情况下,扩容的大小为当前容量的1.5倍,但具体实现可能会根据JVM和JDK版本有所不同。

底层数据结构

ArrayList的底层数据结构是动态数组(Dynamic Array),也常被称作可变数组(Resizable Array)。本质上,它是一个基于数组实现的列表,但它可以动态地改变其大小。在ArrayList中,数组用于存储元素,并且当数组达到其容量时,ArrayList会创建一个新的、更大的数组,并将旧数组的元素复制到新数组中,从而增加其容量。

常用方法

  1. add(E e):向列表的末尾添加指定的元素。

  2. add(int index, E element):在列表的指定位置插入指定的元素。如果索引超出范围,会抛出IndexOutOfBoundsException

  3. remove(int index):移除列表中指定位置的元素,并返回被移除的元素。如果索引超出范围,会抛出IndexOutOfBoundsException

  4. remove(Object o):移除列表中首次出现的指定元素(如果存在)。如果列表不包含该元素,则列表不会改变。

  5. get(int index):返回列表中指定位置的元素。如果索引超出范围,会抛出IndexOutOfBoundsException

  6. set(int index, E element):用指定元素替换列表中指定位置的元素,并返回原来位置的元素。如果索引超出范围,会抛出IndexOutOfBoundsException

  7. size():返回列表中的元素数量。

  8. isEmpty():如果列表不包含元素,则返回true

  9. clear():移除列表中的所有元素,使列表变为空列表。

  10. contains(Object o):如果列表包含指定的元素,则返回true

  11. indexOf(Object o):返回列表中首次出现的指定元素的索引,如果列表不包含该元素,则返回-1。

  12. lastIndexOf(Object o):返回列表中最后一次出现的指定元素的索引,如果列表不包含该元素,则返回-1。

LinkedList

Java中的LinkedList是一个重要的集合类,具有一系列独特的特点、底层数据结构以及丰富的常用方法。

特点

  1. 基于双向链表LinkedList内部使用双向链表数据结构来存储元素,这意味着每个元素都包含指向列表中前一个和后一个元素的引用。这种结构使得在链表中进行插入和删除操作非常高效。

  2. 动态扩容:与ArrayList类似,LinkedList也具有动态扩容的能力,尽管其扩容方式不同于基于数组的ArrayList。由于LinkedList是基于链表的,其“扩容”实际上是通过在链表中添加新的节点来实现的,而不是像ArrayList那样需要复制整个数组。

  3. 线程不安全LinkedList不是线程安全的,如果多个线程同时访问一个LinkedList实例而没有适当的同步,那么它可能会表现出非预期的行为。在多线程环境下,如果需要线程安全的数据结构,可以考虑使用Collections.synchronizedList(List<T> list)方法将LinkedList包装成线程安全的列表,或者使用ConcurrentLinkedQueue等并发集合。

  4. 允许空值和重复值:与ArrayList相同,LinkedList也允许存储null元素,并且同一个值可以在列表中重复出现多次。

  5. 高效的插入和删除:由于LinkedList是基于链表的,因此在链表的头部、尾部或任意位置插入和删除元素都非常高效,只需要修改相关节点的引用即可,时间复杂度通常为O(1)。

  6. 较低的查询性能:与ArrayList相比,LinkedList在查询元素时的性能较低,因为它需要从链表的头部或尾部开始遍历到指定的索引位置。这种遍历方式相对较慢,尤其是当要查找的元素位于链表的中间或末尾时。

底层数据结构

LinkedList的底层数据结构是双向链表。每个节点(Node)都包含三个部分:存储的数据元素、指向前一个节点的引用(prev)以及指向后一个节点的引用(next)。这种结构使得在链表中进行插入和删除操作变得非常高效,因为只需要修改相邻节点的引用即可。

常用方法

LinkedList提供了丰富的常用方法,以下是其中一些主要的方法:

  1. 添加元素

    • add(E e):将指定元素添加到列表的末尾。
    • add(int index, E element):在列表的指定位置插入指定元素。
    • addFirst(E e):将指定元素插入此列表的开头。
    • addLast(E e):将指定元素添加到此列表的末尾(相当于add(E e))。
  2. 删除元素

    • remove():移除并返回此列表中的最后一个元素。
    • remove(int index):移除列表中指定位置的元素。
    • remove(Object o):移除列表中首次出现的指定元素(如果存在)。
    • removeFirst():移除并返回此列表的第一个元素。
    • removeLast():移除并返回此列表的最后一个元素。
  3. 访问元素

    • get(int index):返回列表中指定位置的元素。
    • getFirst():返回此列表的第一个元素。
    • getLast():返回此列表的最后一个元素。
  4. 修改元素

    • set(int index, E element):用指定元素替换列表中指定位置的元素。
  5. 检查

    • isEmpty():如果列表不包含元素,则返回true
    • contains(Object o):如果列表包含指定的元素,则返回true
  6. 遍历

    • 可以使用for-each循环、迭代器(Iterator)或列表迭代器(ListIterator)来遍历LinkedList
  7. 其他

    • size():返回列表中元素的数量。
    • clear():移除列表中的所有元素。
    • toArray():返回包含列表中所有元素的数组。

LinkedList的这些方法使得它非常适合于需要频繁进行插入和删除操作的场景,但在需要频繁查询元素的场景下可能不是最佳选择。

Vector(过时)

Java中的Vector是一个基本的、广泛应用的数据结构,它具有一系列独特的特点、底层数据结构以及丰富的常用方法。以下是关于Vector的详细解答:

特点

  1. 动态扩容

    • Vector的容量可以根据需要自动增长。当元素数量超过了当前容量时,Vector会自动增加容量以容纳更多的元素。
  2. 线程安全

    • Vector是线程安全的,即多个线程可以同时访问和修改Vector的内容。这是通过在每个方法上添加synchronized关键字来实现的,但这也可能导致性能下降。
  3. 存储任意类型元素

    • Vector可以存储任意类型的对象,包括基本类型的包装类对象。
  4. 有序性

    • Vector中的元素是按照插入顺序进行存储的,可以根据索引位置来访问和修改元素。
  5. 支持随机访问

    • 由于Vector中的元素是按照索引顺序存储的,因此可以通过索引来快速访问和修改元素。
  6. 可以进行遍历和搜索

    • Vector提供了多种方法来遍历和搜索元素,如使用Iterator迭代器或使用contains()方法进行元素搜索。

底层数据结构

  • Vector的底层数据结构是一个对象数组(Object[])。这意味着Vector可以存储任何类型的对象。当Vector中的元素数量超过其当前容量时,它会创建一个更大的数组,并将现有元素复制到新数组中,这个过程被称为扩容。类似地,当从Vector中删除元素时,如果Vector的大小变得远小于其容量,则Vector会缩小为适当的大小,以节省内存。

常用方法

Vector提供了丰富的常用方法来操作其元素,以下是一些主要的方法:

  1. 添加元素

    • add(E e):在Vector末尾添加指定的元素。
    • add(int index, E element):在Vector的指定位置插入指定的元素。
    • addElement(E obj):同add(E e),但在较老的Java版本中更为常见。
  2. 删除元素

    • remove(int index):移除Vector中指定位置的元素。
    • remove(Object o):移除Vector中指定元素的第一个匹配项(如果存在)。
    • removeAll(Collection<?> c):从Vector中移除包含在指定Collection中的所有元素。
    • removeElement(Object obj):同remove(Object o),但在较老的Java版本中更为常见。
  3. 访问元素

    • get(int index):返回Vector中指定位置的元素。
    • elementAt(int index):同get(int index),但在较老的Java版本中更为常见。
  4. 修改元素

    • set(int index, E element):用指定元素替换Vector中指定位置的元素。
  5. 检查

    • isEmpty():如果Vector不包含元素,则返回true
    • contains(Object o):如果Vector包含指定的元素,则返回true
  6. 遍历

    • 可以使用for-each循环、Iterator迭代器或ListIterator来遍历Vector。
  7. 其他

    • size():返回Vector中元素的数量。
    • capacity():返回Vector的当前容量。
    • clear():从Vector中移除所有元素。

综上所述,Java中的Vector是一个功能强大的数据结构,适用于需要线程安全、动态扩容以及频繁索引操作的应用场景。然而,在单线程环境下或对性能有较高要求时,可能需要考虑使用其他数据结构如ArrayList

Stack(过时)

Java中的Stack是一种遵循先进后出(LIFO,Last In First Out)原则的数据结构,它是Java集合框架的一部分,并且继承自Vector类。以下是关于Java中Stack的特点、底层数据结构以及常用方法的详细解答:

特点

  1. 先进后出原则:Stack的核心特性是先进后出,即最后加入的元素会最先被移除。
  2. 继承自Vector:Stack类继承自Vector类,因此它继承了Vector的所有方法,但Stack通过限制Vector的某些操作来确保其作为栈的行为。
  3. 线程安全:由于Stack继承自Vector,并且Vector是线程安全的,因此Stack也是线程安全的。然而,这种线程安全性可能会导致在单线程环境下性能下降。
  4. 动态扩容:与Vector一样,Stack也支持动态扩容,当元素数量超过当前容量时,会自动增加容量以容纳更多元素。

底层数据结构

Stack的底层数据结构是通过数组实现的,具体来说,它继承自Vector,而Vector是通过动态数组实现的。这意味着Stack内部也使用数组来存储元素,并且当元素数量超过数组容量时,会进行扩容操作。

常用方法

Stack类提供了一系列用于操作栈的常用方法,以下是一些主要的方法及其说明:

方法名称 描述
push(E item) 将元素压入栈顶。如果栈已满,则抛出StackOverflowError异常(注意:这与EmptyStackException不同,后者是在栈为空时尝试弹出元素时抛出的)。
pop() 移除栈顶元素,并返回该元素。如果栈为空,则抛出EmptyStackException异常。
peek() 返回栈顶元素,但不从栈中移除它。如果栈为空,则抛出EmptyStackException异常。
empty() 测试栈是否为空。如果栈为空,则返回true;否则返回false
search(Object o) 返回对象在栈中的位置(从栈顶开始计数,位置为1)。如果栈不包含该对象,则返回-1
size() 返回栈中元素的数量。
toArray() 将栈转换为一个数组,包含栈中的所有元素。

需要注意的是,由于Stack继承自Vector,它还继承了Vector的一些方法,如addaddElementremoveremoveAllElementscontains等。然而,在使用这些方法时需要谨慎,因为它们的行为可能与栈的先进后出原则不完全一致。例如,addaddElement方法将元素添加到栈的末尾(即栈底),而不是栈顶。因此,在大多数情况下,应该使用Stack特有的push方法来添加元素。

综上所述,Java中的Stack是一个功能强大的栈实现,它提供了丰富的方法来操作栈,并且具有线程安全性和动态扩容的特点。然而,在使用时需要注意其先进后出的原则以及与其他集合类(如Vector)的区别。

标签:Java,ArrayList,元素,List,指定,接口,列表,Vector,线程
From: https://www.cnblogs.com/BingBing-8888/p/18421966

相关文章

  • Java 接口interface
    目录1.定义接口2.实现接口3.多重继承4.抽象方法5.默认方法6.静态方法7.私有方法8.常量在Java中,接口(interface)是一种引用类型,它类似于类(class),但是与类不同的是,接口不能包含任何具体的方法实现(除了默认方法和静态方法之外)。接口定义了一组规则或行为,这些规则由实现该接......
  • 基于Java中的SSM框架实现个人网站管理平台项目【项目源码+论文说明】
    基于java中的SSM框架实现在线个人网站管理平台演示【内附项目源码+LW说明】摘要随着社会及个人社交应用平台的飞速发展,人们的沟通成本逐渐降低,互联网信息的普及也进一步提升了人们对于信息的需求度,通过建立个人网站的方式来展示自己的生活信息同时利用平台结交新的朋友,借......
  • c# 笔记 winform添加右键菜单,获取文件大小 ,多条件排序OrderBy、ThenBy,list<double>截取
    Winform右键菜单‌要在C#Winform应用程序中添加右键菜单,‌你可以按照以下步骤操作:‌1.‌创建菜单项‌在Form的构造函数或加载事件中,‌创建ContextMenuStrip控件的实例,‌并为其添加菜单项。‌2.‌绑定到控件‌将ContextMenuStrip控件绑定到需要显示右键菜单的控件上,‌如Panel......
  • Java花店在线销售及数据分析系统的设计与实现
    太原理工花店在线销售及数据分析系统的设计与实现计算机毕业设计案例基于Java的建筑废弃物管理系统基于ASP.NET的OA系统基于Java的企业质量业绩管理系统Java北方民族大学停车场管理系统基于Java的产品成本管理系统基于PHP的学生事务管理系统Java健身俱乐部基于Java......
  • JavaScript语法入门8 JavaScript中的三种引号
    JavaScript中三种引号,分别是单引号(’xx’)、双引号("xx”)、反引号(`xx`)。三种引号中,单引号和双引号的作用是相同的,用于定义字符串。而反引号是一种扩展功能。单引号、双引号单引号、双引号包裹起来的值是字符串,按照惯例,单引号或者双引号必须成对使用,不能交叉使用。 正确示例:letnam......
  • Java 在 GIS 领域的学习路线?
    Java是一门广泛应用于企业级开发的编程语言,而GIS则是一种常用于地理信息处理和分析的技术。将Java与GIS结合起来,可以在企业级应用中实现更多的功能和业务需求,且在实际领域越来越广泛。Java在GIS中重要的作用1、跨平台性Java具有跨平台的特性,Java在地理信息系统(GIS)领域发挥......
  • Java中的设计模式
    最近在做Java笔试题时看到一道关于Java设计模式的,Java的设计模式有很多,这里来给大家普及一下:Java中的设计模式(DesignPatterns)是软件开发人员在软件开发过程中面临的一般至重复出现的问题的解决方案。它们是一种经过分类编目的、可复用的、经过良好测试的设计方案,通常用于解决常......
  • 如何解决"Unknown column 'column_name' in 'field list'"问题
    当遇到"Unknowncolumn'column_name'in'fieldlist'"这类错误时,通常表明SQL查询中引用了一个不存在的列。这类错误通常会给出具体的列名和出错的位置。下面是一些详细的解决步骤:解决方法:检查SQL查询:确认SQL查询中引用的列名是否正确。检查拼写错误或大小写问题。......
  • java重点学习-JVM类加载器+垃圾回收
    12.7类加载器JVM只会运行二进制文件,类加载器的作用就是将字节码文件加载到JVM中,从而让Java程序能够启动起来。类加载器有哪些启动类加载器(BootStrapClassLoader):加载JAVAHOME/jre/lib目录下的库扩展类加载器(ExtClassLoader):主要加载JAVAHOME/jre/lib/ext目录中的类......
  • 基于Java+SpringBoot+Vue的桂林旅游景点导游平台
    前言✌全网粉丝20W+,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌......