Derivações do metodo SET

11 respostas
ateubh

Atualmente tenho usado o HashSet para guardar os objetos em meus programas. Mas estou tendo o seguinte problema:

o método HashSet não me garante que vou obter os objetos inseridos na ordem em que foram inseridos.

alguém conhece algum método que é derivado da classe Set que me dê essa segurança?

11 Respostas

T

Use LinkedHashSet.

import java.util.*;

/**
 * Esta classe implementa equals e hashCode.
 */
class Cliente {
    private String nome = "";
    private String endereco = "";
    public Cliente(String pNome, String pEndereco) { nome = pNome; endereco = pEndereco; }
    public String getNome() { return nome; } public void setNome(String pNome) { nome = pNome; }
    public String getEndereco() { return endereco; } public void setEndereco(String pEndereco) { endereco = pEndereco; }
    public String toString() { return "nome=" + nome + ", endereco=" + endereco; }
    public boolean equals (Object o) {
        if (!(o instanceof Cliente)) return false;
        if (o == this) return true;
        Cliente c = (Cliente) o;
        // só para simplificar estou supondo que nenhum dos campos é null
        return nome.equals(c.getNome()) && endereco.equals(c.getEndereco());
    }
    public int hashCode() {
        int ret = nome.hashCode();
        ret = ret * 37 + endereco.hashCode();
        // se houver mais campos, vá repetindo a expressão acima "ret = ret * 37 + hashCode do proximo campo"
        // por exemplo, ret = ret * 37 + telefone.hashCode();
        return ret;
    }
}


class TestHashSet {
    public static void main(String[] args) {
        Set<Cliente> clientes = new LinkedHashSet<Cliente>();
        clientes.add (new Cliente ("Luis Inacio", "Palacio da Alvorada"));
        clientes.add (new Cliente ("Fernandinho Beira-Mar", "Presidente Bernardes"));
        clientes.add (new Cliente ("Fernandinho Beira-Mar", "Presidente Bernardes")); // não será repetido - ainda bem!
        clientes.add (new Cliente ("Marcos Pontes", "Estacao Espacial Internacional"));
        clientes.add (new Cliente ("Fernando Henrique Cardoso", "Rua Maranhao"));
        clientes.add (new Cliente ("Bill Gates", "Seattle"));
        for (Cliente cliente : clientes) {
            System.out.println (cliente);
        }
    }
}
ateubh

obrigado

ateubh

não tô conseguindo… segue abaixo o meu código

package model;

import java.util.LinkedHashSet;
import java.util.Set;

public class Select{
    private String nome     = " ";
    private String tamanho  = "1";
    private String disabled = "false";
    private String multiple = "false";
    private String indice   = "0";
    private String tam      = " ";
    private Set parametros  = new LinkedHashSet();
    
    public String getNome() {
        return nome;
    }

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

    public String getTamanho() {
        return tamanho;
    }

    public void setTamanho(String tamanho) {
        this.tamanho = tamanho;
    }

    public String isDisabled() {
        return disabled;
    }

    public void setDisabled(String disabled) {
        this.disabled = disabled;
    }

    public String isMultiple() {
        return multiple;
    }

    public void setMultiple(String multiple) {
        this.multiple = multiple;
    }

    public String getIndice() {
        return indice;
    }

    public void setIndice(String indice) {
        this.indice = indice;
    }

    public Set getParametros() {
        return parametros;
    }

    public void setParametros(Set parametros) {
        this.parametros = parametros;
    }

    public String getTam() {
        if( tam.trim().length() == 0 ) {
            return "A250";
        } else {
            return tam;
        }
    }

    public void setTam(String tam) {
        this.tam = tam;
    }
    
    public boolean equals (Object o) {
        if ( !(o instanceof SelectBoxParametro ) ) 
            return false;
        if (o == this) 
            return true;
        Select c = (Select) o;
        return parametros.equals(c.getParametros());
    }
}

quando uso um iterator para pegar o que está dentro do objeto parametros, eles vêm fora de ordem.

T

a) “parametros” é um Set de que coisa?
b) Como é que os elementos são adicionados a “parametros”?

ateubh

Estou enviando a classe parâmetros

package model;

public class SelectBoxParametro {
    private String valor     = "NULO";
    private String descricao = "SELECIONE UMA OPÇÃO";
    private String selected =  "true";

    public String getValor() {
        return valor;
    }

    public void setValor(String valor) {
        this.valor = valor;
    }

    public String getDescricao() {
        return descricao;
    }

    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }

    public String isSelected() {
        return selected;
    }

    public void setSelected(String selected) {
        this.selected = selected;
    }

    public String getSelected() {
        return selected;
    }
    
    public boolean equals (Object o) {
        if ( !(o instanceof SelectBoxParametro ) ) 
            return false;
        if (o == this) 
            return true;
        SelectBoxParametro c = (SelectBoxParametro) o;
        return valor.equals(c.getValor()) && descricao.equals(c.getDescricao()) && selected.equals(c.getSelected());
    }   
    
     public int hashCode() {
        try{
            return new Integer(valor).intValue();
        }catch( Exception e ) {
            return valor.hashCode();
        }
     }

}

os dados são adicionados da seguinte forma

lSelectBoxParametro = new SelectBoxParametro();
        lSelectBoxParametro.setSelected( "TRUE" );
        lSelectBoxParametro.setDescricao( "<- SELECIONE UMA OPÇÃO ->" );
        lSelectBoxParametro.setValor( "0" );
        lSelectBoxParametro.setSelected( "TRUE" );
        lParametro.add( lSelectBoxParametro );
T

Calcule o hashCode direito. Siga o exemplo que lhe dei.

public int hashCode() {
         int ret = valor.hashCode();
         ret = ret * 37 + descricao.hashCode();
         // se houver mais campos, vá repetindo a expressão acima "ret = ret * 37 + hashCode do proximo campo"
         // por exemplo, ret = ret * 37 + telefone.hashCode();
         return ret;
     }
ateubh

ele continua pegando fora de ordem

public boolean equals (Object o) {
        if ( !(o instanceof SelectBoxParametro ) ) 
            return false;
        if (o == this) 
            return true;
        SelectBoxParametro c = (SelectBoxParametro) o;
        return valor.equals(c.getValor()) && descricao.equals(c.getDescricao()) && selected.equals(c.getSelected());
    }   
    
     public int hashCode() {
        int ret = valor.hashCode();;
        ret = ret * 37 + descricao.hashCode();
        ret = ret * 37 + selected.hashCode();
        return ret;
     }

o que fiz de errado?

T

Agora estou curioso. O que é “ordem” para você?
Que eu saiba, LinkedHashSet deve manter a ordem de inserção (add) dos objetos, quando se usa o Iterator padrão (retornado por “iterator()”) para percorrer os dados.

ateubh

Trocando todos os HashSet por ArrayList funcionou…

O que estava querendo dizer era o seguinte, estou preenchendo combosBox, e o programa insere dados em diversos combos (sempre em ordem alfabetica), mas quando pego esses dados com um iterator, ele me devolve em outra ordem (que não é alfabética).

Antes de substituir os metodos equals e hashcode, ele me devolvia cada hora de um jeito.

De qualquer forma, obrigado pela ajuda.

:wink:

pcalcado

Você quer uma estrutura ordenada, não uma estrutura que garanta a ordem.

Se você precisa de um set ordenado use uma implementação de SortedSet.

http://java.sun.com/j2se/1.5.0/docs/api/java/util/SortedSet.html

T

É por isso que em algumas faculdades o pessoal fala “dados sorteados” (é claro que em português isso é incorreto) em vez de falar “dados ordenados”.
sorted = ordenado, tipicamente em ordem lexicográfica (alfanumérica).
ordered = ordenado (pode ser, por exemplo, ordem de inserção).
Putz

Criado 6 de abril de 2006
Ultima resposta 7 de abr. de 2006
Respostas 11
Participantes 3