我正在创建一个应用程序,用户在其中键入任务列表,并将该列表保存到数组中。数组中的每个任务都是Assignment
类的实例。但是,我意识到在java中,在创建数组之后无法向数组添加元素。所以,我做的是创建了一个名为tasks
的数组,它由许多空值组成:Assignment[]tasks = {null, null, null, null, null, null, null, null, null, null, null, null};
。当我想向数组添加任务时,我只需用对象替换下一个空值。但是,我还需要一个只有任务的数组,没有空值。所以我为所有非空元素创建了一个名为full_tasks
的数组:
for (Assignment task: tasks) {
if (task != null) {
realLength += 1;
}
}
Assignment[] full_tasks = new Assignment[realLength];
for (int i=0; i <= full_tasks.length - 1; i++) {
full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
}
现在,full_tasks
数组应该是所有任务的数组,其中没有一个是null,对吧?但是,当我运行应用程序时,它无法启动活动,它说的错误是由空指针异常引起的:
Caused by: java.lang.NullPointerException: Attempt to read from field 'java.lang.String com.example.lb.homeworkappv11.Assignment.name' on a null object reference
at com.example.lb.homeworkappv11.Schedule.sortTasks(Schedule.java:64)
错误指向的行是:
full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
我仍然不完全确定null对象引用是什么,但我认为这意味着full_tasks
数组中的一个元素为null。这是对的吗?如果是,我该怎么做才能确保full_tasks
数组仅 tasks
数组中的非空元素?
非常感谢你!
编辑:作业类的构造函数是:
public Assignment(String name, int days, int time) {
this.name = name;
this.days_due = days;
this.time = time;
this.toSortBy = "nothing";
}
答案 0 :(得分:2)
null
引用只是null
。在您的代码中tasks[i].name
,您尝试在name
上致电tasks[i]
,因此tasks[i]
为null
。
我可以想到一个场景,你的代码肯定会抛出NullPointerException
。
所以,我假设你的任务数组看起来像这样:
tasks = [task0, null, task2, task3, null, task5]
然后full_tasks
的大小为4,但
for (int i=0; i <= full_tasks.length - 1; i++) {
full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
}
会在i == 1
后立即抛出 NPE ,因为tasks[1]
为null
。
因此,如果您希望仅使用非空任务填充full_tasks
,请确保获得tasks
的正确索引。
答案 1 :(得分:1)
这就是我的想法
您只是找到不是null
的数字元素。你不知道null
中存在的数组在哪里。
假设只有第一个元素是null
。因此realLength
将为7.后一个for
循环从i=0
运行到i=7
。当i=0
时,tasks[i].name
尝试访问第一个元素的name
字段;但你的第一个元素恰好是null。出现问题的地方。
<强>解决方案:强>
有许多解决方案。我能想到的最有效的方法是使用ArrayList
。
要使用数组,您应该存储非null
的所有元素的索引。这是单向的。
这是另一个:
for (Assignment task: tasks) {
if (task != null) {
realLength += 1;
}
}
Assignment[] full_tasks = new Assignment[realLength];
int count = 0;
for (Assignment task: tasks) {
if (task != null) {
full_tasks[count] = new Assignment(task.name, tasks.days_due, task.time);
count++;
}
}
答案 2 :(得分:0)
似乎&#34;任务&#34;列表是空的。确保它已填充或进行空检查 喜欢:
if(tasks[i] !=null) {
full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
}
答案 3 :(得分:0)
您可以认为null不存在,例如当您尝试获取task.name
,其中任务 null 时,您会收到错误,因为您尝试从某些人那里获取名称甚至不存在的东西。
实际上你的代码现在正在做的是检查原始数组中有多少非空项,并尝试将数组中的前n项额外提取到新数组。
即。如果列表为{null, null, non-null, non-null}
,则它有2个非空项,但是您的代码错误地提取前{2}项的列表{null, null}
编辑,实际执行您想要的操作:
ArrayList<Assignment> fullTaskList = new ArrayList<Assignment>();
for (Assignment task: tasks) {
if (task != null) {
fullTaskList.add(task);
}
}
//optional
Assignment[] fullTasks = fullTaskList.toArray(new Assignment[fullTaskList.size()]);
答案 4 :(得分:0)
您的代码中存在问题:
(tasks[i].name, tasks[i].days_due, tasks[i].time).
虽然您正在计算实际大小,但两者之间可能存在一些空值,导致它从列表任务[i]中获取空对象。
解决此问题的一个好主意是使用List而不是Array。可以根据需要增加或减少列表,只需添加或删除对象类型的项目即可。例如:
List<Assignment> list = new ArrayList<>();
Assignment assignment1 = new Assignment(etc.);
list.add(assignment1);
list.get(0) //-> returns the Assignment object that you added.
然后,您可以使用list.size()
来获取大小,以了解有多少项目,或删除最后一项。您可以毫无问题地将新项目添加到列表中。
答案 5 :(得分:0)
您似乎正在尝试将tasks
数组复制并压缩到full_tasks
数组中(删除空元素),但由于您正在访问tasks[i]
,因此这部分不正确在第二个循环中,不检查它是否为空。
而不是:
for (int i=0; i <= full_tasks.length - 1; i++) {
full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
}
你可以这样写:
for (int i = 0, f = 0; i < tasks.length; i++) {
if (tasks[i] != null) {
full_tasks[f] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
f++;
}
}
但是再次解决原始问题,关于无法向数组中添加任何元素的事实,我建议使用ArrayList
而不是简单的数组。这样您就可以使用ArrayList.add(assignment)
添加项目,然后使用ArrayList.remove(index)
重新删除它们。