As classes do pacote util do java realmente fazem jus ao nome, uma bem interessante é a classe ArrayList que faz uso de generics e oferece a capacidade de criar listas com objetos.
Um exemplo bem simples disso seria esse:
public class Pessoa { private String nome;
private String cpf;
private int idade;
public Pessoa(String nome, String cpf, int idade) {
this.nome = nome;
this.cpf = cpf;
this.idade = idade;
}
//getters e setters omitidos
}
É possível criar uma lista de pessoas com a modelagem acima:
public static void main(String[] args) {
List<Pessoa> pessoas = new ArrayList<>();
Pessoa pessoa1 = new Pessoa("Marcos", "12345678941", 20);
pessoas.add(pessoa1);
}
Até aqui tudo bem simples, mas e se eu quiser verificar se já existe uma pessoa antes de colocar na lista? O método contains() ajuda nisso.
public static void main(String[] args) {
List<Pessoa> pessoas = new ArrayList<>();
Pessoa pessoa1 = new Pessoa("Marcos", "12345678941", 20);
pessoas.add(pessoa1);
if(pessoas.contains(pessoa1)) {
System.out.println("Pessoa já existe na lista");
} else {
System.out.println("Pessoa não existe na lista");
}
}
Resultado no console:
Mas aqui, está comparando referência de memória com referência de memória.. Caso eu crie um segundo objeto de pessoa com os mesmos dados o resultado será false, mostrando que a pessoa não está na lista. Vamos verificar?
public static void main(String[] args) {
List<Pessoa> pessoas = new ArrayList<>();
Pessoa pessoa1 = new Pessoa("Marcos", "12345678941", 20);
Pessoa pessoa2 = new Pessoa("Marcos", "12345678941", 20);
pessoas.add(pessoa1);
if(pessoas.contains(pessoa2)) {
System.out.println("Pessoa já existe na lista");
} else {
System.out.println("Pessoa não existe na lista");
}
}
Resultado no console:
Mas então posso inserir dados duplicados numa lista? Sim.
Isso acontece porque foi verificada a referência de memória, não os atributos do objeto em si. Mas como sair dessa?
Felizmente é muito fácil, basta usar um método bem famoso chamado equals. Ele deve ser adicionado na classe Pessoa, ou seja, na classe que será usada para comparações. Fica parecido com isso:
public class Pessoa {
private String nome;
private String cpf;
private int idade;
public Pessoa(String nome, String cpf, int idade) {
this.nome = nome;
this.cpf = cpf;
this.idade = idade;
}
//getters e setters omitidos
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pessoa pessoa = (Pessoa) o;
return idade == pessoa.idade && Objects.equals(nome, pessoa.nome) && Objects.equals(cpf, pessoa.cpf);
}
@Override
public int hashCode() {
return Objects.hash(nome, cpf, idade);
}
}
Testando esse mesmo código da main, o resultado será diferente:
public static void main(String[] args) {
List<Pessoa> pessoas = new ArrayList<>();
Pessoa pessoa1 = new Pessoa("Marcos", "12345678941", 20);
Pessoa pessoa2 = new Pessoa("Marcos", "12345678941", 20);
pessoas.add(pessoa1);
if(pessoas.contains(pessoa2)) {
System.out.println("Pessoa já existe na lista");
} else {
System.out.println("Pessoa não existe na lista");
}
}
Resultado:
Sobre o método equals que foi utilizado:
- Devemos sobrescrever para definir um critério de igualdade (foi feito na classe pessoa);
- A implementação padrão compara referências de memória;
- É um método definido na classe Object;
- Sua assinatura é: public boolean equals(Object ref)
Continuando com alguns métodos:
Podemos saber o tamanho de uma lista, o método size() retorna a quantidade de elementos:
System.out.println("Tamanho da lista: " + pessoas.size());
Resultado:
Podemos saber se está vazia, o método isEmpty() retorna um boolean:
System.out.println("Lista vazia: " + pessoas.isEmpty());
Resultado:
Existem mais métodos nessa classe e vale a pena dar uma olhada, nesse pequeno texto eu queria deixar uma anotação sobre o método contains e como ele pode ser útil no dia a dia.