1. Este site usa cookies. Ao continuar a usar este site está a concordar com o nosso uso de cookies. Saber Mais.

Duvida na LinkedList Java

Discussão em 'Programação' iniciada por _coelhinha_, 15 de Dezembro de 2008. (Respostas: 23; Visualizações: 1697)

  1. _coelhinha_

    _coelhinha_ Power Member

    Boas,

    Tou com um pequeno problema, estou a fazer 1 programa que implementa linkedlist's e quando tento imprimir a lista ela imprime apenas o ultimo elemento que foi inserido sabem-me explicar porque? eu tenho uma classe do tipo Lobo que tem como metodos o nome e o ano e o toString depois noutra classe, classe principal do programa, crio o Lobo e ainda crio 1 lista do tipo Lobo onde insiro as coisas e é lá que tento imprimir mas como disse isto imprime sempre a ultima entrada...será dos metodos nome e ano?? Obrigado. :)
     
  2. Baderous

    Baderous Banido

    Podes mostrar como estás a fazer a inserção e o printing da lista?
     
  3. _coelhinha_

    _coelhinha_ Power Member

    Construtor:
    this.lobo = new Lobo ();
    this.pos = new LinkedList <Lobo> ();

    Um dos metodos da classe lobo (o do ano é igual):
    public String nome (){
    System.out.print("Introduza nome: ");
    Scanner nomeLeitor = new Scanner(System.in);
    return nome = nomeLeitor.next();
    }

    Inserçao dos dados:
    public void novoLobo(){
    String gps = new String ("Lobo");
    lobo.nome();
    try{
    lobo.anoNascimento();
    }
    catch (InputMismatchException io){
    System.out.println ("ERRO!!! O ano e' um inteiro!");
    }
    status.add(gps);
    pos.add(index,lobo); /* Criei a treta do index para ver se ele criava no index a seguir*/
    index++;
    }

    Metodo para imprimir na class principal:
    public void listar (){

    System.out.println(pos + " " + status + " " + posicionavel);
    }

    Aqui está os bocados de codigo que acho que sao os importantes :) tive de volta disso ate ás 5 da manha e mesmo agora ainda nao vi o problema lol Obrigado :)
     
  4. solidforms

    solidforms Power Member

    hum, nao vi com muita atenção o que poderá ser outra coisa.
    Tu tens varios objectos do tipo Lobo guardados na lista ligada, correcto?

    Esse método listar deveria ser um iterador que ia imprimindo cada célula da lista. Dessa forma nao estas a iterar os elementos todos :x. Nem sabia que mandando imprimir o apontar pos da lista mandava o ultimo elemento, pensava que mandava um endereço um pouco estranho :x.
    Todavia, o código esta um pouco confuso.
    Daqui a um pouco vou tentar ver com melhor atenção. Mas o que me salta à vista é esse System.out.println(pos + ...);
    Devias ter um iterador ou um ciclo for a percorrer a lista:
    for( int i = 0 ; i < pos.size() ; i++)
    Lobo l = pos.get(i) ou pos.next();
    System.out.println(l.toString() + ...);

    Nao sei como tens a tua lista implementada :x.

    Cumps ;).
     
  5. _coelhinha_

    _coelhinha_ Power Member

    Sim eu sei que o codigo tá um bocado confuso...é que eu neste momento estou a tentar optimizar o codigo mas com esse problema nao me deixa avançar...continuando nem com o iterador vai lá lol vou passar ja o codigo 1 bocado + limpo lol
     
  6. _coelhinha_

    _coelhinha_ Power Member

    Metodo Listar:
    /**
    * Opcao LISTAR
    */
    public void listar (){
    Iterator <Lobo> it = lobos.iterator();
    while(it.hasNext())
    System.out.print(it.hasNext());
    }



    Metodo novo lobo:


    /**
    * Opcao NOVO_LOBO,
    * cria um novo lobo
    */
    public void novoLobo(){
    String gps = new String ("Lobo");
    lobo.setNome();
    try{
    lobo.anoNascimento();
    }
    catch (InputMismatchException io){
    System.out.println ("ERRO!!! O ano e' um inteiro!");
    }
    status.add(gps);
    lobos.add(lobo);
    }
     
  7. Baderous

    Baderous Banido

    Esse código está um pouco feio com mistura de I/O e camada computacional. Aquilo que eu aconselhava era teres um segundo construtor que aceitasse como parâmetros uma string e um inteiro, os quais serviriam para inicializar as variáveis de instância da classe Lobo, nomeadamente nome e ano:

    Código:
    public class Lobo {
    private String nome;
    private int ano;
    
    public Lobo() { this("",0); }
    public Lobo(String nome, int ano) { this.nome = nome; this.ano=ano; }
    Depois na classe principal terias a LinkedList<Lobo>, onde colocarias instâncias de Lobo com os valores lidos através do teclado:

    Código:
    public class Main {
    Scanner input = new Scanner(System.in);
    LinkedList<Lobo> lista = new LinkedList<Lobo>();
    nome = input.nextLine();
    ano = input.nextInt();
    Lobo lobo1 = new Lobo(nome,ano);
    lista.add(lobo1);
    // e assim sucessivamente
    E depois para mostrar os elementos da lista, podes iterar sobre a lista com um for:
    Código:
    for (Lobo l : lista)
    System.out.println(l);
    Sendo invocado o método toString da classe Lobo, o qual também poderias definir na classe Lobo:
    Código:
    public String toString() {
    return "Lobo\n\tNome: " + this.nome + "\tAno: " + this.ano;
    }
     
  8. _coelhinha_

    _coelhinha_ Power Member

    É impressao minha ou esse é o mesmo codigo mas apenas + bonitinho? pelo que percebi a diferença é que tens un segundo construtor...um construtor para inicializar as variaveis e outro para atribuir os valores ás variaveis
     
  9. Baderous

    Baderous Banido

    Não só está mais bonito como está mais correcto do ponto de vista de desenvolvimento de software. O teu código misturava camada de I/O com camada de computação de dados. Usando o teu código, se eu um dia quisesse fazer um menu interactivo com Swing para introduzi o nome e ano do lobo, teria de alterar quer a classe principal, quer a classe Lobo, pois na classe Lobo, fazes leitura de dados do teclado e isso não deve ser feito (deve ser feito apenas em classes dedicadas exclusivamente ao tratamento de I/O), enquanto que usando as minhas classes, apenas teria de criar a classe de interacção, sem alterar mais nada.
     
  10. _coelhinha_

    _coelhinha_ Power Member

    Bgd pela ajuda mas de qualquer maneira isso nao me resolve o problema lol isto ainda imprime sempre os mesmos dados =S de qualquer maneira o que tu fizeste ainda nao é o objectivo do trabalho lol mas bgd na mesma ;)
     
  11. solidforms

    solidforms Power Member

    public void listar (){
    Iterator <Lobo> it = lobos.iterator();
    while(it.hasNext())
    System.out.print(it.hasNext());
    }

    hum, nao é o hasNext() :x, esse é um método que retorna um booleano true se tem next.
    deveria ser:
    while(it.hasNext())
    Lobo l = it.next();
    System.out.println(l.toString());

    O que o Baderous disse é verdade, ganha o habito de separar I/O da computação. I/O tratas apenas no Main.

    String gps = new String ("Lobo");
    lobo.setNome();

    um "setter" deve ter um parâmetro. Ou estas a Fazer isso na classe Lobo? :x. E o new String é desnecessário. Faz apenas String gps = "Lobo";
    Para que serve o status?

    Mete o código de inserção na lista :x.
    [EDIT]: e ja agora tens o iterador das listas implementado? Mete a classe LinkedList<E> aqui, sff ;).

    ;).
     
  12. _coelhinha_

    _coelhinha_ Power Member

    Ok essa do hasNext foi má..vi mal LOL agora o main nao posso alterar porque ja é fornecido pelo prof. O Status é uma flag que permite dizer se o lobo ja tem gps ou nao lol foi a melhor maneira que encontrei de fazer LOL o setNome faço na class lobo é errado? lool Tenho que implementar outro iterador para alem daquele? é porque as listas ja o têm lol

    isto é a classe Lobo é so isto que tnho LOL

    public class Lobo {

    /**
    * Guarda o nome dado pelo utilizador
    */
    private String nome;

    /**
    * Guarda o ano dado pelo utilizador,
    * referente a um lobo
    */
    private int ano;

    public Lobo(){
    this.nome = nome;
    this.ano = ano;
    }

    public String setNome (){
    System.out.print("Introduza nome: ");
    Scanner nomeLeitor = new Scanner(System.in);
    nome = nomeLeitor.next();
    return nome;
    }

    public int anoNascimento (){
    System.out.print("Introduza ano: ");
    Scanner intLeitor = new Scanner(System.in);
    ano = intLeitor.nextInt();
    return ano;
    }

    public String getNome (){
    return nome;
    }

    public int getAno (){
    return ano;
    }

    public String toString () {
    return nome + "/" + ano;
    }
    }
     
  13. souto

    souto To fold or to FOLD?

    Essa classe está feiinha. Isso pode complicar-te a vida (já complica).
    O ideal é criares um par de objectos: um que representa o lobo, com os seus atributos (as variáveis privadas), métodos set e get (setNome(String nome), setAnoNascimento(int ano), getNome(), getAnoNascimento()), e o toString(), onde imprimes o nome e a data de nascimento.

    Terias depois outro objecto para criar objectos do tipo Lobo, onde pedes duas coisas: nome e data de nascimento.

    Quando tiveres isso, é mais fácil criares objectos Lobo, e adicioná-los à tal lista que falas (arraylist, suponho).

    Para iterares sobre cada objecto dessa lista só precisas de fazer o que o Baderous disse:

    Código:
    for (Lobo l : lista)
      System.out.println(l);
    
    Supondo que lista é um objecto do tipo ArrayList<Lobo> LinkedList<Lobo>.
    É isso.

    PS: já vi que é uma linkedlist, mas é indiferente. É válido na mesma.
     
    Última edição: 15 de Dezembro de 2008
  14. solidforms

    solidforms Power Member

    Isso do gps é inutil. Na classe Lobo poderias ter mais um atributo:
    boolean gps;

    em que punhas a true se ja tem gps ou false caso contrario.
    Esses set's nao parecem muito correctos :x. se tens o getNome() os set's deveriam ser do tipo void setNome(String nome){ this.nome = nome; }

    E na classe Main fazias um metodo publico que recebia essa informação do Scanner fazias o setNome(String nome) ou passavas logo no constructor. Poupava complicações, acredita.
    Em relação à listagem das coisas, de facto, podes fazer como foi dito em cima.
    fazes um l.toString :x.

    Se o problema persistir deverá ser as listasligadas :x.
    Manda o prof passear xD, nao podes alterar o que ele da mas podes acrescentar :rolleyes:.
     
  15. _coelhinha_

    _coelhinha_ Power Member

    Muito obrigado pelas dicas =P graças ás vossas dicas realmente o codigo tem ficado + simples ...mas nem com iterador nem com for each consigp imprimir os varios lobos LOLOLOLOL

    vou mostrar um output do trabalho LOL :


    Introduza uma opcao: novo_lobo
    Introduza nome: maria
    Introduza ano: 2001
    Introduza uma opcao: listar
    maria/2001
    Introduza uma opcao: novo_lobo
    Introduza nome: fojo
    Introduza ano: 2003
    Introduza uma opcao: listar
    fojo/2003
    fojo/2003


    EDIT: e fiz algo do genero que me disseram para fazer mas nao me simplificou muito a vida lool
     
    Última edição: 15 de Dezembro de 2008
  16. AliFromCairo

    AliFromCairo Power Member

    Boas, caso seja possível, coloca aqui o código que estás a utilizar neste momento para fazer a listagem, e para fazer a inserção.
     
  17. zyThuM

    zyThuM Power Member

    Código:
    [B]Construtor:[/B]
    this.lobo = new Lobo ();
    this.pos = new LinkedList <Lobo> ();
    
    [B]Um dos metodos da classe lobo (o do ano é igual):[/B]
    public String nome (){
            System.out.print("Introduza nome: ");
            Scanner nomeLeitor = new Scanner(System.in);
            return nome = nomeLeitor.next();
        }
    
    [B]Inserçao dos dados:[/B]
        public void novoLobo(){
            String gps = new String ("Lobo");
            lobo.nome();
            try{ 
                lobo.anoNascimento();
            }
            catch (InputMismatchException io){
                System.out.println ("ERRO!!! O ano e' um inteiro!");
            }
            status.add(gps);
            pos.add(index,lobo); /* Criei a treta do index para ver se ele criava no index a seguir*/
            index++;
        }
    Tira a iniciação da variavel lobo do construtor. E mete dentro do método novoLobo.
    Aliás esta variável não deveria ser variável da classe. Deveria ser só declara dentro do método. O teu problema está relacionado à manipulação desta variável.
     
  18. _coelhinha_

    _coelhinha_ Power Member

    /**
    * Opcao LISTAR
    */
    public void listar (){
    for (Lobo l : lobos)
    System.out.println(l + " " + gps());
    }

    private String gps (){
    return status ? "LoboComGps" : "Lobo";
    }

    Isto imprime supostamente a lista

    ----------------------------------------------

    public void setNome (String nome){
    this.nome = nome;
    }

    public void anoNascimento (int ano){
    this.ano = ano;
    }

    public String getNome (){
    return nome;
    }

    public int getAno (){
    return ano;
    }

    public String toString () {
    return nome + "/" + ano;
    }

    cá está o codigo que faz a insercao dos dados e dps faço lobos.add(lobo); para adicionar ;)
     
  19. _coelhinha_

    _coelhinha_ Power Member

    Tks realmente se meter no metodo novoLobo ele ja imprime bem =) mas tenho de manter tabem no metodo construtor se nao ele rebenta...:S
     
  20. solidforms

    solidforms Power Member

    De facto foi uma boa visão essa da instancia do objecto.
    Agora os porquês. Se declarares uma variavel global à classe e nao a reinicializares vais estar sempre a modificar o proprio objecto.

    Hum, apaga essa variavel. E mete-a so no método. Hum, mete aqui o teu código todo onde inseres. Poderás estar a usar a variavel algures e quando apagas estoira.
     

Partilhar esta Página