一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

JavaList接口add做法怎么用?常见插入异常及解决方案

时间:2026-08-05 08:43:56 编辑:袖梨 来源:一聚教程网

Java中有一个用于表示线性表的List接口,其中包含

add

addAll

set

三个用于向表中插入元素的方法,笔者近期在编码过程中,遇到了一些问题,并总结了一些注意事项,mark一下。

·add方法

List

接口中的

add

方法有如下两种重载方式:

  1. ① boolean add(E e);

  2. ② void add(int index, E element);

其中:

方法①用于向列表的末尾插入新元素,这也是

List

接口中最常用的插入方法;

方法②则可以在插入操作过程中指定插入的位置,此时,会自动将当前位置及只有的元素后移进行插入,要留意的是,参数

index

的值不可大于当前

list

的容量,即在使用此方法填充一个

list

时,必须以

0

开始依次填充。

可以参考如下的示例代码:

import java.util.ArrayList;import java.util.List;/** * This is the Test program. * @version 2018-04-06 * @author Octopusfly */ public class Main {    public static void main(String[] args) {        List<String> stringList = new ArrayList<>();        stringList.add(0, "string0");        stringList.add(1, "string1");        stringList.add(2, "string2");        stringList.add(3, "string3");        stringList.add(4, "string4");        System.out.println(stringList);    }}

该程序很简单,创建了一个

ArrayList

对象,然后向其中添加了个字符串,然后打印输出,下图为运行效果:

JavaList接口add方法怎么用?常见插入异常及解决方案

将上述代码做细微的修改,如下:

import java.util.ArrayList;import java.util.List;/** * This is the Test program. * @version 2018-04-06 * @author Octopusfly */ public class Main {    public static void main(String[] args) {        List<String> stringList = new ArrayList<>();        stringList.add(4, "string4");        stringList.add(3, "string3");        stringList.add(2, "string2");        stringList.add(1, "string1");        stringList.add(0, "string0");        System.out.println(stringList);    }}

相比修改前的代码,修改后的代码调整了第

12-16

行的顺序,此时的执行结果如下图:

JavaList接口add方法怎么用?常见插入异常及解决方案

由于

ArrayList

对象初始化时不包含任何元素,因此

size

的值为

0

,此时向下标为的位置添加元素时,就会抛出异常。

注意,即使在创建list对象时指定了初始化大小,依旧会有以上问题,对于上面的代码,如果将第

11

行修改为:

List<String> stringList = new ArrayList<>(100)

,并不能避免出现上面的异常。

·addAll方法

addAll

方法和

add

方法类似,区别在于

addAll

方法可以一次插入一个集合中的多个元素,重载方法也有两种:

  1. ① boolean addAll(Collection<? extends E> c);

  2. boolean addAll(int index, Collection<? extends E> c);

首先,对于包含下标参数

index

的方法②,在使用时具有和包含

index

参数的

add

方法同样的限制条件,在执行插入前同样会检查

size

的值,如果指定的

index

值大于

size

值,则会抛出异常,可以参考如下的示例代码:

import java.util.ArrayList;import java.util.HashSet;import java.util.List;import java.util.Set;/** * This is the Test program. * @version 2018-04-06 * @author Octopusfly */public class Main {    public static void main(String[] args) {        Set<String> stringSet = new HashSet<>();        stringSet.add("string1");        stringSet.add("string2");        stringSet.add("string3");        List<String> stringList = new ArrayList<>();        stringList.addAll(0, stringSet);        System.out.println(stringList);    }

代码运行结果如下:

JavaList接口add方法怎么用?常见插入异常及解决方案

如果将上述代码中的第

19

行修改为:

stringList.addAll(1, stringSet)

,则会抛出异常,运行效果如下图:

JavaList接口add方法怎么用?常见插入异常及解决方案

最后要留意的是,

addAll

方法中的集合

c

不可以传入

null

值,否则会有异常。

另外,该方法没有线程安全的设置,当传入的参数

c

正在被另一个线程操作时,其结果是不确定的,参考如下示例代码:

import java.util.ArrayList;import java.util.HashSet;import java.util.List;import java.util.Set;/** * This is the Test program. *  * @version 2018-04-06 * @author Octopusfly */public class Main {    public static void main(String[] args) {        Set<String> stringSet = new HashSet<>();        List<String> stringList = new ArrayList<>();        Thread thread1 = new Thread() {            public void run() {                try {                    for (int i = 0; i < 20; i++) {                        stringSet.add("string" + i);                        Thread.sleep(10);                    }                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            }        };        Thread thread2 = new Thread() {            public void run() {                try {                    Thread.sleep(30);                } catch (InterruptedException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }                stringList.addAll(stringSet);                System.out.println(stringList);            }        };        thread1.start();        thread2.start();    }}

为了更明显地显示此特征,笔者在代码中添加了线程休眠的过程,调整第

22

行和第

34

行的休眠参数将得到不同的输出结果,由此可知,

addAll

方法并不具有线程安全的特性。

·set方法

set

方法直观上根据方法名可以理解为设置

list

中某个位置的元素。但需要注意的是,该方法本质上是一种替换操作,即,要设置某个位置上的元素,这个位置在设置前必须有元素,否则会抛出异常,示例代码如下:

import java.util.ArrayList;import java.util.List;/** * This is the Test program. *  * @version 2018-04-06 * @author Octopusfly */public class Main {    public static void main(String[] args) {        List<String> stringList = new ArrayList<>();        stringList.set(1, "abc");        stringList.set(2, "def");    }}

代码很简单,创建了一个

list

,然后在和的位置设置元素,由于新创建的

list

在位置和

是没有元素的,因此替换失败,抛出异常,结果如下:

JavaList接口add方法怎么用?常见插入异常及解决方案

对于某些应用,就需要以乱序的方式插入到

list

中,笔者的应用场景是:当从数据库中读取数据到

list

中时,要保证

list

中的数据有序,但数据库的存储是不保序,虽然可以读取到内存以后再进行排序,但是考虑到数据量比较大,读取到内存再排序的性能比较低,因此,笔者决定在数据库中存储每条数据的序号,然后读取数据的时候在根据序号直接添加到

list

里面,这个时候就需要以乱序的方式插入

list

,对于上面的异常,可以采取预填充的方式,示例代码如下:

import java.util.ArrayList;import java.util.List;/** * This is the Test program. *  * @version 2018-04-06 * @author Octopusfly */public class Main {    public static void main(String[] args) {        List<String> stringList = new ArrayList<>();        stringList.add(null);        stringList.add(null);        stringList.add(null);        stringList.add(null);        stringList.add(null);        stringList.add(null);        stringList.set(2, "2");        stringList.set(1, "1");        stringList.set(0, "0");        stringList.set(4, "4");        stringList.set(3, "3");        stringList.set(5, "5");        System.out.println(stringList);    }}

程序首先对

list

进行了

null

填充,然后在通过

set

方法替换为有用的数据,此时就可以乱序插入了,程序执行结果如下:

JavaList接口add方法怎么用?常见插入异常及解决方案

总结

热门栏目