ArrayList初始化为一个大小,但索引超出范围,大小为零。为什么?

时间:2015-11-08 10:21:18

标签: java arraylist

所以我正在初始化ArrayLists的ArrayList,以便拥有一组可调整大小的数组,以将类的名称保存为Design Analyzer家庭作业的字符串。 ArrayLists初始化为7(对于我正在使用的测试文件),但是当我执行get on element 1时,我得到一个IndexOutOfBounds异常。在检查导致问题的ArrayList的大小(提供者)时,大小为零。我很难理解为什么ArrayList的大小为零,尽管事实上我已将它初始化为我的cls ArrayList(在我的测试用例中为7)的大小。当我在if语句中尝试使用get(i)提供程序时抛出异常,但为什么呢?任何帮助将不胜感激。

public class DesignAnalyzer {

//private Hashtable classSet = new Hashtable();
//ArrayList<Integer> counters = new ArrayList<>();
private static ArrayList<ArrayList<String>> providers;
private static ArrayList<ArrayList<String>> clients;
//private static ArrayList<String>[] 

public static void analyze(ArrayList<Class<?>> cls, String path){
    Package homePkg = Package.getPackage(path.substring(path.lastIndexOf("\\")+1));
    ArrayList<ArrayList<String>> providers = new ArrayList<ArrayList<String>>(cls.size());
    ArrayList<ArrayList<String>> clients = new ArrayList<ArrayList<String>>(cls.size());
    providers.ensureCapacity(cls.size());
    clients.ensureCapacity(cls.size());
    for(int i = 0; i < cls.size(); ++i){
        providers.set(i, new ArrayList<String>());
        clients.set(i, new ArrayList<String>());
    }
    getProviders(cls, homePkg);
    getClients(cls);
    //providers.clear();
}

private static void getProviders(ArrayList<Class<?>> cls, Package pkg){
    for(int i = 0; i < cls.size(); ++i){
        Class<?> spr = cls.get(i).getSuperclass();
        int temp = providers.size(); //should be 7 in test case, but coming back as zero
        if(spr != null && spr.getPackage().toString().equals(pkg.toString()) &&
                !providers.get(i).contains(spr.toString())) // exception being thrown here at i = 1 b/c providers.size is zero...
            providers.get(i).add(spr.toString());

2 个答案:

答案 0 :(得分:1)

您传递给ArrayList构造函数的数字是ArrayList的初始容量,而不是初始大小。初始大小为0,除非您传递给构造函数(不是采用capacity参数的相同构造函数),另一个Collection用于填充ArrayList

在检查providers.get(i)之前,切勿致电providers.size() > i

P.S。

我发现您的代码初始化了providers方法中的ArrayList analyze。但是,您初始化局部变量而不是同名的静态类成员。这意味着getProviders实际上应该抛出NullPointerException而不是IndexOutOfBoundsException(除非您在某些代码中初始化providers静态成员,否则不会包含)。

尝试将analyze方法更改为:

public static void analyze(ArrayList<Class<?>> cls, String path){
    Package homePkg = Package.getPackage(path.substring(path.lastIndexOf("\\")+1));
    providers = new ArrayList<ArrayList<String>>(cls.size());
    clients = new ArrayList<ArrayList<String>>(cls.size());
    ....

答案 1 :(得分:1)

相对于documentation,这样的构造函数执行以下操作:

  

构造一个具有指定初始容量的空列表。

因此,访问它以一个超出范围的异常结束是完全合理的,因为它是空的。 ensureCapacity发生了类似的事情,我发现你在代码中使用了capacity。它只是做了以下事情:

  

如果需要,增加此ArrayList实例的容量,以确保它至少可以容纳由minimum capacity参数指定的元素数。

我猜你误解了ArrayList对于像size这样的容器的含义以及实际上var cells = canvas.selectAll(".cell") .style("position", "relative") .data(treemap) .enter() .append("g") .attr("class", "cell") .style("stroke", "#fff"); cells.append("rect") .attr("x", function(d) { return d.x; }) .attr("y", function(d) { return d.y; }) .attr("width", function(d) { return d.dx; }) .attr("height", function(d) { return d.dy; }) .style("fill", function(d) { return d.children ? null:color(d.parent.name); }); 的含义。虽然后者实际上表明有多少项目,但前者与容器的内部表示有关。如您所知,这样的容器会根据需要动态增长,但如果您知道哪个是预期的最终大小,则可以稍微优化它,作为在访问项目方面的算法中使用的示例。