单列集合List

集合List

概述

List集合是开发时以及算法方面用的频率非常高的一种集合,尤其是ArrayList更是被经常使用。

        List本身是一个接口,该接口继承自Collection接口,它有两个常用的实现子类ArrayList和LinkedList。从功能特性上来看,List是有序、可重复的单列集合,集合中的每个元素都有对应的顺序索引,我们可以通过该索引来访问指定位置上的集合元素。默认情况下,List会按元素的添加顺序给元素设置索引,第一个添加到List集合中的元素索引为0,第二个为1,后面依此类推。所以List的行为和数组几乎完全相同,它们都是有序的存储结构。另外List集合中允许有重复的元素,甚至可以有多个null值。

List接口的类关系

        从这个类关系中我们可以看到,List接口继承了Collection接口,并且有ArrayList、LinkedList、Vector等子类,其中Vector现在已经不太常用了,所以我们重点掌握ArrayList和LinkedList就行。

常用API方法

在List接口中定义了子类的一些通用方法,如下所示:

boolean add(E e)在集合末尾添加一个数据元素
boolean add(int index, E e)在集合的指定索引出添加一个数据元素
E remove(int index)删除集合中指定索引的元素
E get(int index)获取集合中指定索引出的元素
boolean remove(Object e)删除集合中的某个元素
int size()获取集合的大小(包含元素的个数)

以上这些方法,就是我们比较常用的几个方法

List对象创建方式

List作为一个接口,我们通常不能直接new List来创建其对象,在Java中给我们提供了如下两种创建List对象的方式:

  • 通过多态方式创建:new List的某个子类,比如new ArrayList()等;

  • 通过List.of()方法创建:of()方法可以根据给定的数据元素快速创建出List对象,但该方法不接受null值,如果传入null会抛出NullPointerException异常。

public static void main(String[] args) {
    //List对象创建方式一
    List<String> list1 = new ArrayList<>();

    List<String> list2 = new LinkedList<>();

    //List对象创建方式二
    List<Integer> list3 = List.of(1,3,2,5,2);
    //方式二不能传递null,否则会报异常
    //List<Integer> list4 = List.of(1,3,2,null,2);
}

 List与数组的转换方式

一般情况下,List转数组有如下几种方式:

  • toArray()方法:该方法会返回一个Object[]数组,但该方法会丢失类型信息,在实际开发时较少使用;

  • toArray(T[])方法:传入一个与集合的数据元素类型相同的Array,List会自动把元素复制到传入的Array中;

  • T[] toArray(IntFunction<T[]> generator)方法:函数式写法,这是Java中的新特性。

List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
String[] array = list.toArray(new String[list.size()]);
 

数组转list

反过来,数组也可以转为List集合,一般的方式如下:

  • List.of(T...)方法:该方法会返回一个只读的List集合,如果我们对只读List调用add()、remove()方法会抛出UnsupportedOperationException异常。其中的T是泛型参数,代表要转成List集合的数组;

  • Arrays.asList(T...)方法:该方法也会返回一个List集合,但它返回的List不一定就是ArrayList或者LinkedList,因为List只是一个接口。

int[] arr = {1, 2, 3, 4, 5};
List<Integer> list = List.of(arr);

String[] array = {"a", "b", "c"};
List<String> list = Arrays.asList(array);

  ArrayList集合

简介

        ArrayList是一个数组队列,位于java.util包中,它继承自AbstractList,并实现了List接口。其底层是一个可以动态修改的数组,该数组与普通数组的区别,在于它没有固定的大小限制,我们可以对其动态地进行元素的添加或删除。

        存储在集合内的数据被称为”元素“,我们可以利用索引来访问集合中的每个元素。为了方便我们操作这些元素,ArrayList给我们提供了相关的添加、删除、修改、遍历等功能。

        因为ArrayList的底层是一个动态数组,所以该集合适合对元素进行快速的随机访问(遍历查询),另外尾部成员的增加和删除操作速度也较快,但是其他位置上元素的插入与删除速度相对较慢。基于这种特性,所以ArrayList具有查询快,增删慢的特点。

底层原理

  1. 利用空参创建的集合,在底层创建一个默认长度为0的数组
  2. 添加第一个元素时,底层会创建一个新的长度为10的数组
  3. 存满时,会扩容1.5倍
  4. 如果一次添加多个元素,1.5倍放不下,则新创建数组的长度以实际为准

LinkedList集合

简介

        LinkedList采用链表结构来保存数据,所以是一种链表集合,类似于ArrayList,也是List的一个子类,位于java.util包中。它的底层是基于线性链表这种常见的数据结构,但并没有按线性的顺序存储数据,而是在每个节点中都存储了下一个节点的地址。

        LinkedList的优点是便于向集合中插入或删除元素,尤其是需要频繁地向集合中插入和删除元素时,使用LinkedList类比ArrayList的效率更高。但LinkedList随机访问元素的速度则相对较慢,即检索集合中特定索引位置上的元素速度较慢。

相关类关系

        LinkedList直接继承自AbstractSequentialList,并实现了List、Deque、Cloneable、Serializable等多个接口。通过实现List接口,具备了列表操作的能力;通过实现Cloneable接口,具备了克隆的能力;通过实现Queue和Deque接口,可以作为队列使用;通过实现Serializable接口,可以具备序列化能力。LinkedList类结构关系如下图所示:

LinkedList集合的特有功能

- 特有方法

public void addFirst(E e)在该列表开头插入指定的元素
public void addLast(E e)将指定的元素追加到此列表的末尾
public E getFirst()返回此列表中的第一个元素
public   E getLast()返回此列表中的最后一个元素
public E removeFirst()从此列表中删除并返回第一个元素
public   E removeLast()从此列表中删除并返回最后一个元素

LinkedList与ArrayList对比 

        与ArrayList相比,LinkedList进行添加和删除的操作效率更高,但查找和修改的操作效率较低。基于这种特性,我们可以在以下情况中使用ArrayList:

  • 需要经常访问获取列表中的某个元素;

  • 只需要在列表的末尾进行添加和删除某个元素。

当遇到如下情况时,可以考虑使用LinkedList:

  • 需要经常通过循环迭代来访问列表中的某些元素;

  • 需要经常在列表的开头、中间、末尾等位置进行元素的添加和删除操作。

总结 

  • List是按索引顺序访问的、长度可变的有序列表;

  • List和Array可以相互转换;

  • ArrayList与LinkedList都是List接口的实现类,都实现了List中所有未实现的方法,但实现的方式有所不同;

  • ArrayList底层的数据结构基于动态数组,访问元素速度快于LinkedList,在快速访问数据时ArrayList的执行效率比较高;

  • LinkedList底层的数据结构基于链表,占用的内存空间较大,但批量插入或删除数据时快于ArrayList。当频繁向集合中插入和删除元素时,使用LinkedList比ArrayList的效率更高。

  • 26
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,有多种单列集合可供使用。其中一些常见的单列集合包括: - ArrayList:ArrayList是基于数组实现的动态数组,可以根据需要自动扩展容量。它允许存储重复元素,并且可以按索引访问元素。 - LinkedList:LinkedList是基于链表实现的集合,它可以高效地进行插入和删除操作。与ArrayList相比,LinkedList在随机访问方面性能较差,但在插入和删除操作方面更加高效。 - HashSet:HashSet是基于哈希表实现的集合,它不允许存储重复元素,并且不保证元素的顺序。HashSet提供了常数时间的插入、删除和查找操作。 - TreeSet:TreeSet是基于红黑树实现的有序集合,它按照元素的自然顺序进行排序,或者根据提供的Comparator进行排序。TreeSet不允许存储重复元素。 - LinkedHashSet:LinkedHashSet是基于哈希表和链表实现的有序集合,它按照元素插入的顺序进行排序。LinkedHashSet允许存储重复元素。 - PriorityQueue:PriorityQueue是基于优先级堆实现的队列,它根据元素的优先级进行排序。PriorityQueue允许存储重复元素,并且提供了常数时间的插入和删除最小元素的操作。 以上是一些常见的单列集合,每种集合都有其特定的用途和适用场景。具体选择哪种集合取决于你的需求和性能要求。 #### 引用[.reference_title] - *1* *2* *3* [Java中Collection单列集合](https://blog.csdn.net/m0_60489526/article/details/119830185)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值