从零开始学Java之List集合有哪些特性?——List集合
一. List集合简介
概述
List本身是一个接口,该接口继承自Collection接口,它有两个常用的实现子类ArrayList和LinkedList。从功能特性上来看,List是有序、可重复的单列集合,集合中的每个元素都有对应的顺序索引,我们可以通过该索引来访问指定位置上的集合元素。默认情况下,List会按元素的添加顺序给元素设置索引,第一个添加到List集合中的元素索引为0,第二个为1,后面依此类推。所以List的行为和数组几乎完全相同,它们都是有序的存储结构。另外List集合中允许有重复的元素,甚至可以有多个null值。
但是如果我们是使用数组来添加和删除元素,就会非常的不方便。比如从一个已有的数组{'A', 'B', 'C', 'D', 'E'}中删除索引为2的元素,这个“删除”操作实际上是把'C'后面的元素依次往前挪一个位置;而“添加”操作实际上是把指定位置以后的元素依次向后挪一个位置,腾出位置给新加入的元素。针对这两种操作,使用数组实现起来都会非常麻2. 类关系
我们来看看List接口的类关系,如下图所示:烦。所以在实际应用中,我们增删元素时,一般都是使用有序列表(如ArrayList),而不是使用数组。
类关系
我们来看看List接口的类关系,如下图所示:
从这个类关系中我们可以看到,List接口继承了Collection接口,并且有ArrayList、LinkedList、Vector等子类,其中Vector现在已经不太常用了,所以我们重点掌握ArrayList和LinkedList就行。
3. 常用API方法
在List接口中定义了子类的一些通用方法,如下所示:
● boolean add(E e):在集合末尾添加一个数据元素;
● boolean add(int index, E e):在集合的指定索引出添加一个数据元素;
● E remove(int index):删除集合中指定索引的元素;
● boolean remove(Object e):删除集合中的某个元素;
● E get(int index):获取集合中指定索引出的元素;
● int size():获取集合的大小(包含元素的个数)。
以上这些方法,就是我们在开发时比较常用的几个方法,大家需要记住哦。
4. List对象创建方式
List作为一个接口,我们通常不能直接new List来创建其对象,在Java中给我们提供了如下两种创建List对象的方式:
● 通过多态方式创建:new List的某个子类,比如new ArrayList()等;
● 通过List.of()方法创建:of()方法可以根据给定的数据元素快速创建出List对象,但该方法不接受null值,如果传入null会抛出NullPointerException异常。
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class Demo01 {
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,5,7,9);
//该方式不能传入null参数,否则会产生NullPointerException异常
//List<Integer> list4 = List.of(1,3,5,7,9,null);
}
}
List集合遍历方式
很多时候,我们都会对集合进行遍历操作,也就是要把集合中的每个元素挨个的取出来,以下是几种常用的集合遍历方式:
● 普通for循环配合get(索引值)方法进行遍历:这种遍历方式实现起来代码较为复杂,且get(int)取值方法只对ArrayList比较高效,但对LinkedList效率较低,索引越大时访问速度越慢。
● 增强for循环进行遍历:我们也可以使用增强for循环进行遍历,该方式比普通for循环实现起来更为简洁。
● 使用Iterator迭代器进行集合遍历:不同的List对象调用iterator()方法时,会返回不同实现的Iterator对象,该Iterator对象对集合总是具有最高的访问效率。
import java.util.Iterator;
import java.util.List;
public class Demo02 {
public static void main(String[] args) {
//List遍历方式一,普通for循环:
List<String> list = List.of("java", "大数据", "壹壹哥");
for(int i=0;i<list.size();i++) {
System.out.println("遍历方式一,值="+list.get(i));
}
//List遍历方式二,迭代器:
Iterator<String> it = list.iterator();
while(it.hasNext()){
//取出下一个值
String value = it.next();
System.out.println("遍历方式二,值="+value);
}
//List遍历方式三,增强for循环:内部会自动使用Iterator
for(String item:list) {
System.out.println("遍历方式三,item="+item);
}
}
}
上面提到的Iterator对象,有两个常用方法,如下所示:
● boolean hasNext():该方法用于判断集合中是否还有下一个元素;
● E next():该方法用于返回集合的下一个元素。
虽然使用Iterator遍历List集合的代码,看起来比使用索引较复杂,但Iterator遍历List集合的效率却是最高效的方式。
另外只要是实现了Iterable接口的集合类,我们都可以直接使用for each增强循环来遍历。在增强for循环中,Java编译器会自动把for each循环变成基于Iterator方式的遍历方式。
6. List与数组的转换方式
其实List与Array数组在很多地方都是比较相似的,比如都可以根据索引对数据元素进行遍历取值等操作。因为存在着这种相似之处,所以在List和数组之间是可以互相转换的,即List集合可以转成数组,数组也可以转成List集合。
6.1 List转数组
一般情况下,List转数组有如下几种方式:
● toArray()方法:该方法会返回一个Object[]数组,但该方法会丢失类型信息,在实际开发时较少使用;
● toArray(T[])方法:传入一个与集合的数据元素类型相同的Array,List会自动把元素复制到传入的Array中;
● T[] toArray(IntFunction<t[]> generator)方法:函数式写法,这是Java中的新特性,后面壹哥会单独讲解。
import java.util.List;
/**
* @author Sun
*/
public class Demo03 {
public static void main(String[] args) {
List<String> list = List.of("java", "大数据", "壹壹哥");
// List转数组方式一:返回一个Object[]数组
Object[] array = list.toArray();
for (Object val : array) {
System.out.println("方式一,value="+val);
}
// List转数组方式二,给toArray(T[])传入与数组元素类型相同的Array,如果数组类型与集合数据元素类型不匹配则会产生如下异常:
// java.lang.ArrayStoreException: arraycopy: element type mismatch:
//can not cast one of the elements of java.lang.Object[] to the type of the destination array, java.lang.Integer
String[] array2 = list.toArray(new String[list.size()]);
for (String val : array2) {
System.out.println("方式二,value="+val);
}
// List转数组方式三:返回一个String[]数组
String[] array3 = list.toArray(String[]::new);
for (String val : array3) {
System.out.println("方式二,value="+val);
}
}
}
在本案例中,第一种实现方式是调用toArray()方法直接返回一个Object[]数组,但这种方法会丢失类型信息,所以开发是很少使用。
第二种方式要给toArray(T[])方法传入一个与集合数据元素类型相同的Array,List内部会自动把元素复制到传入的Array数组中。如果Array类型与集合的数据元素类型不匹配,就会产生”java.lang.ArrayStoreException: arraycopy: element type mismatch: can not cast one of the elements of java.lang.Object[] to the type of the destination array......“异常。
第三种方式是通过List接口定义的T[] toArray(IntFunction<t[]> generator)方法,这是一种函数式写法,壹哥以后再单独给大家讲解。
6.2 数组转List
反过来,数组也可以转为List集合,一般的方式如下:
● List.of(T...)方法:该方法会返回一个只读的List集合,如果我们对只读List调用add()、remove()方法会抛出UnsupportedOperationException异常。其中的T是泛型参数,代表要转成List集合的数组;
● Arrays.asList(T...)方法:该方法也会返回一个List集合,但它返回的List不一定就是ArrayList或者LinkedList,因为List只是一个接口。
import java.util.Arrays;
import java.util.List;
/**
* @author Sun
*/
public class Demo04 {
public static void main(String[] args) {
// 数组转List的方式一:List.of()返回一个只读的集合,不能进行add/remove等修改操作。
List<Integer> values = List.of(1,8,222,10,5);
for (Integer val : values) {
System.out.println("方式一,value="+val);
//该集合是一种只读的集合,不能在遍历时进行增删改等更新操作,只能进行读取操作,
//否则会产生java.lang.UnsupportedOperationException异常
//values.remove(0);
}
// 数组转List的方式二:Arrays.asList()返回一个只读的集合,不能进行add/remove等修改操作。
List<String> items = Arrays.asList("java","壹壹哥","元宇宙");
for (String item : items) {
System.out.println("方式二,value="+item);
//不可以进行增删改操作
//items.add("sss");
//items.remove(0);
}
}
}
在本案例中,无论我们是通过List.of()方法,还是通过Arrays.asList()方法,都只会返回一个只读的集合。这种集合在遍历时不能进行增删改等更新操作,只能进行读取操作,否则会产生java.lang.UnsupportedOperationException异常。
猜你喜欢LIKE
相关推荐HOT
更多>>servlet底层原理是什么?
1、ServletAPI核心类与接口2、Servlet类处理请求的流程创建servlet类的步骤:创建一个命名为TestServlet继承javax.servlet.http.HttpServlet类详情>>
2023-05-30 10:41:22多线程的优势与劣势分别是什么?
多线程是指在同一个程序中,同时运行多个线程,每个线程都可以独立执行不同的任务,相互之间不会干扰。多线程的优势和劣势如下:优势:提高程序...详情>>
2023-05-30 10:32:12设计模式之生产者与消费者的代码实现
本文主要讲述生产者和消费者模式,文中会使用通俗易懂的案例,使你更好地学习本章知识点并理解原理,做到有道无术。什么是生产者和消费者模式生...详情>>
2023-05-30 10:25:46从零开始学Java之interface接口
一.接口简介简介Java中的接口(interface)类似于是一种特殊的抽象类,它也是众多抽象方法的集合。接口的定义方式、组成部分都与抽象类相似,却比...详情>>
2023-05-29 11:26:17热门推荐
如何进行mysql数据备份?
沸什么是servlet的生命周期?servlet请求处理流程是怎样的?
热servlet底层原理是什么?
热怎样编写java程序?
新多线程的优势与劣势分别是什么?
ssm框架的作用与原理是什么?
设计模式之生产者与消费者的代码实现
接口和抽象类有什么区别?4个方面对比
从零开始学Java之interface接口
从零开始学Java之Java中的内部类是怎么回事?
一分钟带你了解MySQL——基础与介绍
在java中,super关键字怎样使用
什么是事件流以及事件流的传播机制 ?
弹性盒有哪些属性是在父元素身上?