首页 > 解决方案 > 我的简单列表集地图数据结构代码未编译,引发异常

问题描述

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

线程“主”java.lang.IndexOutOfBoundsException 中的异常:在 java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64) 在 java.base/jdk.internal 的索引 2 超出了长度 2 的范围。 util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70) 在 java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:266) 在 java.base/java.util.Objects.checkIndex(Objects.java: 359) 在 java.base/java.util.ArrayList.set(ArrayList.java:441) 在 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"));

    }
}

标签: javaarraylistdata-structuresdatasetmaps

解决方案


你可以看看异常实际上是怎么说的:

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)

如果您查看班级中的行号9Example.java您会看到,您设置"Visit Japan"的索引号2bucketList

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

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

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

这是为什么?

如果您查看 的实现ArrayList,您就会明白为什么。当您初始化 anArrayList时,这就是所谓的:

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

在哪里DEFAULTCAPACITY_EMPTY_ELEMENTDATA

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

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

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,事实上,随着新元素的添加,数组 size 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抛出。


推荐阅读