3
respostas

Estou com um erro em um exercício

A Classe Funcionario esta assim:

package br.com.funcionarios;

public class Funcionario {
    private String nome;
    private int idade;

    public Funcionario(String nome, int idade) {
        this.nome = nome;
        this.idade = idade;
    }
    public String getNome() {
        return nome;
    }
    public void setNome(String nome) {
        this.nome = nome;
    }
    public int getIdade() {
        return idade;
    }
    public void setIdade(int idade) {
        this.idade = idade;
    }

}

E a classe para Ordenar esta desta forma:

package br.com.funcionarios;

import java.util.Comparator;

public class OrdenaPorIdade  implements Comparator<Funcionario>{

    @Override
    public int compare(Funcionario funcionario, Funcionario outroFuncionario) {
        return funcionario.getIdade() - outroFuncionario.getIdade();
    }

}

O Teste main que consome esta classe Funcionario, ficou assim:

package br.com.funcionarios;

import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class TesteFuncionario {

    public static void main(String[] args) {
        Funcionario f1 = new Funcionario("Barney", 31);
        Funcionario f2 = new Funcionario("Diogo", 29);
        Funcionario f3 = new Funcionario("Micaela", 31);
        Funcionario f4 = new Funcionario("Jefferson", 47);

        Set<Funcionario> funcionarios = new TreeSet<>(new OrdenaPorIdade());

        funcionarios.add(f1);
        funcionarios.add(f2);
        funcionarios.add(f3);
        funcionarios.add(f4);

        Iterator<Funcionario> iterador = funcionarios.iterator();

        while (iterador.hasNext()) {
            System.out.println(iterador.next().getNome());
        }

    }

}

O erro é que a Saída esta mostrando apenas 3 nomes mas foi enviado para classe 4 nomes: Este é o resultado, Esta suprimindo o nome Micaela.

Diogo
Barney
Jefferson

Alguém sabe o que pode estar acontecendo?

3 respostas

fiz um outro teste trocando a idade da Micaela para 32, e desta forma funcionou. Ele suprimiu porque a idade estava repetida. Mas por que ? É assim mesmo? Pensei que isto acontecia somente quando o nome fosse igual também.

Parece que o problema esta no TreeSet mesmo: fiz um novo Teste trocando por HashSet e deu certo:

public static void main(String[] args) {
    Funcionario f1 = new Funcionario("Barney", 31);
    Funcionario f2 = new Funcionario("Diogo", 31);
    Funcionario f3 = new Funcionario("Micaela", 31);
    Funcionario f4 = new Funcionario("Jefferson", 47);

    //Set<Funcionario> funcionarios = new TreeSet<>(new OrdenaPorIdade());
    Set<Funcionario> funcionarios = new HashSet<>();
    funcionarios.add(f1);
    funcionarios.add(f2);
    funcionarios.add(f3);
    funcionarios.add(f4);

    Iterator<Funcionario> iterador = funcionarios.iterator();

    while (iterador.hasNext()) {
        System.out.println(iterador.next().getNome());
    }
    System.out.println("---------------------------------------");
    funcionarios.forEach(funcionario ->{
        System.out.println(funcionario.getNome() + ", " +funcionario.getIdade());
    });
}

A saída foi a seguinte:

Micaela
Barney
Jefferson
Diogo
---------------------------------------
Micaela, 31
Barney, 31
Jefferson, 47
Diogo, 31

Ola Jefferson.

Na verdade não é um erro. Lembre-se que característica da família de coleções Set é não permitir repetição dos dados (ao tentar inserir um dado repetido, ele não retorna erro, só ignora mesmo o dado).

Para um objeto qualquer poder ter esse referencial de comparação, precisamos dizer ao Set qual dado ele deve levar em consideração na comparação, e assim, caso repita, ele ignora o dado. Caso a gente não indique o referencial de comparação, será sempre posição de memória dos objetos.

No caso de HashSet, esse referencial deve ser feito em conjunto com os método compare e hashcode. Já no caso do TreeSet, o referencial é somente o compare (que para ele, é obrigatório ter).

Note que você indica para o TreeSet que o comparador é o atributo idade dos seus objetos. Assim, dois objetos com dados diferentes, mas com idades iguais, o segundo objeto pra ele é repetido e não estará na coleção.

Se você precisa de repetição de dados (e ainda possibilidade de ordenação), deve usar a família de coleções List, como o ArrayList.