Implementando Lista Encadeada em Java

Estava implementando uma lista encadeada em Java e estava com muitas duvidas no código.A minha primeira duvida é quanto a variavel proximo ser do tipo Lista eu entendi que é para guardar a referencia para o proximo objeto mas nao entendi porque as variaveis primeiro e ultimo da classe ListaAluno nao foram criadas na classe lista e sim na outra ja que elas sao do tipo Lista.Ainda nao terminei a de implementar,parei por aqui porque estou com duvida nessa parte.

public class Lista {

private int nota;
private Lista proximo;

public void setNota(int nota){
this.nota = nota;

}
public void getNota(){

 return this.nota;

}

public void setProximo(Lista proximo){

 this.proximo = proximo;    
}

}

public class AlunoLista {
int qntelementos;
Lista primeiro,ultimo; //

public  AlunoLista(){
    this.qntelementos = 0;
    this.primeiro = null;
    this.ultimo = null;
}

public void inserirNoComeco(int nota){
    if(this.qntelementos == 0){
        
        Lista novo = new Lista();
        novo.setNota(nota);
        novo.setProximo(primeiro); //
        this.primeiro = novo; //
    }
    else{
 
        
        Lista novo2 = new Lista();
        novo2.setNota(nota);
        novo2.setProximo(primeiro);    
        primeiro = novo2;
    }
    
}

}

Bom dia,

“nao entendi porque as variáveis primeiro e ultimo da classe ListaAluno nao foram criadas na classe lista e sim na outra ja que elas sao do tipo Lista”

No caso, você terá uma ListaAlunos e um tipo Lista

Lista primeiro, guardara a primeira lista de alunos
Lista ultimo, guardara a ultima lista de alunos

Que estranho, acredito que esse Lista deveria ser aluno não lista. Mas vamos seguindo kkk

No caso esses 2 elementos é para indicar ao algoritmo quando for percorrido por onde começar e onde terminar.

Respondendo a pergunta, a lista ligada funciona da seguinte maneira.

Temos uma variável que sempre aponta para o próximo, depois do primeiro as seguintes apontaram para os anteriores, e o ultimo apontara para ele mesmo. Pode-se visualizar como um trem com diversos vagões.

O motivo de temos o primeiro e o ultimo, novamente é para indicar por onde começar e onde terminar na hora da iteração.

Proximo proximo = primeiro.getProximo,
agora como temos a referencia do proximo basta fazer

proximo.getProximo;

não teríamos como capturar a referencia do próximo se não houve-se o marco inicial que seria o primeiro, pois só ele referencia para o próximo ponto. O motivo de AlunoLista não ter o primeiro e o ultimo é que está classe não é a gerenciadora da lista ligada e sim a Lista. Lista sabe ou deveria saber o que não é o caso, a quantidade de itens na lista,
ultimo e primeiro.

No caso, o que está te levando a confusão é AlunoLista esta gerenciando a lista ligada, em vez de que somente Lista fizesse esse trabalho.

A implementação da Apostila da Caelum é mais clara

https://www.caelum.com.br/apostila-java-estrutura-dados/listas-ligadas/#5-23-exercicios-lista-ligada

bora >>

1 curtida

Nao entendi o this.primeiro eu sei a funcao do this que e dizer que é o objeto que esta sendo utilizado mas qual a funcao de usar this nesse caso especifico sendo que so existe um elemento primeiro na lista?

public void inserirNoComeco(int nota){
if(this.qntelementos == 0){

        Lista novo = new Lista();
        novo.setNota(nota);
        novo.setProximo(primeiro); 
        this.primeiro = novo; // porque this
    }

Passei o metodo faltando boa parte dele aqui vai ele completo

public void inserirNoComeco(int nota){
if(this.qntelementos == 0){

        Lista novo = new Lista();
        novo.setNota(nota);
        novo.setProximo(primeiro); // 
        this.primeiro = novo; // porque this
    }
    else{
    
        
        
        
        Lista novo2 = new Lista();
        novo2.setNota(nota);
        novo2.setProximo(primeiro);    
        primeiro = novo2;
    }
    
}
Lista novo = new Lista(); // cria lista
    novo.setNota(nota); // insere nota
    novo.setProximo(primeiro); //insere o proximo que no caso é ele mesmo, assim como ele é o primeiro da lista tem que se referenciar a si próprio como próximo*
    this.primeiro = novo; // insere na primeira posição o novo. Com o this fica mais claro que está pegando o elemento. Mas é opcional*

Somente é necessário o this quando a 2 variáveis com mesmo nome.
fica claro a utilização do this em um construtor, mas você pode acabar se habituando a essa utilização que é bem mais clara*

1 curtida

obrigado @jonathan.sky agora sim eu entendi

Opa, qualquer coisa estamos a ordem. Na época que estava estudando esse foi o algoritmo que mais me bugou, Os demais são mais de boa para entender. bora >>> 0/

@jonathan.sky uma variavel em que o tipo dela é o mesmo da classe por exemplo

class Lista {
int valor;
Lista var; // armazena endereço de memoria ou um objeto do tipo lista?e qual seria a funcao de amrazenar um objeto?

}

Lista var, Isso é chamado de variável de referencia, o que ela faz até o momento é limitar um espaço na memoria e demarca a mesma para aceitar somente referencia para objeto Lista, porém ainda não foi instanciada.

Se estivesse em ambiente C e utiliza-se printf na var, teriamos sujeira de memoria, pois mostraria o valor que está armazenada naquele endereço.

Lista var = new Lista( ); //sobrescreve dados do endereco que está sendo referenciada pelo var como novo objeto Lista da classe Lista

Seguindo a pergunta:
// armazena endereço de memoria ou um objeto do tipo lista?e qual seria a função de armazenar um objeto?

Exemplo:

public class Lista {
public String msg = “Hello My Friend”;

   public void getMsg( ) { //método da classe Lista que printa o nome no terminal
      System.out.printf(msg");
    }
}

Lista var = new Lista( ); //endereço onde var referencia contém objeto Lista, Então posso usar seus métodos.
Lista var2 = new Lista( );

var.getMsg( ); //Hello My Friend
var2.getMsg( ); // Hello My Friend

só como bónus, as duas variáveis referenciam objetos diferentes, então se alteramos a var

var.nome = "ULA";

var.getMsg( ); //ULA
var2.getMsg( );//Hello My Friend

porém, se alteramos a referencia do var2 para referenciar a mesma referencia de var

var2 = var;

var.getMsg( ); //ULA
var2.getMsg( );//ULA

var2 está com o atributo de instancia modificado também, pois eles estão fazendo a mesma referencia.

@jonathan.sky tava lendo a apostila que voce me passou e fiquei com uma duvida.A duvida ta na linha this.ultima.setProx();

public class Celula {
private Celula proxima;
private Object elemento;
public Celula(Celula proxima, Object elemento) {
this.proxima = proxima;
this.elemento = elemento;
}
public Celula(Object elemento) {
this.elemento = elemento;
}
public void setProxima(Celula proxima) {
this.proxima = proxima;
}
public Celula getProxima() {
return proxima;
}
public Object getElemento() {
return elemento;
}
}

public class ListaLigada {
private Celula primeira;
private Celula ultima;
private int totalDeElementos;
}
public void adiciona(Object elemento) {
if (this.totalDeElementos == 0) {
this.adicionaNoComeco(elemento);
} else {
Celula nova = new Celula(elemento);
this.ultima.setProxima(nova); o ultima é uma variavel da classe listaligada e a duvida é ela pode usar uma variavel da classe celula??
this.ultima = nova;
this.totalDeElementos++;
}
}

@jonathan.sky variavel nao,metodo da classe celula,porque setprox é um metodo da classe celula