【问题标题】:2D Array of ArrayLists null exceptionArrayLists 的二维数组空异常
【发布时间】:2013-01-30 13:36:34
【问题描述】:

我有一个具有 ArrayList 属性的类,以及另一个具有该类的二维数组的类:

public class someThingsList {

    private List<someThings> lst;

    public someThingsList () {
        this.lst = new ArrayList<someThings>();
    }
    public addThing(someThings) {
        someThings s = someThings;
        this.lst.add(s);
    }
}

public class x implements y {

    private static someThingsList[][] field;

    public x(int h, int w) {
    x.field = new someThingsList[h][w];
    for (someThingsList[] lst1 : x.field)
        for (someThingsList lst2 : lst1)
            lst2 = new someThingsList();
}

例如,当我有一个新的 x 对象时,将 (2,2) 作为 h 和 w,并尝试这样做

x.fields[0][0].addThing(thing);

我收到 NullPointerException 错误,知道为什么吗?

【问题讨论】:

  • 不相关,但尝试使用前导大写字母命名您的类(和接口),使用前导小写字母命名您的变量。将使someThings s = someThings; 之类的代码更具可读性。
  • 抱歉,这应该是 public addThing(someThings sT) { someThings s = sT; this.lst.add(s); }

标签: java arraylist multidimensional-array


【解决方案1】:

您的代码的问题是,当您为每个循环迭代第二个时,您正在实例化“lst2”的值,它是循环的局部变量,因此它不会影响您的原始数组。一旦你的循环超过 lst2 的值就会丢失。这样您的数组元素保持为空,当您尝试在空对象上调用方法时,它会给出空指针异常。

要理解这一点,请尝试打印 arr[0]。它将打印一个对象类型,然后尝试打印 a[0][0] 这将打印 null。

希望这可以清除您的语法不起作用的原因。

尝试运行这段代码,你就会明白这里出了什么问题。

import java.util.*;
class someThingsList {

    private List<String> lst;

    public someThingsList () {
        this.lst = new ArrayList<String>();
    }
    public void addThing(String someThings ) {
        String s = someThings;
        this.lst.add(s);
    }
}
class Main{

    private static someThingsList[][] field;

 public static void main (String[] args) throws java.lang.Exception
  {
    new Main(3,3);
System.out.println(Main.field[0]);
System.out.println(Main.field[0][0]);
    Main.field[0][0].addThing("thing");
  }

    public Main(int h, int w) {
    Main.field = new someThingsList[h][w];
    for (someThingsList[] lst1 : Main.field)
    {
    System.out.println(lst1);
        for (someThingsList lst2 : lst1){
System.out.println(lst2);
            lst2 = new someThingsList();
System.out.println(lst2);}
    }
    }
}

【讨论】:

    【解决方案2】:

    不幸的是,当您想要对数组进行变异时,您不能对数组使用增强的 for-each 循环。您的示例中的lst2 只是另一个引用(对null),修改它不会修改原始数组。试试这个:

    for(int i = 0; i < field.length; ++i)
        for(int j = 0; j < field[i].length; ++j)
            field[i][j] = new someThingsList();
    

    或者:

    for(int i = 0; i < h; ++i)
        for(int j = 0; j < w; ++j)
            x.field[i][j] = new someThingsList();
    

    事实上,这个问题并不特定于数组。检查以下代码:

    List<String> strings = //...
    
    for(String s: strings) {
        s += "Bar";
    }
    

    尽管看起来好像您正在修改原始 strings 列表,但您几乎没有修改临时 s 变量,该变量在每次循环后重新创建并忽略。

    【讨论】:

    • "x.field[i].length"下红色为:表达式的类型必须是数组类型但解析为int
    • @codeoverflow:刚刚用编译器检查过,它对我有用。也许问题出在其他地方?
    • 在“x.field.length[i]”下我的意思是,对不起,当我将它更改为“x.field.length”时它可以工作,嗯..
    • 现在可以了 ;) 我有“x.field.length[i]”而不是你写的,非常感谢!
    【解决方案3】:

    您已经实例化了数组x.field = new someThingsList[h][w];,但您没有实例化someThingsList 对象。所以 x.field[i][j] 给出NullPointerException

    for(int i = 0; i < x.field.length; i++)
        for(int j = 0; j < x.field[i].length; j++)
            x.field[i][j] = new someThingsList();
    

    【讨论】:

    • "x.field[i].length"下红色为:表达式的类型必须是数组类型但解析为int
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-12-02
    • 2012-02-05
    • 1970-01-01
    • 2011-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多