当前位置: 代码网 > it编程>编程语言>Java > Java List接口add方法怎么用?常见插入异常及解决方案

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

2026年08月04日 Java 我要评论
java中有一个用于表示线性表的list接口,其中包含add、addall和set三个用于向表中插入元素的方法,笔者近期在编码过程中,遇到了一些问题,并总结了一些注意事项,mark一下。·

java中有一个用于表示线性表的list接口,其中包含addaddallset三个用于向表中插入元素的方法,笔者近期在编码过程中,遇到了一些问题,并总结了一些注意事项,mark一下。

·add方法

list接口中的add方法有如下两种重载方式:

  • ① boolean add(e e);
  • ② 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对象,然后向其中添加了5个字符串,然后打印输出,下图为运行效果:

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

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行的顺序,此时的执行结果如下图:

由于arraylist对象初始化时不包含任何元素,因此size的值为0,此时向下标为4的位置添加元素时,就会抛出异常。

注意,即使在创建list对象时指定了初始化大小,依旧会有以上问题,对于上面的代码,如果将第11行修改为:list<string> stringlist = new arraylist<>(100),并不能避免出现上面的异常。

·addall方法

addall方法和add方法类似,区别在于addall方法可以一次插入一个集合中的多个元素,重载方法也有两种:

  • ① boolean addall(collection<? extends e> c);
  • 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);
    }

代码运行结果如下:

如果将上述代码中的第19行修改为:stringlist.addall(1, stringset),则会抛出异常,运行效果如下图:

最后需要注意的是,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,然后在12的位置设置元素,由于新创建的list在位置12是没有元素的,因此替换失败,抛出异常,结果如下:

对于某些应用,就需要以乱序的方式插入到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方法替换为有用的数据,此时就可以乱序插入了,程序执行结果如下:

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com