Join objects inside collection of different objects

1

How do I "merge" or concatenate an object into a collection of different objects? I've tried redoing but it always gives the same error.

public class Prova {
    private String titulo;

    private int numQuestoes;

    private String disciplina;

    private double notaMaxima;

    private String professor;

    private int id = 0;

    Questao[] questao = new Questao[100];


    static int contador = 0;


  Prova(String titulo, int numQuestoes , String disciplina , double  notaMaxima , String professor){


    contador++;
    this.id = Prova.contador;

  this.titulo = titulo;
  this.numQuestoes = numQuestoes;
  this.disciplina = disciplina;
  this.notaMaxima = notaMaxima;
  this.professor = professor;
  }

  public String getTitulo() {
    return titulo;
  }

  public void setTitulo(String titulo){
      this.titulo = titulo;
  }

  public int getNumQuestoes() {
    return numQuestoes;
  }

  public void setNumQuestoes(int numQuestoes) {
    this.numQuestoes = numQuestoes;
  }

  public String getDisciplina() {
    return disciplina;
  }

  public double getNotaMaxima() {
    return notaMaxima;
  }

  public String getProfessor() {
    return professor;
  }

  public int getId() {
    return id;
  }

  public void mostrarProva() {
    System.out.println("ID: "+id);
    System.out.println("Título: "+titulo);
    System.out.println("Número de Questões: "+numQuestoes);
    System.out.println("Disciplina: "+disciplina);
    System.out.println("Nota Máxima: "+notaMaxima);
    System.out.println("Professor: "+professor);



    //System.out.println("\n");
  } 

  public class Questao {
    private int numero;
  //private String item;
    private String enunciado;
    private String resposta;
    static int contador = 0;
    private int id;



    Questao(int numero, String enunciado, String resposta){

    contador++;
    this.id = Questao.contador;

    this.numero = numero;
    this.enunciado = enunciado; 
    this.resposta = resposta;
    }

  public int getNumero(){
    return numero;
  }

  public String getEnunciado(){
    return enunciado;
  }

  public String getResposta() {
    return resposta;
  }

  public int getId() {
    return id;
  }

  public void mostrarQ() {
    System.out.println("ID :"+id);
    System.out.println("Numero : "+numero);
    System.out.println("Enunciado : "+enunciado);
    System.out.println("Resposta : "+resposta);
  }

  }

     public class CadastroDeProvas {

     Prova[] provas = new Prova[100];

     int qtdProvas = 0;
     int qtdQuest = 0;

    void adicionarQuestao (int i, Questao questao){  
         provas[i].questao[qtdQuest] = questao;
          qtdQuest++;
     }

    void imprimir(){ 
      for(int i = 0; i < qtdProvas; i++){
            provas[i].mostrarProva();
      for(int j=0;j < qtdQuest;j++) {
            provas[i].questao[j].mostrarQ();
      }

        }
    }

}

The int i parameter is the position of the vector object of provas[] that concatenated with the vector questao[] will receive the object questao .

 void imprimir(){ 
    for(int i = 0; i < qtdProvas; i++){
            provas[i].mostrarProva();
    for(int j=0;j < qtdQuest;j++) {
            provas[i].questao[j].mostrarQ();
    }

        }
    }

Every time I run the code imprimir() it gives an error in this method, more specifically in the line highlighted below:

provas[i].questao[j].mostrarQ();
public class Questao {
    private int numero;
    //private String item;
    private String enunciado;
    private String resposta;
    static int contador = 0;
    private int id;

The error more specifically:

Exception in thread "main" java.lang.NullPointerException
    at br.ufc.crateus.provas.CadastroDeProvas.imprimir(CadastroDeProvas.java:26)
    at br.ufc.crateus.provas.Principal.main(Principal.java:92)
    
asked by anonymous 09.12.2017 / 15:30

3 answers

0

First, you should better organize your code with indentation and never forget the modifiers public or private , after all, in most cases, package visibility is not what you want. And when you want it, it's always good to put a comment on this ( /* package */ ) to make it clear that you really want package visibility and not just forgot about the visibility modifier, in addition to telling you what other class and method of the same package that method or constructor should be used.

Once this is done, remember that working directly with arrays is torture. Prefer to use lists, Map s, or something else. In mature, modern and well-developed Java projects, it makes little sense to use arrays directly, and when they do appear, it is usually to use varargs , or used with annotations, or because a a particular API that needs to be used produces or consumes arrays, or they are primitive type arrays used that correspond to raw data used in I / O operations, or to accomplish something very simple for which it does not need much sophistication. Outside of these cases, it is rarely a good idea to use arrays directly. And even in those cases, the array is often encapsulated in some other class.

In your case, when using lists, you no longer have to worry about knowing how many questions or how many tests are registered, just see the size of the list. In addition, it eliminates the need to check if certain array positions are null, which even eliminates the NullPointerException you had. It also eliminates the need to keep track of a bunch of crazy counters and all the complexity involved.

Note that you have an array called questao . Now, if the name is in the singular, I would not expect it to be an array. The questoes name would be much better. The name provas is correctly in the plural.

It is also a good idea to add the final modifier to object fields that can not be assigned once the builder is complete.

In addition, the use of changeable variables with the static (global variables) modifier is always an anti-default. One bad thing, a sign that something in your project is wrong. In your case, the variables contador of classes Prova and Questao serve to count the tests and questions, and therefore, it makes sense that they were in class CadastroDeProvas . In fact, in the case of Questao , the id could be replaced by the id of the test and the number of the question in the test.

Finally, if you want to get the description of an object, use the toString() method, which is already implemented satisfactorily for lists. Placing System.out.println directly in the show method prevents you from taking this description and deciding what to do with it, if you want to put it elsewhere. Another alternative would be to work with StringBuilder s.

And to ensure good tunneling, never access a field of type array or list of another class directly. Always do this by a method. E and if method should not export the array or list, but make the desired operation with it. That is, instead of:

provas[i].questao[qtdQuest] = questao;

You would do something like:

provas[i].adicionarQuestao(questao);

However, this still uses provas as if it were an array. In addition, the responsability of adding a question to the test should be in the Prova class, not the CadastroDeProvas class.

That said, let's restructure your classes:

import java.util.ArrayList;
import java.util.List;

public class Prova {
    private final String titulo;

    private final String disciplina;

    private final double notaMaxima;

    private final String professor;

    private final int id;

    private final List<Questao> questoes = new ArrayList<>();

    // Deve ser utilizado apenas pelo método criarProva da classe CadastroDeProvas.
    /* package */ Prova(int id, String titulo, String disciplina, double notaMaxima, String professor) {
        this.id = id;
        this.titulo = titulo;
        this.disciplina = disciplina;
        this.notaMaxima = notaMaxima;
        this.professor = professor;
    }

    public String getTitulo() {
        return titulo;
    }

    public int getNumeroQuestoes() {
        return questoes.size();
    }

    public String getDisciplina() {
        return disciplina;
    }

    public double getNotaMaxima() {
        return notaMaxima;
    }

    public String getProfessor() {
        return professor;
    }

    public int getId() {
        return id;
    }

    public void adicionarQuestao(String enunciado, String resposta) {
        questoes.add(new Questao(this, questoes.size() + 1, enunciado, resposta);
    }

    @Override
    public String toString() {
        return new StringBuilder("ID: " + id
                + "\nTítulo: " + titulo
                + "\nNúmero de Questões: " + getNumeroQuestoes()
                + "\nDisciplina: " + disciplina
                + "\nNota Máxima: " + notaMaxima
                + "\nProfessor: " + professor
                + "\nQuestões: " + questoes);
    }
}
public class Questao {
    private final Prova prova;
    private final int numero;
    private final String enunciado;
    private final String resposta;

    // Deve ser utilizado apenas pelo método adicionarQuestao da classe Prova.
    /* package */ Questao(Prova prova, int numero, String enunciado, String resposta) {
        this.prova = prova;
        this.numero = numero;
        this.enunciado = enunciado; 
        this.resposta = resposta;
    }

    public Prova getProva() {
        return prova;
    }

    public int getNumero() {
        return numero;
    }

    public String getEnunciado() {
        return enunciado;
    }

    public String getResposta() {
        return resposta;
    }

    @Override
    public String toString() {
        return "ID da prova: " + prova.getId()
                + "\nNúmero: " + numero
                + "\nEnunciado: " + enunciado
                + "\nResposta: " + resposta
    }
}
import java.util.ArrayList;
import java.util.List;

public class CadastroDeProvas {
     private final List<Prova> provas = new ArrayList<>();

     public Prova criarProva(String titulo, String disciplina, double notaMaxima, String professor) {
         Prova p = new Prova(provas.size() + 1, titulo, disciplina, notaMaxima, professor);
         provas.add(p);
     }

     @Override
     public String toString() { 
         return provas.toString();
     }
}

Finally, your Prova class also seems to confuse two different concepts. A concept is the model of proof, with the statement of the questions. Another thing is the response given by each student in the test he received and the grade obtained. However, in order to change that I would need to know a few more things about your project.

    
09.12.2017 / 22:03
0

You could solve it better using arraylist, if you do not know it yet.

Now if you are doing a job for college and / or travel then.

First, array does not accept different types of values. If you make an array to insert integers, you can not success- fully add String or Double values.

    
09.12.2017 / 22:03
0

OK .. I think I understand what you need.

Where did you write:

void imprimir(){ 
    for(int i = 0; i < qtdProvas; i++){
            provas[i].mostrarProva();
    for(int j=0;j < qtdQuest;j++) {
            provas[i].questao[j].mostrarQ();
    }

        }
    }

Did you mean ... Something like:

  • Test 1 + test data 1;

    • Test1.Queue1 + question data 1
    • Test1.Questao2 + question data 2
    • Test1.Questao2 + question data 3
    • Test1.QuestaoN + question data N
  • Test 2 + test data 2;

    • (etc)

Correct me, if I'm wrong. I'm still trying to figure out your need.

If so, do something like

public class Questao{
//todos os campos da classe + construtores, getters and setters necessarios

@Override
public String toString(){
    return String.format(
  "ID : %s\n"+
  "Numero : %d \n" + 
  "Enunciado : %s \n" +
  "Resposta : %s \n", id, numero, enunciado, resposta );
}

}

Now set the Test:

public class Prova{
    //todos os campos, construtores, getters e setters

    private List<Questao> questoes = new Arraylist<>();

    @Override
    public String toString(){
        String saida = 
            String.format("ID: %d \n" + 
                    "Título: %s \n" + 
                    "Número de Questões: %d \n" +
                    "Disciplina: %s \n" +
                    "Nota Máxima: %f \n" + 
                    "Professor: %s \n",
                    id, numQuestoes, disciplina, notaMaxima, professor 
            );
        for(Questao q : questoes){
            saida += q.toString();
        }
    }
}

Now, just run into the embrace:

public class TestProfile {

 List<Prova> provas = new Arraylist<>();

 int qtdProvas = 0;
 int qtdQuest = 0;

void adicionarQuestao (int i, Questao questao){  
     provas.getQuestoes.add(questao);
     //será necessário algum ajuste aqui
 }

void imprimir(){ 
   for(Prova p : provas){
        System.out.println(p);
   }
}

Implicitly, the println method will call the toString method inherited from the Object class (parent of all java classes) and will bring the verbalization you want.

    
10.12.2017 / 00:38