ユーザーがタスクのリストを入力し、そのリストが配列に保存されるアプリを作成しています。配列内の各タスクは、Assignment
クラスのインスタンスです。しかし、Javaでは、配列の作成後に要素を配列に追加することは不可能であることを認識しました。そこで、私はtasks
という配列を作成しましたこれは多くのnull値で構成されています:Assignment[]tasks = {null, null, null, 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ではありませんよね?ただし、アプリを実行すると、アクティビティを起動できません。エラーメッセージは、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
配列の要素の1つがnullであることを意味します。それは正しいでしょうか?そうであれば、full_tasks
配列がonlytasks
配列のnull以外の要素であることを確認するにはどうすればよいですか?
どうもありがとうございます!
編集:割り当てクラスのコンストラクター関数は次のとおりです。
public Assignment(String name, int days, int time) {
this.name = name;
this.days_due = days;
this.time = time;
this.toSortBy = "nothing";
}
null
参照は、まさにnull
です。あなたのコードではそれはtasks[i].name
であり、ここでtasks[i]
でname
を呼び出そうとすると、tasks[i]
はnull
になります。
あなたのコードが間違いなくNullPointerException
をスローする、私が考えることができる1つのシナリオがあります。したがって、タスク配列は次のようになると想定します。
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
はnull
であるため、tasks[1]
になるとすぐに[〜#〜] npe [〜#〜]がスローされます。
したがって、full_tasks
にnull以外のタスクのみを入力する場合は、tasks
の正しいインデックスを取得していることを確認してください。
これが私の考えです
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++;
}
}
tasks
配列をfull_tasks
配列にコピーして圧縮しようとしているようです(null要素を削除しています)。2番目のループでtasks[i]
にnullかどうかをチェックせずにアクセスしているため、これは部分的に正しくありません。 。
の代わりに:
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)
を使用してそれらを再度削除することができます。
「タスク」リストが空のようです。値が入力されていることを確認するか、次のようにnullチェックを配置します。
if(tasks[i] !=null) {
full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
}
Nullは存在しないものと考えることができます。たとえば、task.name
を取得しようとすると、タスクはnullとなり、エラーが発生します。さえ存在しません。
実際、コードが現在実行しているのは、元の配列内のnull以外の項目の数を確認し、配列の最初のn項目を余分に抽出して新しい配列に変換することです。
つまり、リストが{null, null, non-null, non-null}
の場合、2つのnull以外のアイテムがありますが、コードは{null, null}
である最初の2つのアイテムのリストを誤って抽出します
編集、実際にやりたいことを行うには:
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()]);
あなたのコードの問題はここにあります:
_(tasks[i].name, tasks[i].days_due, tasks[i].time).
_
実際のサイズを数えていますが、その間にいくつかのnull値が含まれている可能性があり、そのため、リストtasks [i]からnullオブジェクトが取得されます。
これを解決するには、配列の代わりにリストを使用することをお勧めします。リストは必要に応じて増減できます。オブジェクトタイプのアイテムを追加または削除するだけです。例えば:
_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()
を使用してサイズを取得し、そこにあるアイテムの数を確認したり、最後のアイテムを削除したりできます。リストに新しいアイテムを追加しても問題はありません。