Estrutura de dados - Lista Ligada[RESOLVIDO]

10 respostas
cido18

Olá a todos,

Estou estudando a apostila de estrutura de dados da Caelum, mas durante a resolução de lista ligada, ao compilar o código ocorre um NullPointerException.

package br.com.fj14.listaLigada;

import br.com.fj14.vetor.Celula;

public class ListaLigada<T>{
	private int totalDeElementos;
	private Celula  primeira;
	private Celula ultima;


	public void adiciona(T t) {
		if(this.totalDeElementos == 0){
			this.adicionaNoComeco(t);
		}else{
		Celula nova = new Celula(t);
		this.ultima.setProxima(nova);
		nova.setAnterior(this.ultima);
		this.ultima = nova;
		this.totalDeElementos++;
		}
		
	}

	public void adiciona(int posicao, T t) {
		if(posicao == 0){
			adicionaNoComeco(t);
		}else if(posicao == this.totalDeElementos){
			this.adiciona(t);
		}else{
			Celula anterior = this.pegaCelula(posicao - 1);
			Celula proxima = anterior.getProxima();
			Celula nova = new Celula(anterior.getProxima(),t);
			nova.setAnterior(anterior);
			anterior.setProxima(nova);
			proxima.setAnterior(nova);
			this.totalDeElementos++;
		}
		
	}

	public Object pega(int posicao) {
		return this.pegaCelula(posicao).getElemento();
	}

	public void remove(int posicao) {
		if(!this.posicaoOcupada(posicao)){
			throw new IllegalArgumentException("Posição não existe");
		}
		if(posicao ==0){
			this.removeDoComeco();
		}else if (posicao == this.totalDeElementos - 1){
			this.removeDoFim();
		}else{
			Celula anterior = this.pegaCelula(posicao - 1);
			Celula atual = anterior.getProxima();
			Celula proxima = atual.getProxima();
			anterior.setProxima(proxima);
			proxima.setAnterior(anterior);
		
			this.totalDeElementos --;
		}
	}

	public int tamanho() {
		return this.totalDeElementos;
	}


	public boolean contem(T t) {
		Celula atual = this.primeira;
		while(atual !=null){
			if(atual.getElemento().equals(t)){
				return true;
			}
			atual = atual.getProxima();
		}
		return false;
	}

	
	public void adicionaNoComeco(T t) {
		if(this.totalDeElementos == 0){
			Celula nova = new Celula(t);
			this.primeira = nova;
			this.ultima = nova;
		}else{
			Celula nova = new Celula(this.primeira,t);
			this.primeira.setAnterior(nova);
			this.primeira = nova;
		}
		this.totalDeElementos++;
	}

	
	public void removeDoComeco() {
		if(!this.posicaoOcupada(0)){
			throw new IllegalArgumentException("Posição não encontrada");
		}
		this.primeira = this.primeira.getProxima();
		this.totalDeElementos --;
		if(this.totalDeElementos ==0){
			this.ultima = null;
		}
	}

	public void removeDoFim() {
		if(!posicaoOcupada(this.totalDeElementos - 1)){
			throw new IllegalArgumentException("Posição não encontrada");
		}
		if(this.totalDeElementos == 1){
			this.removeDoComeco();
		}else{
			Celula penultima  =  this.ultima.getAnterior();
			penultima.setProxima(null);
			this.ultima = penultima;
			this.totalDeElementos--;
		}
	}
	
	private boolean posicaoOcupada(int posicao){
		return posicao >= 0 && posicao < this.totalDeElementos;
	}
	
	private Celula pegaCelula(int posicao){
		if(!posicaoOcupada(posicao)){
			throw new IllegalArgumentException("Posição não encontrada");
		}
		Celula atual = this.primeira;
		for(int i = 0; i < posicao; i++){
			atual = atual.getProxima();
		}
		return atual;
	}

	public String toSring(){
		if(this.totalDeElementos == 0){
			return "[]";
		}else{
			StringBuilder builder = new StringBuilder("[");
			Celula atual = this.primeira;
			while (atual != null){
				builder.append(atual.getElemento());
				builder.append(", ");
				atual = atual.getProxima();
			}
			builder.append(atual.getElemento());
			builder.append("]");
			return builder.toString();
		}
	}
}

E o teste :

package br.com.fj14.listaLigada;

public class TesteListaLigada {
	public static void main(String[] args) {
		ListaLigada lista = new ListaLigada();
		// teste adiciona
		lista.adiciona(0,"Rafael");
		lista.adiciona(1,"Paulo");
		System.out.println(lista.toSring());
		//saida [Rafael, Paulo]
		
		System.out.println(lista.tamanho());		
	}
}

Pelo debug que fiz, no metodo toString() da classe Lista Ligada, depois do while a variável atual fica com o valor null, mas não consegui entender o porque.

Desde já agradeço.

10 Respostas

giuliasousa

hey Cido, aparentemente o que acontece é que ao dar um atual = atual.getProxima() no último elemento do array ele vai pra null, pois o elemento atual é !=null então ele entra no while, mas o próximo é null porque ele é o último elemento da lista, assim, quando vc da atual.getElemento() logo depois do while gera a exceção, já que atual é null ele não consegue fazer um getElemento().

cido18

giuliasousa agradeço por ter respondido, acredito então que esteja faltando alguma linha na apostila, pois , fui fazendo de acordo com que estava escrito.Mas ainda não sei como popular o atributo próximo, tem alguma ideia?

giuliasousa

Você não deve popular o atributo próximo, não seria interessante alterar uma estrutura num método toString, vc pode antes de fazer atual.getElemento(), testar se o atual != null.

cido18

Mas o problema seria que esse objeto sempre estaria como null e sempre iria cair na mesma situação.
Obrigado pela resposta, vou fazer um tratamento para isso.

giuliasousa

realmente, depois do while o atual sempre estaria null, porque fazer um append de atual.getElemento() depois do while? todos os elementos já teriam sido impressos, você apenas precisaria fechar o “]”.

cido18

Teoricamente para pegar o ultimo elemento, de acordo com a explicação na mesma apostila o “for” iria da ultima posição -1, mas como estou usando o StringBuilder provavelmente ele já faria isso.

giuliasousa

Não entendi o que vc quis dizer com o for, cido, o problema não era a NullPointer no toString? E o que o StringBuilder já faria?

cido18

Desculpa viajei mesmo, o problema continua é de NullPointer, mas a minha dúvida é se realmente preciso fazer na linha 146:

builder.append(atual.getElemento());

Sinceramente não vi muita utilidade nessa parte, mas como estava no exercicio acabei fazendo.

giuliasousa

Então, cido, voce nao precisa fazer isso porque no teste while(atual!=null) vc percorre todos os elementos da lista até ela acabar, quando vc pega um proximo == null é sinal de que a lista acabou.

cido18

Putz agora eu entendi o que você disse(desculpa a demora), aquela linha não serve para nda já que estou fazendo isto no while…
Desculpa ai, mas entendi :smiley:

Criado 19 de abril de 2012
Ultima resposta 20 de abr. de 2012
Respostas 10
Participantes 2