ArrayList IndexOutOfBoundsException 尽管在列表的容量内添加



我有以下代码

public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    list.add(1, 555);
}

它用 10 个元素初始化,但我得到异常

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 0   
   at java.util.ArrayList.rangeCheckForAdd(ArrayList.java:612)  
   at java.util.ArrayList.add(ArrayList.java:426)   
   at ListTest.main(ListTest.java:9)

虽然下面的代码工作正常

public static void main(String[] args) {
    List<Integer> list = new ArrayList<>();
    list.add(0, 555);
}

为什么有人可以解释我? 以及如何解决我想将项目放在代码中的第 1、2 或第 5 位的问题?

它由 10 个元素初始化

不,不是。它初始化时的内部缓冲区大小为 10,但这在很大程度上是一个实现细节。列表的大小仍为 0,您可以通过在add呼叫之前打印出list.size()来确认。

区分

"缓冲区中的空间量准备接受更多元素而无需复制"和"列表的大小"非常重要。从add文档中:

抛出:
IndexOutOfBoundsException - 如果index超出范围 ( index < 0 || index > size()

这里size()是 0,1 > 0 ,因此例外。

在假设框架(或编译器)出错之前,您应该始终检查文档。

如何解决我想将项目放在代码中的第 1、2 或第 5 位的问题?

要么需要先添加足够的元素,例如

for (int i = 0; i < 10; i++) {
    list.add(null);
}
list.set(1, 555);
list.set(2, 500);
list.set(5, 200);

请注意,这些是设置操作,而不是添加 - 不清楚您是真的要插入还是修改。

或者,您可能应该改用数组。例如:

int[] array = new int[10];
array[1] = 555;
array[2] = 500;
array[5] = 200;

在这两种情况下,请务必了解索引是从 0 开始的 - 因此list.set(1, 555)更改列表的第二个元素。您希望list.set(0, 555)更改第一个元素。这同样适用于数组。

这是你的答案:public void add(int index, E element) {的代码片段

 if (index > size || index < 0)
        throw new IndexOutOfBoundsException(
        "Index: "+index+", Size: "+size);

基本上,当您执行new ArrayList()时,列表的大小将0 。由于您的指数大于 size ,因此您可以获得IndexOutOfBoundsException

您必须逐渐将元素添加到列表中,列表将自动扩展。

如果你想在特定位置添加某个元素,并且你知道你想要的项目数量的长度;你可以使用一个整数数组,然后把它转换成一个列表,例如

public static void main(String []args){
    Integer []fixedLengthArray = new Integer[5];
    fixedLengthArray[1] = 3;
    List<Integer> intList = Arrays.asList(fixedLengthArray);
    for(int i= 0;i<intList.size();i++)System.out.println("Value of index "+i+":"+intList.get(i));
}

输出将是:

索引值 0:空索引值 1:3索引值 2:空索引值 3:空索引 4 的值:空

虽然该方法被调用add但它实际上是一个插入操作。你实际上是在告诉Java"把它放在列表中的第一项之后",而Java回答"列表中没有第一项"。

public static void main(String[] args) {
     List<Integer> list = new ArrayList<>(1);
     list.add(0, 555);
}

此代码将有所帮助。如果该索引位置有数据,则可以调用此带索引的 add 方法。

首先它会给出编译错误

List<Integer> list = new ArrayList<>(); 

对于ArrayList<Integer>()

and it is initialize with 10 elements 你在哪里做的。?

我们看到的,它不是用 10 个元素初始化的,实际上它是空的,为什么当你尝试在索引1上添加一些东西时,它会在线给出 IndexOutOfBound。

list.add(0, 555);

这是因为你不会从树上得到果实,直到你下这么简单的树。

当你初始化列表的时候,它是一个空列表,可以通过list.size()来验证它会返回0,现在列表中有0个元素并且你正在尝试访问1个索引,所以它给了你异常

来自 Java 文档

void add(int index,
       E element)

在此列表中的指定位置插入指定的元素(可选操作)。将当前位于该位置的元素(如果有)和任何后续元素向移动(将一个元素添加到其索引中)。

Throws:

IndexOutOfBoundsException - 如果索引超出范围(索引<0 || 索引> size())

你的"list"仍然是一个ArrayList所以你不能改变它的索引(通常,数组列表的索引必须从 0 开始)。所以当你把"list.add(1,555)"抛出错误的原因。

只是简单的list.add(555)

代替ArrayList,您可以使用Map,SortedMap,HashMap,TreeMap。这些会将值存储为一对键 - 值。

Hashtable<Integer,Integer> list = new Hashtable<>();
list.put(1, 555);
HashMap<Integer,Integer> list2 = new HashMap<Integer,Integer>();
list2.put(3, 555);

希望这有帮助!

因为,在第二个代码段零是第一个索引。但是在第一个代码段中,一个不是第一个索引,并且您的索引没有任何内存分配。

你必须这样做;

public static void main(String[] args) {
             List<Integer> list = new ArrayList<>();
             list.add(0, 555); //Correct
             list.add(1, 55); //Correct
             list.add(2, 525); //Correct
             list.add(5, 55235); // Not-correct  ! 
        }

创建一个列表,并为所有索引分配默认值。然后使用所需的索引。

public static void main(String[] args) {
             List<Integer> list = new ArrayList<>();
             for(int i=0; i<10; i++)
             {
                 list.add(null);//or default value like -99
              }
             list.add(0, 555); //Correct
             list.add(1, 55); //Correct
             list.add(2, 525); //Correct
             list.add(5, 55235); //correct  ! 
        }

就这样做

int[] array = new int[10];

最新更新