我的简单 List Set Map Data Structure 代码未编译,引发异常

My simple List Set Map Data Structure code is not compile, Exception raised

这是我尝试 运行 下面的代码时在控制台中打印出来的内容,我不知道为什么代码没有编译,而且我没有看到任何问题。请帮忙!!谢谢

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 2 out of bounds for length 2 at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64) at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70) at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:266) at java.base/java.util.Objects.checkIndex(Objects.java:359) at java.base/java.util.ArrayList.set(ArrayList.java:441) at Example.main(Example.java:9)

import java.util.*;

public class Example {

    public static void main(String[] args) {
        List<String> bucketList = new ArrayList<>();
        bucketList.add("Visit Alaska");
        bucketList.add("Visit Hawaii");
        bucketList.set(2, "Visit Japan");

        for (String list : bucketList) {
            System.out.print(list);
        }

        Set<String> codingJournal = new LinkedHashSet<>();
        codingJournal.add("2/10/2021");
        codingJournal.add("5/8/2021");
        codingJournal.add("7/31/2021");

        for (String journal : codingJournal) {
            System.out.print(journal);
        }

        Map<String, ArrayList<String>> BU = new HashMap<>();
        ArrayList<String> languages = new ArrayList<>();
        languages.add("Java");
        languages.add("SQL");
        ArrayList<String> classes = new ArrayList<>();
        classes.add("CS520");
        classes.add("CS669");
        BU.put("Languages", languages);
        BU.put("Classes", classes);

        System.out.println(BU.get("Classes"));

    }
}

你可以看看异常的实际内容:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 2 out of bounds
...
...
java.base/java.util.ArrayList.set(ArrayList.java:441) at Example.main(Example.java:9)

如果您查看 Example.java class 中的行号 9,您会发现,您在 [=21] 索引中设置了 "Visit Japan" =] 共 bucketList 个:

bucketList.set(2, "Visit Japan");

刚刚引入 bucketList 并且在该调用之前只添加了 2 个元素:

List<String> bucketList = new ArrayList<>();
bucketList.add("Visit Alaska");
bucketList.add("Visit Hawaii");

这是为什么?

如果您查看 ArrayList 的实现,您就会明白原因。当你初始化一个ArrayList时,这就是所谓的:

public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

其中 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 是:

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = new Object[0];

如果调用了add(Object obj),则在ArrayList class中找到以下实现:

public boolean add(E e) {
    ++this.modCount;
    this.add(e, this.elementData, this.size);
    return true;
}

其中 this.add(...) 表示:

private void add(E e, Object[] elementData, int s) {
    if (s == elementData.length) {
        elementData = this.grow();
    }

    elementData[s] = e;
    this.size = s + 1;
}

所以我想你可以猜到这里发生了什么。您的列表在初始化和之后修改时是一个默认大小为0的数组,实际上,随着新元素的添加,数组大小为grow()。让我们看看这个 grow() 做了什么:

private Object[] grow() {
    return this.grow(this.size + 1);
}

private Object[] grow(int minCapacity) {
    return this.elementData = Arrays.copyOf(this.elementData, this.newCapacity(minCapacity));
}

所以,你看,它创建了一个具有新大小容量的新数组。

因此,当您添加前两个元素后,您就创建了一个长度为 2 的数组供您使用。这就是为什么每当您尝试设置 bucketList.set(2, "Visit Japan"); 时,您都在尝试访问长度为 2 的零索引数组的索引号 2,这显然不是绑定的。因此 ArrayIndexOutOfBoundException 被抛出。