Je crée une application dans laquelle l'utilisateur tape une liste de tâches, et cette liste est enregistrée dans un tableau. Chaque tâche du tableau est une instance de la classe Assignment
. Cependant, j'ai réalisé qu'en Java, il n'est pas possible d'ajouter un élément à un tableau après sa création. J'ai donc créé un tableau appelé tasks
, composé de nombreuses valeurs nulles: Assignment[]tasks = {null, null, null, null, null, null, null, null, null, null, null, null};
. Lorsque je veux ajouter une tâche au tableau, je remplace simplement la valeur null suivante par l'objet. Cependant, j'ai également besoin d'un tableau contenant uniquement les tâches, sans valeur NULL. J'ai donc créé un tableau appelé full_tasks
pour tous les éléments non nuls:
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);
}
Alors maintenant, le tableau full_tasks
devrait être un tableau de toutes les tâches, dont aucune n'est nulle, non? Cependant, lorsque j'exécute l'application, elle ne peut pas lancer l'activité. Une erreur est due à une exception de pointeur 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)
La ligne sur laquelle l'erreur pointe est la suivante:
full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
Je ne suis toujours pas tout à fait sûr de ce qu'est une référence d'objet null, mais je pense que cela signifie qu'un des éléments du tableau full_tasks
est null. Cela serait-il correct? Et si c'est le cas, que puis-je faire pour m'assurer que le tableau full_tasks
est seulement les éléments non nuls du tableau tasks
?
Merci beaucoup!
Edit: la fonction constructeur de la classe d'affectation est:
public Assignment(String name, int days, int time) {
this.name = name;
this.days_due = days;
this.time = time;
this.toSortBy = "nothing";
}
Une référence null
est simplement cette null
. Dans votre code, c'est tasks[i].name
où vous essayez d'appeler name
sur tasks[i]
alors tasks[i]
est null
.
Il y a un scénario auquel je peux penser, où votre code lancerait certainement une NullPointerException
. Donc, je suppose que votre tableau de tâches peut ressembler à ceci:
tasks = [task0, null, task2, task3, null, task5]
Alors full_tasks
aura une taille de 4 mais
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);
}
jette unNPEdès que i == 1
car tasks[1]
est null
.
Donc, si vous voulez remplir full_tasks
avec seulement des tâches non nulles, assurez-vous de disposer des bons index tasks
.
Voici ce que je pense
Vous venez de trouver les éléments numériques qui ne sont pas null
name__. Vous ne savez pas où dans le tableau les null
name __ sont présents.
Supposons UNIQUEMENT que le premier élément est null
name__. Donc realLength
sera 7. La dernière boucle for
va du i=0
au i=7
. Lorsque i=0
, tasks[i].name
tente d'accéder au champ name
du premier élément; mais votre premier élément se trouve être null`. C'est là que les choses vont mal.
Solution:
Il y a plusieurs solutions. Le plus efficace auquel je puisse penser utilise un ArrayList
name__.
Pour vous déplacer en utilisant des tableaux, vous devez stocker les index de tous les éléments qui ne sont pas null
name__. C'est une façon.
Voici un autre:
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++;
}
}
Il semble que vous tentiez de copier et de compacter le tableau tasks
dans le tableau full_tasks
(en supprimant les éléments nuls), mais vous procédez en partie de manière incorrecte, car vous accédez à tasks[i]
dans la deuxième boucle sans vérifier si sa valeur est null.
Au lieu de:
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);
}
vous pourriez écrire quelque chose comme ceci:
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++;
}
}
Mais encore une fois, pour résoudre votre problème initial, concernant le fait que vous ne puissiez ajouter aucun élément à un tableau, je suggère d’utiliser un ArrayList
au lieu d’un simple tableau. Cela vous permet d'ajouter des éléments avec ArrayList.add(assignment)
et de les supprimer à nouveau avec ArrayList.remove(index)
.
On dirait que la liste "tâches" est vide. Assurez-vous qu’il est rempli ou mettez un chèque nul Comme:
if(tasks[i] !=null) {
full_tasks[i] = new Assignment(tasks[i].name, tasks[i].days_due, tasks[i].time);
}
Vous pouvez considérer null comme quelque chose qui n'existe pas, par exemple, lorsque vous essayez d'obtenir task.name
, où tâche est null , vous obtenez une erreur, car vous essayez d'obtenir un nom qui n'existe même pas.
En réalité, votre code vérifie actuellement le nombre d'éléments non nuls dans le tableau d'origine et tente d'extraire les n premiers éléments supplémentaires du tableau dans un nouveau tableau.
c'est-à-dire que si la liste est {null, null, non-null, non-null}
, elle a 2 éléments non nuls, mais votre code extrait à tort la liste des 2 premiers éléments qui sont {null, null}
Modifier, pour réellement faire ce que vous voulez:
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()]);
Le problème dans votre code est ici:
(tasks[i].name, tasks[i].days_due, tasks[i].time).
Bien que vous comptiez la taille réelle, il pourrait y avoir une valeur null entre les deux qui le ferait pour obtenir un objet null à partir de la liste des tâches [i].
Une bonne idée pour résoudre ce problème consiste à utiliser une liste au lieu d'un tableau. Une liste peut être augmentée ou réduite à votre guise, il vous suffit d'ajouter ou de supprimer un élément de votre type d'objet. Par exemple:
List<Assignment> list = new ArrayList<>();
Assignment assignment1 = new Assignment(etc.);
list.add(assignment1);
list.get(0) //-> returns the Assignment object that you added.
Ensuite, vous pouvez utiliser list.size()
pour obtenir la taille, savoir combien d’éléments sont présents ou pour supprimer le dernier élément. Et vous n'auriez aucun problème pour ajouter de nouveaux éléments à la liste.