[RESOLVIDO] Como resolver o NullPointerException da Classe abaixo?

Oi, gente! Fiz um exercício e cheguei na solução, mas estou com problemas:

O exercício consiste em determinar os 10 maiores estados brasileiros por extensão territorial. O código funciona e roda. O problema é que quando rodo o JUnity recebo NullPointerException. Hoje, uma pessoa me ensinou a inserir um breakpoint na linhas exibidas pelo JUnity e rodar no modo Debug e o erro de fato apareceu, problema é que não sei como resolver.

O Debug aponta para variáveis nulas dentro da classe State, quando uso a palavra reservada this e no método compare. Só que não sei como contornar esse problema.

Alguém pode me ajudar? Desde já, muito obrigada!

Seguem os códigos.

Obs: Cada código está em um arquivo diferente:

Código 1 - Classe Principal:

package challenge;

import challenge.SimpleReadCSV;
import challenge.State;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


public class Main{
	static List<State> state = new ArrayList<State>();
	static Double[] Uf = new Double[27];
	static String[] name = new String[27];
	
	public List<State> listThe10largestStatesInBrazil() {
		State st = new State();
		
		for(int i = 0; i < 10; i++) {
			state.add(new State(Uf[i], name[i]));
		}
		
		Collections.sort(state, st.reversed());
		
		return state;
	}
	
	
	public static void StateResults() {
		System.out.printf("-------------------------------------------------\n");
		System.out.printf(" Os 10 maiores estados brasileiros - (1.000 Km\u00B2)\n");
		System.out.printf("-------------------------------------------------\n");
		System.out.printf("| Nº | Nome do Estado            | \006rea         |\n");
		System.out.printf("-------------------------------------------------\n");
		for(int i = 0; i < 10; i++){
			System.out.printf("| %02d | %-18s\t | %s\t|\n", 
					i+1, state.get(i).getName(), 
					state.get(i).getUf().toString().replace(".", ","));
		}System.out.printf("-------------------------------------------------\n");
	}
	
	public static void main(String[] args) {
		Main objectMain = new Main();
		String doc = "EstadosBrasileirosPorOrdemAlfabética.csv";
		SimpleReadCSV rdFile = new SimpleReadCSV(doc);
		rdFile.reading();
		
		Uf = rdFile.getUf();
		name = rdFile.getName();
		objectMain.listThe10largestStatesInBrazil();
		StateResults();
	}

}

Código 2 - Classe State:

package challenge;

import java.util.Comparator;

public class State implements Comparator<State>{
	
	private Double Uf;
	private String name;
	
	State() {
		
	}
	
	public State(Double Uf, String name) {
		this.Uf = Uf;
		this.name = name;
	}
	
	public Double getUf() {
		return Uf;
	}
	
	public void setUf(Double uf) {
		Uf = uf;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}

	@Override
	public int compare(State o1, State o2) {
		return Double.compare(o1.getUf(), o2.getUf()); //Essa linha é exibida no debugg com erro.
	}	

}

Sobre a classe State, o debug aponta esses erros e eu não sei o que posso fazer para resolver isso:
ErroBreakPoint

Código 3 - Classe SimpleReadCSV:

package challenge;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;

public class SimpleReadCSV {
	private String arquivo;
	private String[] column;
	private String[] name = new String[27];
	private Double[] Uf = new Double[27];
	
	public SimpleReadCSV(String arquivo) {
		this.arquivo = arquivo;
	}
	
	public String getArquivo() {
		return arquivo;
	}
	
	public void setArquivo(String arquivo) {
		this.arquivo = arquivo;
	}
	
	public String[] getColuna() {
		return column;
	}
	
	public void setColumn(String[] column) {
		this.column = column;
	}
	
	public String[] getName() {
		return name;
	}
	
	public void setNome(String[] name) {
		this.name = name;
	}
	
	public Double[] getUf() {
		return Uf;
	}
	
	public void setUf(Double[] Uf) {
		this.Uf = Uf;
	}
	
	public void reading() {
		
		try {
			System.setIn(new FileInputStream(new File(arquivo)));
		} catch(FileNotFoundException e) {
			System.out.println("Arquivo não encontrado!");
		}
		
		int i = -1;
		Scanner read = new Scanner(System.in);
		String line;
		while(read.hasNext()) {
			i++;
			line = read.nextLine();
			column = line.split(";");
			name[i] = column[0];
			Uf[i] = Double.parseDouble(column[1].replace(",", "."));
		}
		read.close();
	}
}

Arquivo CSV:

EstadosBrasileirosPorOrdemAlfabética.csv (468 Bytes)

Vc não está inicializando o seu List com coisa alguma. Veja se o .size() é maior ou igual a 10.

Vc leu os dados em um objeto e parece q ficaram por la…

1 curtida

Dei uma refatorada no seu código pra ficar mais fácil.

Classe State:

package challenge;

public class State {

    private double area;
    private String name;

    public State(double area, String name) {
        this.area = area;
        this.name = name;
    }

    public double getArea() {
        return area;
    }

    public String getName() {
        return name;
    }
}

Classe SimpleReadCSV:

package challenge;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class SimpleReadCSV {

    public List<State> reading(String arquivo) throws IOException {
        return reading(new File(arquivo));
    }

    public List<State> reading(File arquivo) throws IOException {
        return reading(new FileInputStream(arquivo));
    }

    public List<State> reading(InputStream arquivo) throws IOException {
        List<State> estados = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(arquivo))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] columns = line.split(";");
                String nome = columns[0];
                double area = Double.parseDouble(columns[1].replace(",", "."));
                estados.add(new State(area, nome));
            }
        }
        return estados;
    }
}

package challenge;

Classe Main:

package challenge;

import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Main {

    public static void main(String[] args) {
        Main objectMain = new Main();
        objectMain.execute();
    }

    public void execute() {
        try {
            SimpleReadCSV rdFile = new SimpleReadCSV();
            List<State> todosEstados = rdFile.reading("EstadosBrasileirosPorOrdemAlfabética.csv");
            List<State> maioresEstados = listThe10largestStatesInBrazil(todosEstados);
            stateResults(maioresEstados);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void stateResults(List<State> estados) {
        System.out.printf("-------------------------------------------------\n");
        System.out.printf(" Os 10 maiores estados brasileiros - (1.000 Km\u00B2)\n");
        System.out.printf("-------------------------------------------------\n");
        System.out.printf("| Nº | Nome do Estado            | Área         |\n");
        System.out.printf("-------------------------------------------------\n");
        for (int i = 0; i < estados.size(); i++) {
            State estado = estados.get(i);
            System.out.printf("| %02d | %-18s\t | %s\t|\n",
                              i + 1,
                              estado.getName(),
                              String.valueOf(estado.getArea()).replace(".", ","));
        }
        System.out.printf("-------------------------------------------------\n");
    }

    public List<State> listThe10largestStatesInBrazil(List<State> estados) {
        Comparator<State> comparadorArea = new Comparator<State>() {
            @Override
            public int compare(State a, State b) {
                return Double.compare(a.getArea(), b.getArea());
            }
        };

        Collections.sort(estados, comparadorArea.reversed());

        return estados.subList(0, 10);
    }
}

Saída:

-------------------------------------------------
 Os 10 maiores estados brasileiros - (1.000 Km²)
-------------------------------------------------
| Nº | Nome do Estado            | Área         |
-------------------------------------------------
| 01 | Amazonas         	 | 1570,7	|
| 02 | Pará              	 | 1247,6	|
| 03 | Mato Grosso       	 | 903,3	|
| 04 | Minas Gerais      	 | 587,5	|
| 05 | Bahia             	 | 564,6	|
| 06 | Mato Grosso do Sul	 | 357,1	|
| 07 | Goiás             	 | 340,0	|
| 08 | Maranhão          	 | 332,0	|
| 09 | Rio Grande do Sul 	 | 281,7	|
| 10 | Tocantins         	 | 277,6	|
-------------------------------------------------

Sim, inicializei minha lista:

static List<State> state = new ArrayList<State>();

Quando verifico o tamanho, ele exibe 10.

Me expressei mal.
O q vc carrega nessa list parece não inicializado. Tanto que vc tem um null pointer exception

Um vetor de 27 posições não inicializa as posições individuais

Então, como inseriria um valor individual em cada posição da minha lista? A única forma que conheço foi a que usei…

Entendo que assim insiro individualmente.

Tentei, na classe State, criar as variáveis como vetores, mas sempre que passo os argumentos pelo construtor, ele passa o vetor inteiro e não a posição individual. Então voltei a deixar como está…

Pensei em inserir os 27 itens na lista e então exibir apenas 10, mas o problema é que o .size() precisa ser 10 para os parâmetros usados no teste do JUnity.

Estou pensando em reescrever todo o código, mas ainda não sei muito bem como proceder para isso não aconteça de novo…

ok eu acho que eu entendi

o seu codigo rola um uso e abuso de atributos estaticos e vc passa de um para o outro.

por exemplo, vc nao usa o retorno do metodo listThe10largestStatesInBrazil

mas vamos por partes: eu acabei de voltar do dentista e nao quero executar essas classes pra ver o que acontece. vc pode mostrar detalhes da exception?

eu tenho ideias sobre como vc poderia deixar o codigo mais simples e facil de entender, por exemplo o seu SimpleReadCSV poderia ter construtor simples e vc poderia ter um unico metodo

public List<State> read(String doc) throws java.io.FileNotFoundException

o que isso te ajuda:

  1. minimiza estados globais - que sao um parto para fazer testes
  2. vc pode ler quantos arquivos quiser
  3. te obriga a tratar esse erro
  4. vc pode inclusive ter outros metodos capazes de ler um Iterator<String> que por acaso a classe Scanner implementa e eh otimo para testes.

agora o listThe10largestStatesInBrazil poderia tambem receber um List<State> e vai agir como um filtro onde vc aplica primeiro o Collections.sort e só depois pega os primeiros 10 elementos (fica a sugestao de talvez receber o 10 via parametro e o metodo ser generico) porem vc precisa definir o que fazer se a sua lista tiver menos de 10 (uma exception talvez?)

de uma refletida. eu tive dificuldade de entender as indas e vindas de alguns dados.

Alias o seu objeto State representa um estado? o que é Uf ? surface area? vc pode dar um nome descritivo e talvez nao usar java.lang.Double e sim um double comum (java faz autobox para o tipo wrapper quando preciso eu ACHO)

de qq forma mostre a exception que vc tem

1 curtida

Deu uma olhada como eu escrevi sua classe SimpleReadCSV ?

Oi, perdão pela demora em responder! :blush:
Sim, eu vi! Obrigada! Mas estou tentando entender o que você fez no código… Por que você criou três métodos com o mesmo nome na classe SimpleReadCSV?

 public List<State> reading(String arquivo) throws IOException {
        return reading(new File(arquivo));
    }

    public List<State> reading(File arquivo) throws IOException {
        return reading(new FileInputStream(arquivo));
    }

    public List<State> reading(InputStream arquivo) throws IOException {
//mais código aqui
}

Perdão?! é que estou aprendendo a lidar com listas e arquivo de entradas há pouco… :grin:

Isso se chama sobrecarga de métodos.
Dessa forma eu posso chamar o método reading usando um objeto do tipo String, do tipo File ou do tipo InputStream.

O que importa é o conteúdo desse método:

   public List<State> reading(InputStream arquivo) throws IOException {
        List<State> estados = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(arquivo))) {
            String line;
            while ((line = reader.readLine()) != null) {
                String[] columns = line.split(";");
                String nome = columns[0];
                double area = Double.parseDouble(columns[1].replace(",", "."));
                estados.add(new State(area, nome));
            }
        }
        return estados;
    }

Ele lê o arquivo CSV passado pôr parâmetro e retorna uma lista de objetos do tipo State.

1 curtida

Muito obrigada pela ajuda! Embora eu não tenha usado a solução que você passou, pois um novo entendimento do desafio apareceu aqui, seu código me ajudou a entender como usar a interface Comparator, que ainda não conseguia entender muito bem!
Mais uma vez, muito obrigada pela ajuda! :blush: :grinning:

Obrigada pela explicação, mas resolvi de outra forma! :blush: :grinning: