Bom dia amigos, estou com uma duvida em relacao a classificao com TreeSet implementando a interface Comparable, estou usando o metodo compareTo para ordenar os elementos, porem um TreeSet nao deveria ter duplicatas, correto? Pois bem, a saida do meu codigo da maneira que esta nao elimina a duplicidade, tinha entendido que a sobrescricao dos metodos equals e hashCode eliminaria a duplicidade e o metodo compareTo ordenaria os objetos, segue abaixo meu codigo:
import java.util.Date;
import java.util.Set;
import java.util.TreeSet;
public class Veiculo implements Comparable{
String marca;
String anoFabricacao;
Integer chassi;
public Veiculo(String marca, String anoFabricacao, Integer chassi){
this.marca = marca;
this.anoFabricacao = anoFabricacao;
this.chassi = chassi;
}
public boolean equals(Object obj){
if(((Veiculo)obj).chassi==this.chassi)
return true;
return false;
}
public int hashCode(){
return chassi;
}
@Override
public int compareTo(Object o) {
return this.anoFabricacao.compareTo(((Veiculo)o).anoFabricacao);
}
public String toString(){
return "Marca: " + marca + "\n" + "Ano Fabricacao: " + anoFabricacao + "\n" + "Chassi: " + chassi + "\n";
}
public static void main(String[] args) {
Set veiculo = new TreeSet();
veiculo.add(new Veiculo("Ford","2000",123));
veiculo.add(new Veiculo("GM", "2011",123));
veiculo.add(new Veiculo("Volks","2000", 900));
veiculo.add(new Veiculo("Citroen","2007", 2000));
veiculo.add(new Veiculo("GM","2009",215));
System.out.println(veiculo);
}
}
Por favor, se alguem puder me ajudar eu agradeco. Abraco a todos.
TreeSet/TreeMap dependem apenas do comparator (método compare).
HashSet/HashMap/LinkedHashSet/LinkedHashMap dependem dos métodos “hashCode” e “equals”.
Seu método “compare” está incompleto (teria de usar mais campos,não só o ano de fabricação).
Usa o Chassi no compareTo, porquê é um atributo único(tipo um id).
Acho que isso eliminará duplicidades.
Da forma que você fez, vai ordenar apenas por ano de fabricação.
Eu mudaria um pouco assim, para eliminar esse cast no método compareTo()
public class Veiculo implements Comparable<Veiculo> {
//...
public int compareTo(Veiculo o) {
return this.anoFabricacao.compareTo(o.anoFabricacao);
}
//...
}
A propósito, a linha referente a: veiculo.add(new Veiculo("Volks","2000", 900));
não vai aparecer, já que o Ford 2000 veio 1°.
Almeidaah
Valeu pela resposta, mas essa parte eu já sabia pois já havia feito, mesmo assim valeu pelo interesse em ajudar.
Romarcio
Cara, eu entendi o que você fez, mas estou em um momento de estudos onde ainda não uso os genéricos, e acredito que o seu código tem genéricos, correto? Agradecendo também pela sua resposta.
entanglement
Cara, desculpa minha ignorância mas eu não entendi o que você quis dizer, ainda assim vou testar usando mais de um campo pra ver os resultados e posto aqui, Obrigado pela resposta.
Bom dia, Sidney.Tavares
Na verdade realizei alguns testes aqui também o equals comprando com os operadores de igualde e com o metodo equals() estão funcinando normalmente mas na hora de add() ao TreeSet ele não esta considerando duplicidade, o hashcode() é utilizado na buscas das Collections sendo mais importante na tabelas de espalhamento Hashtable,HashMap,LinkedHashMap,LinkedHashSet lembrando sempre que o contrato de implementação do methodo HashCode() diz que se A.equals(B) então A.hashCode() == B.hashCode().
A implementação do metodo compareTo() da interface Comparable é utilizado justamente para dizer se os objetos cujo o qual não precedem de uma ordenação natural como (implementam compareTo())String,Integer,Short… tenham uma ordenação e sejam comparados para inclusão nas Collections.
Implemente seu codigo para usar o atributo this.chassi dentro de compareTo() e ai sim ele ficara ordenado e classificado. Para verificar isso faça o teste comparando os objetos que esta utilizando para add() no TreeSet() com .equals() e depois ==.
Obs.: Seguindo uma logica de tipos o anoFabricacao tambem poderia ser trocado para um tipo Inteiro, e é importante lembra também ja que não esta sendo utilizado genericos (não somente por isso) no metodo equals() é relevante salientar o teste de instanceof antes da comparação dos atributos e os atributos estarem seguindo uma regra de encapsulamento sendo acessados através do metodos getXXX().
Boa sorte, bons estudos…
Espero te ajudado em algo…
import java.util.Set;
import java.util.TreeSet;
public class Veiculo implements Comparable{
private String marca;
private Integer anoFabricacao;
private Integer chassi;
public String toString(){
return "Marca: " + marca + "\n" + "Ano Fabricacao: " + anoFabricacao + "\n" + "Chassi: " + chassi + "\n";
}
public Veiculo(String marca, Integer anoFabricacao, Integer chassi){
this.marca = marca;
this.anoFabricacao = anoFabricacao;
this.chassi = chassi;
}
public Integer getAnoFabricacao() {
return anoFabricacao;
}
public Integer getChassi() {
return chassi;
}
public String getMarca() {
return marca;
}
public boolean equals(Object obj){
if((obj instanceof Veiculo) && (((Veiculo)obj).getChassi()).equals(this.getChassi())){
return true;
}else{
return false;
}
}
public int hashCode(){
return getChassi();
}
@Override
public int compareTo(Object o) {
if(this.chassi==(((Veiculo)o).getChassi())) {
return 0;
}else if(this.chassi < (((Veiculo)o).getChassi())){
return -1;
}else{
return 1;
}
}
public static void main(String[] args) {
// System.out.println(new Veiculo("Ford",2000,123).equals(new Veiculo("GM", 2011,123)));
// System.out.println(new Veiculo("Ford",2000,123) == (new Veiculo("GM", 2011,123)));
Set veiculo = new TreeSet();
veiculo.add(new Veiculo("Ford",2000,123));
veiculo.add(new Veiculo("GM", 2011,123));
veiculo.add(new Veiculo("Volks",2000, 900));
veiculo.add(new Veiculo("Citroen",2007, 200));
veiculo.add(new Veiculo("GM",2009,215));
System.out.println(veiculo);
}
}
Le Java Reis
Boa tarde, olha, sua explicação foi excelente,acho que o que eu não aprendi ainda, ou o detalhe que tá me faltando assimilar, é que
nesse caso a classe não é ordenada e eu que devo especificar a forma como ela será ordenada, é isso? Já que neste caso não há uma ordem natural? Ou estou confundindo as coisas? Se você puder me dar mais essa dica eu agradeço.
Ah, e você com certeza contribuiu bastante para meu entendimento.Abraço.
Sidney.Tavares
Fico feliz em pode estar ajudando apesar de ter feito minha prova ontem 22\10 não fui aprovado tive um score de 68% eram necessario minino de 70% mas ta valendo, tentarei de novo espero que você tenha mais sorte e é exatamente isso mesmo que você que você citou; as classes criadas por nós programadores, para serem usadas na ordenação/classificação dos Collections precisam implementar o compareTo() da interface java.util.Comparable ou o compare() da interface java.lang.Comparator repare que as duas interfaces se encontram em pacotes diferentes.
Comparable sendo implementado diretamente no objeto\classe que o programador esta criando permitindo que este objeto\classe tenha uma unica forma de ordenação\classificação; ou, pode também utilizar uma nova classe para implementar Comparator podendo assim criar varias classes de implementação da mesma(Comparator) passando uma instância desse mesmo objeto\classe para o construtor de TreeSet(Comparator<E extends Object> c) ou como parametro no metodo sort(List l , Comparator<E extends Object> c) de Collections.
DICA.: Essa interface Comparator pode ser implementada utilizando uma classe interna anonima na sua própria classe de implementação de Comparable
Abraços, e desculpe o desabafo com relação a prova.
Bons estudos…
Le Java Reis
Mais uma vez muito obrigado, com essa explicação eu vou encerrar este tópico, sobre a sua prova, é realmente uma pena, porque faltou pouquíssimo, mas pelo que pude perceber acho que você não vai desanimar e na próxima com certeza vai estar pronto. Abraço e acredito que por mais vezes vamos nos esbarrar por aqui, pois agora é que estou aprofundando meus estudos para tentar tirar a minha em janeiro, valeu mesmo pela ajuda.