Coleções

Propaganda
Coleções
Podemos definir coleção como a representação de um
grupo de objetos, semelhante aos arrays. No entanto, as
coleções são implementações que geralmente encapsulam
arrays, oferecendo algumas facilidades como:
●
●
●
●
●
busca;
inserção;
redimensionamento dinâmico;
remoção de elementos;
ordenação
Exemplos da utilização de coleções
Quando fazemos consultas em banco de dados e queremos
armazenar os objetos que representam o resultado da
consulta em um único objeto.
Exemplo: A consulta de clientes por categoria pode retornar
uma coleção de objetos cliente.
Mapeamento de relações 1 para muitos, ou seja, um
cliente tem muitos endereços. Podemos dizer que um objeto
do tipo Cliente tem uma coleção de objetos do tipo
Endereco.
Vantagens na utilização de coleções
Não é necessário implementar
busca, redimensionamento e etc.
métodos
de
ordenação,
Normalmente, há a melhora na performance, pois provê
implementações otimizadas criadas por especialistas.
Interface em Java
O que é uma interface?
●
A
interface
é
uma
forma
de
especificação
de
comportamento de classes, onde definimos todos os
métodos que devem ser implementados pela classe,
garantindo que as classes que implementem a interface
terão, obrigatoriamente, todos os métodos definidos na
interface;
●
Interfaces definem a forma como iremos interagir com
as classes que a implementam;
1
●
Interface é um protótipo de classe;
A Interface Collection (java.util.Collection)
A
interface
Collection
é
a
especificação
representa um grupo de objetos chamados de elementos.
que
Existem diferentes implementações e sub-interfaces da
interface Collection que oferecem vantagens e desvantagens,
dependendo da situação, podemos encontrar coleções com as
seguintes características:
●
●
●
Algumas permitem elementos duplicados e outras não
Algumas são ordenadas e outras não
Algumas permitem a inserção do elemento null e outras
não
Esta interface é utilizada apenas como "objeto para
polimorfismo" para que um método possa receber uma
Collection genérica, ou seja, qualquer classe que a
implemente ou uma de suas sub-interfaces.
<<Interface>>
Collection
<<Interface>>
Set
<<Interface>>
List
Importância da Sobrescrita do hashCode e equals
equals()
O que acontece quando comparamos dois objetos da mesma
classe utilizando o operador == ?
Inicialmente, poderíamos acreditar que os atributos
que compõe cada um dos objetos seriam comparados,
retornando true se todos forem idênticos. Porém, a JVM
verifica se a referência dos objetos é a mesma, ou seja, se
os endereços de memória são iguais.
2
De acordo com a documentação do JavaDoc da classe
Object, que define o método equals(), devemos sempre
sobrescreve-lo
levando
em
consideração
as
seguintes
relações:

Reflexão: x.equals(x) deve ser true para qualquer x
diferente de null;

Simetria: Para x e y diferentes de null, se
x.equals(y) é true, então y.equals(x) também deve
ser;
Transitividade: Para x, y e z diferentes de null, se
x.equals(y) é true, e y.equals(z) é true, então
x.equals(z) também deve ser true;


Consistência: Para x e y diferentes de null,
múltiplas chamadas de x.equals(y) devem sempre
retornar o mesmo valor;

Para x diferente de null, x.equals(null) deve sempre
retornar false
Vamos analisar alguns exemplo para entender o uso do método
equals().
Pessoa.java
public class Pessoa{
private String nome;
private String RG;
public Pessoa(String nome, String RG){
this.setNome(nome);
this.setRG(RG);
}
public void setNome(String nome){
this.nome = nome;
}
public void setRG(String RG){
this.RG = RG;
}
public String getNome(){
return nome;
}
public String getRG(){
return RG;
}
}
3
TestePessoa.java
public class TestePessoa{
public static void main (String args[]){
Pessoa p1 = new Pessoa("Jessica", "752");
Pessoa p2 = new Pessoa("Jessica", "752");
if (p1 == p2){
System.out.println("p1 igual p2 com ==");
}
else{
System.out.println("p1 != p2 com ==");
}
}
}
Veja abaixo a saída gerada pela execução da classe
TestePessoa.java.
p1 != p2 com ==
Os objetos foram considerados diferentes pelo operador
==, embora contenham atributos idênticos, pois a referência
aos objetos na memória heap é diferente.
Vamos analisar um novo exemplo, porém desta
utilizando o método equals() herdado da classe Object.
vez
TestePessoa.java
public class TestePessoa{
public static void main (String args[]){
Pessoa p1 = new Pessoa("Jessica", "752");
Pessoa p2 = new Pessoa("Jessica", "752");
if (p1.equals(p2)){
System.out.println("p1 igual p2 com equals da classe Object");
}
else{
System.out.println("p1 != p2 com equals da classe Object");
}
}
}
Veja abaixo a saída gerada pela execução da classe
TestePessoa.java, agora com a utilização do método equals
da classe Object.
p1 != p2 com equals da classe Object
A comparação utilizando o método equals apresentou o
mesmo resultado daquele que utilizou o operador ==. Isto
4
aconteceu porque o método equals, herdado da classe Object,
emprega o operador == para comparar objetos.
Se o objetivo é informar que os objetos da classe
Pessoa são iguais caso o conteúdo de todos os seus
atributos forem iguais, devemos então sobrescrever o método
equals na classe Pessoa.
Veja abaixo as alterações
TestePessoa.java.
nas
classes
Pessoa.java
e
Pessoa.java
public class Pessoa{
private String nome;
private String RG;
public Pessoa(String nome, String RG){
this.setNome(nome);
this.setRG(RG);
}
public void setNome(String nome){
this.nome = nome;
}
public void setRG(String RG){
this.RG = RG;
}
public String getNome(){
return nome;
}
public String getRG(){
return RG;
}
//Sobrescrita do método equals da classe Object
public boolean equals(Object o){
//Devemos verificar se o objeto "o" eh uma
//instancia da classe Pessoa
if (o instanceof Pessoa){
//Devemos fazer o cast de Object para Pessoa
Pessoa p = (Pessoa) o;
if (this.getNome().equals(p.getNome())
&& this.getRG().equals(p.getRG())){
return true;
}
else{
return false;
}
}
else{
return false;
}
}
}
5
TestePessoa.java
public class TestePessoa{
public static void main (String args[]){
Pessoa p1 = new Pessoa("Jessica", "752");
Pessoa p2 = new Pessoa("Jessica", "752");
if (p1.equals(p2)){
System.out.println("p1 igual p2 com equals da classe Pessoa");
}
else{
System.out.println("p1 != p2 com equals da classe Pessoa");
}
}
}
Veja abaixo a saída gerada pela execução da classe
TestePessoa.java, agora com a utilização do método equals
da classe Pessoa.
p1 igual p2 com equals da classe Pessoa
hashCode()
Segundo o JavaDoc da classe Object, o método
hashCode() retorna números inteiros distintos para objetos
distintos. Este número é gerado pela conversão do endereço
interno do objeto em um número inteiro.
As implementações de equals e hashCode devem ser
coerentes, ou seja, sempre que dois objetos forem
considerados iguais pelo método equals, os dois objetos
também devem possuir o mesmo hashCode. Embora não seja
exigido pela especificação que dois objetos diferentes
tenham hashCodes diferentes, é coerente implementar os
métodos de forma que objetos diferentes tenham hashCodes
diferentes.
A implementação de hashCode, pode ser baseada
implementação de hashCode dos atributos da classe.
na

Vamos criar uma classe Funcionário que tem
atributos: nome e fone. Ambos do tipo String;

O método equals da classe Funcionário irá retornar
true se e somente se o nome e o fone do Funcionário
forem iguais;

O hashCode do Funcionário será calculado somando o
hashCode do nome e do fone do Funcionário.
dois
6
Veja o exemplo abaixo que sobrescreve
equals()
e
hashCode()
da
classe
Object
Funcionário.
os métodos
na
classe
Funcionario.java
public class Funcionario{
String nome;
String fone;
public boolean equals(Object o){
//Devemos verificar se o objeto "o" eh uma
//instancia da classe Funcionario
if (o instanceof Funcionario){
//Devemos fazer o cast de Object para Funcionario
Funcionario f = (Funcionario) o;
if (this.nome.equals(f.nome)
&& this.fone.equals(f.fone)){
return true;
}
else
return false;
}
else
return false;
}
public int hashCode(){
return this.fone.hashCode() + this.nome.hashCode();
}
public static void main (String args[]){
Funcionario f1 = new Funcionario();
Funcionario f2 = new Funcionario();
f1.nome = "Joao";
f1.fone = "564";
f2.nome = "Joao";
f2.fone = "564";
if (f1.equals(f2)){
System.out.println("f1 igual f2");
System.out.println("hashCode f1: " + f1.hashCode());
System.out.println("hashCode f2: " + f2.hashCode());
}
else{
System.out.println("f1 diferente f2");
System.out.println("hashCode f1: " + f1.hashCode());
System.out.println("hashCode f2: " + f2.hashCode());
}
}
}
7
Conjuntos (Set), Listas (List) e Mapeamento (Map)
A Interface List (java.util.List)
A interface List define uma coleção ordenada, também
conhecida como seqüência. Por isto, quando utilizamos
objetos que implementem esta interface, obtemos o controle
sobre a posição em que os elementos são inseridos, sendo
possível acessá-los através de um índice inteiro (posição
na lista).
Exemplo:
Índice
List
0
obj1
1
obj2
2
obj3
...
...
n
Objn
Normalmente as classes que implementam esta interface
permitem elementos duplicados e elementos null.
Hierarquia
<<Interface>>
Collection
<<Interface>>
List
ArrayList
8
A Interface Set (java.util.Set)
Esta Collection é a representação de
matemáticos, e caracteriza-se por não possuir
repetidos no seu interior.
conjuntos
elementos
De que maneira é feita a análise de elementos idênticos?
Tecnicamente, a Set verifica um a um os objetos
existentes em seu interior com o elemento a ser incluído.
Esta verificação é feita invocando o método equals de cada
um dos objetos, passando como parâmetro o objeto a ser
inserido. Se a análise retornar true o objeto não será
incluído ao Set.
<<Interface>>
Collection
<<Interface>>
Set
HashSet
A Interface Map (java.util.Map)
Esta interface define objetos que mapeiam chaves e
valores, onde as chaves não podem ser duplicadas, mas os
valores sim.
Map chave (Object)
Valor (Object)
Pessoa1
Filho1
Pessoa2
Filho2
Pessoa3
Filho3
...
...
PessoaN
FilhoN
Não aceita elementos repetidos
Aceita elementos repetidos
9
Desta forma, não há nenhuma restrição específica ao
valor null, exceto pelo fato que a condição de chaves não
repetidas seja respeitada, ou seja, é possível adicionar
apenas uma chave igual a null e quantos valores null forem
necessários.
A interface oferece três visualizações distintas de um
Map:



As chaves podem ser visualizadas como um objeto do
tipo Set;
Os valores podem ser vistos como uma coleção de
objetos;
Conjunto (objeto do tipo Set) de pares chaves-valor.
Usando Estruturas de Listas ArrayList
A classe ArrayList (java.util.ArrayList)
É uma implementação da interface List, onde o tamanho
do array pode ser alterado em tempo de execução. Quando
utilizamos ArrayList é permitida a inserção de todo tipo de
elementos, inclusive null.
Construtores
●
ArrayList():
Constrói
um
ArrayList
capacidade inicial de 10 posições;
vazio,
●
ArrayList(int
capacidadeInicial):
Constrói
ArrayList vazio com a capacidade inicial igual
parâmetro informado;
com
um
ao
Métodos para adicionar elementos ao ArrayList
●
void add(int i, Object obj): Adiciona o novo objeto
obj na posição i;
●
boolean add(Object obj): Adiciona o novo objeto obj na
última posição do ArrayList;
●
Object set(int i, Object obj): Substitui um objeto
existente no ArrayList na posição i pelo objeto obj;
É importante observar que os métodos acima recebem
como parâmetro um Object e, por isto, sempre que é passado
um objeto específico, como por exemplo, um Cliente ou uma
String é realizado um upcast automático.
10
Método para verificar se o ArrayList contém um determinado
elemento:
●
boolean contains(Object obj): Retorna true se o
ArrayList possui o objeto obj. A análise é baseada no
método equals implementado na classe obj.
Métodos para recuperar elementos ou posição de um elemento
dentro do ArrayList:
●
Object get(int pos): Retorna o elemento que está na
posição pos do ArrayList;
●
int indexOf(Object obj): Retorna a posição do objeto
obj no ArrayList. Caso o Object obj não seja
encontrado, o método irá retornar -1;
Método para remover elementos do ArrayList:
●
Object remove(int index):
estiver na posição index.
Remove
o
elemento
que
Método para verificar o tamanho / número de elementos do
ArrayList:
●
int size():
ArrayList;
Retorna
o
número
de
elementos
do
Abaixo temos um exemplo da utilização da classe ArrayList.
public class Funcionario {
private String nome;
private int idade;
public Funcionario(String nome, int idade){
this.setNome(nome);
this.setIdade(idade);
}
public int getIdade() {
return idade;
}
public void setIdade(int idade) {
this.idade = idade;
}
public String getNome() {
return nome;
}
11
public void setNome(String nome) {
this.nome = nome;
}
public String toString(){
String str = "Funcionario: " + nome + "\nIdade: " + idade + "\n";
return str;
}
}
import java.util.ArrayList;
public class TesteArrayList {
public static void main(String[] args) {
//Cria objetos da classe Funcionario
Funcionario func1 = new Funcionario("Joao", 35);
Funcionario func2 = new Funcionario("Gerson", 42);
Funcionario func3 = new Funcionario("Renato", 27);
//Adiciona os funcionarios no ArrayList
ArrayList funcionarios = new ArrayList();
funcionarios.add(func1);
funcionarios.add(func2);
funcionarios.add(func3);
imprimeFuncionarios(funcionarios);
System.out.println("O funcionario 1 serah removido...");
Funcionario funcRemovido =
(Funcionario) funcionarios.remove(1);
System.out.println("Funcionario removido: " + funcRemovido);
imprimeFuncionarios(funcionarios);
}
private static void imprimeFuncionarios(ArrayList funcionarios){
Funcionario func;
System.out.println("Qtde de funcionarios: " +
funcionarios.size());
for (int nCont = 0; nCont < funcionarios.size(); nCont++){
func = (Funcionario) funcionarios.get(nCont);
System.out.println(nCont + ": \n" + func);
}
System.out.println("-----------FIM---------------");
}
}
12
Veja a saída gerada pela execução da classe TesteArrayList:
Qtde de funcionarios: 3
0:
Funcionario: Joao
Idade: 35
1:
Funcionario: Gerson
Idade: 42
2:
Funcionario: Renato
Idade: 27
-----------FIM--------------O funcionario 1 serah removido...
Funcionario removido: Funcionario: Gerson
Idade: 42
Qtde de funcionarios: 2
0:
Funcionario: Joao
Idade: 35
1:
Funcionario: Renato
Idade: 27
-----------FIM---------------
A Interface Iterator (java.util.Iterator)
A interface Iterator é utilizada para navegar dentro
de coleções como a Set e List. As interfaces Set e List
definem o método iterator() que retorna um Iterator.
A interface Iterator, por sua vez, possui o método
hasNext() para identificar se existem mais elementos na
coleção.
Outro
método
importante
desta
classe
é
aquele
utilizado para obter o próximo elemento da coleção e que
possui a seguinte assinatura:
Object next()
13
Veja o exemplo abaixo:
import java.util.ArrayList;
import java.util.Iterator;
public class TesteIterator {
public static void main(String[] args) {
String nome1 = "Carlos";
String nome2 = "Josias";
String nome3 = "Marcos";
String nome4 = "Armando";
ArrayList nomes = new ArrayList();
nomes.add(nome1);
nomes.add(nome2);
nomes.add(nome3);
nomes.add(nome4);
Iterator iterator = nomes.iterator();
int iCont = 1;
String nome;
while (iterator.hasNext()){
nome = (String) iterator.next();
System.out.println("nome[" + iCont++ + "] = " + nome);
}
}
}
Saída gerada pela execução do programa acima:
nome[1]
nome[2]
nome[3]
nome[4]
=
=
=
=
Carlos
Josias
Marcos
Armando
OBS: Observe que a ordem de inserção dos elementos no
ArrayList foi respeitada durante a impressão na tela.
Usando Estruturas de Conjunto HashSet
A classe HashSet (java.util.HashSet)
A classe HashSet é uma das implementações da interface
Set, que não é indexada, nem ordenada por natureza. Esta
implementação de Set é ideal para buscas, mas não para
navegação seqüencial.
14
Construtores
●
HashSet(): Constrói um HashSet vazio, com capacidade
inicial de 16 posições;
HashSet(int capacidadeInicial): Constrói um HashSet
vazio com a capacidade inicial igual ao parâmetro
informado;
Métodos para adicionar elementos ao HashSet
●
●
void add(Object obj): adiciona o Object obj se o mesmo
já não estiver presente. Este método retorna true se o
elemento for inserido;
Método para verificar se o HashSet contém um determinado
elemento:
●
boolean contains(Object obj):
HashSet possui o objeto obj.
Retorna
true
se
o
Ao contrário do ArrayList que possui métodos como
get() e indexOf() para recuperar elementos ou posição de
elementos, o HashSet não possui estes métodos.
Método para remover elementos do HashSet:
●
Object remove(Object obj):
mesmo estiver presente.
Remove
o
elemento
se
o
Método para verificar o tamanho / número de elementos do
HashSet:
●
int size(): Retorna o número de elementos do HashSet;
Como a coleção Set não é indexada, devemos utilizar a
interface Iterator para navegar dentro desta coleção.
15
Veja o exemplo abaixo:
import java.util.HashSet;
import java.util.Iterator;
public class TesteHashSet {
public static void main(String[] args) {
String nome1 = "Carlos";
String nome2 = "Josias";
String nome3 = "Marcos";
String nome4 = "Armando";
HashSet nomes = new HashSet();
nomes.add(nome1);
nomes.add(nome2);
nomes.add(nome3);
nomes.add(nome4);
Iterator iterator = nomes.iterator();
int iCont = 1;
String nome;
while (iterator.hasNext()){
nome = (String) iterator.next();
System.out.println("nome[" + iCont++ + "] = " + nome);
}
}
}
Saída gerada pela execução do programa acima:
nome[1]
nome[2]
nome[3]
nome[4]
=
=
=
=
Armando
Marcos
Josias
Carlos
OBS: Observe que a ordem de inserção dos elementos no
HashSet não foi respeitada durante a impressão na tela.
Usando Estruturas de Mapeamento HashMap
A classe HashMap (java.util.HashMap)
HashMap é uma implementação da interface Map. Esta
implementação não garante a ordem dos seus elementos, nem
que estarão sempre na mesma ordem.
A classe HashMap permite a inserção de null, mas vale
lembrar que a chave deve ser única, isto é, apenas uma
poderá ser igual a null.
16
Construtores

HashMap(): Constrói um HahsMap vazio com capacidade
inicial de 16 posições;
●
HashMap(int capacidadeInicial): Constrói um HashMap
vazio com a capacidade inicial igual ao parâmetro
informado;
Método para adicionar um par chave-valor no HashMap

Object put (Object chave, Object valor): Adiciona o
par chave-valor ao HashMap. Caso tente adicionar um
par chave-valor cuja chave já tenha sido adicionada
anteriormente, o valor anterior será substituído pelo
novo e o método put irá retornar o valor antigo.
Caso o par chave-valor não tenha sido adicionado
anteriormente, o método put irá retornar null.
Métodos para verificar
chave ou valor
se
o
HashMap
contém
determinada

boolean containsKey(Object chv): Retorna true se for
encontrada a chave chv;

boolean containsValue(Object vle): Retorna true se
for encontrado o valor vle.
Método para recuperar um valor do HashMap

Object get(Object chv): Retorna o valor associado à
chave chv passada como parâmetro.
OBS: Caso a chave não seja encontrada, null será retornado.
No entanto, existe a possibilidade de haver uma chave
associada ao valor null, portanto é muito importante
verificar se a chave existe no HashMap, através do método
containsKey().
Método para remover elementos do HashMap

Object remove(Object chv): Remove o par chave-valor
encontrado no HashMap.
17
Método para verificar o tamanho / número de elementos do
HashMap

int size(): Retorna o número de pares chave-valor
encontrados no HashMap.
O exemplo abaixo utiliza um hashMap.
Pessoa.java
public class Pessoa {
private String nome;
private String cpf;
public Pessoa (String nome, String cpf){
this.nome = nome;
this.cpf = cpf;
}
public String getCpf() {
return cpf;
}
public void setCpf(String cpf) {
this.cpf = cpf;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public String toString(){
String str = "Nome: " + getNome();
str += "\nCPF: " + getCpf();
return str;
}
public boolean equals(Object o){
if (o instanceof Pessoa){
Pessoa p = (Pessoa) o;
//Verifica se o CPF das pessoas são iguais
if (this.getCpf().equals(p.getCpf()))
return true;
else
return false;
}
else
return false;
}
}
18
TesteHashMap.java
import java.util.*;
public class TesteHashMap {
public static void main (String args[]){
String cpf1 = "251";
Pessoa p1 = new Pessoa ("Carlos", cpf1);
String cpf2 = "573";
Pessoa p2 = new Pessoa ("Roberto", cpf2);
String cpf3 = "952";
Pessoa p3 = new Pessoa ("Matheus", cpf3);
HashMap pessoas =
pessoas.put(cpf1,
pessoas.put(cpf2,
pessoas.put(cpf3,
new HashMap();
p1);
p2);
p3);
imprimirMapPessoas(pessoas);
String chave = "952";
removerElemento(pessoas, chave);
imprimirMapPessoas(pessoas);
}
public static void imprimirMapPessoas(HashMap pessoas){
Set chaves = pessoas.keySet();
Iterator iTer = chaves.iterator();
String chave;
Pessoa p;
System.out.println("\n --- HashMap de Pessoas ---");
while (iTer.hasNext()){
chave = (String) iTer.next();
p = (Pessoa) pessoas.get(chave);
System.out.println("Chave: " + chave);
System.out.println(p + "\n");
}
}
public static void removerElemento(HashMap map, String chave){
Pessoa pessoaRemovida = null;
if (map.containsKey(chave)){
System.out.println("\n --- Pessoa removida do
hashMap ---");
pessoaRemovida = (Pessoa) map.remove(chave);
System.out.println(pessoaRemovida);
}
else{
System.out.println("CPF (chave) nao encontrada no
hashMap");
}
}
}
19
Classificando Listas
A classe Collections (Java.util.Collections)
Arrays e implementações da interface List, usualmente,
são utilizadas para armazenar objetos de mesma classe.
Contudo, esses objetos são armazenados segundo a ordem de
inclusão. Muitas vezes é interessante que, após a inclusão
de todos os objetos, haja uma ordenação usando a "ordem
natural".
Para
conseguirmos
essa
ordenação,
contudo,
é
necessário definirmos a "ordem natural", significando que a
classe a ser armazenada na List precisa implementar a
interface Comparable juntamente com seu método compareTo().
Ao se analisar a documentação das implementações de
List, percebe-se que não existe um método que faça a
ordenação.
Para fazer esta ordenação podemos empregar o método
estático sort da classe utilitária Collections. Isso
significa
que
ao
executarmos
o
método
Collections.sort(List),
a
lista
tornar-se-á
ordenada
segundo a sua ordem natural.
A interface Comparable (Java.lang.Comparable)
Esta interface define classes que são ordenáveis, ou
seja, que podem ser automaticamente ordenadas por coleções
ou outras classes.
A interface Comparable define um método que servirá
como regra de ordenação das instâncias da classe que a
implementa. Essa padronagem é denominada ordem natural, que
é uma regra que deve ser utilizada para saber a precedência
dos objetos.
Assinatura do método:
int CompareTo(Object o)
Podemos
exemplificar
com
a
classe
String,
que
implementa esta interface e sua implementação de comparação
faz a análise caracter a caracter para definição da
ordenação de Strings.
20
Logo, pelo conceito de ordem natural da String, a
instância "automóvel" estaria localizada antes da instância
"barco", pois se compararmos as primeiras letras da
instância, a letra 'a' antecede a letra 'b'.
Contudo, usando classes criadas durante a abstração do
modelo, nem sempre temos um parâmetro adequado para
comparar duas instâncias. Se tomarmos como exemplo uma
classe Funcionário, possuindo os atributos nome, RG e
Registro Funcional, qual dos parâmetros deve ser utilizado
para definir a "ordem natural" do objeto? E se tivermos
duas instâncias de funcionário "João da Silva" (homônimos),
qual deve ser o próximo parâmetro de ordenação? Através da
implementação desta interface é possível definir qual é a
regra de ordenação natural.
O método a ser implementado pela interface possui a
assinatura int compareTo(Object o) usada para comparação da
instância atual com qualquer outra instância da mesma
classe.
Um número negativo deverá ser retornado se o objeto
estiver "antes" daquele passado como parâmetro, zero se
forem iguais e um número positivo, se estiver "após".
Vale ressaltar que o método equals da classe que
implementa o Comparable deve ser coerente com o resultado
do método compareTo. Portanto, se as instâncias de objetos
A e B retornarem true para A.equals(B), significa que
A.compareTo(B) deverá retornar zero e vice-versa.
Vejamos agora um exemplo da utilização do
Collections.sort(List)
e
a
implementação
do
CompareTo(Object o) da interface Comparable.
Para
este
exemplo
utilizaremos
Aluno.java e TesteAluno.java.
duas
método
método
classes:
A classe Aluno possui dois atributos: nome e RA, e a
ordem natural dos objetos desta classe foi definida da
seguinte forma:
Primeiramente os objetos serão ordenados pelo atributo
"nome" seguindo a ordem alfabética e em caso de empate
(nomes iguais) será utilizado o RA como segundo critério
para desempate.
21
public class Aluno implements Comparable{
private String nome;
private long RA;
public Aluno(String nome, long RA){
this.nome = nome;
this.RA = RA;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public long getRA() {
return RA;
}
public void setRA(long ra) {
RA = ra;
}
public boolean equals(Object obj){
if (obj instanceof Aluno){
Aluno aluno = (Aluno) obj;
if(this.getNome().equalsIgnoreCase(aluno.getNome())
&& this.getRA() == aluno.getRA()){
return true;
}
else{
return false;
}
}
else
return false;
}
public int compareTo(Object obj){
Aluno aluno = (Aluno) obj;
int resp = this.getNome().compareTo(aluno.getNome());
if (resp != 0){
return resp;
}
else{
if (this.getRA() < aluno.getRA()){
return -1;
}
else if (this.getRA() > aluno.getRA()){
return 1;
}
else{
return 0;
}
}
}
public int hashCode(){
return (int)this.RA + this.getNome().hashCode();
}
public String toString(){
String aluno = "nome: " + this.getNome() + "\n" + "RA: " + this.getRA();
return aluno;
}
}
22
Note que a classe Aluno implementa
"Comparable" e o método compareTo().
a
interface
O método compareTo() faz primeiramente a comparação do
atributo "nome" dos objetos e em caso de empate faz a
comparação do atributo "RA".
A classe "Aluno" também faz a sobrescrita dos métodos
equals(), toString() e hashCode(), todos da classe Object.
Veja abaixo a implementação da classe TesteAluno.java.
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
public class TesteAluno {
public static void main (String[] args) {
Aluno aluno1 = new Aluno("Orlando", 123);
Aluno aluno2 = new Aluno("Rafael", 258);
Aluno aluno3 = new Aluno("Amanda", 642);
Aluno aluno4 = new Aluno("Bruna", 634);
Aluno aluno5 = new Aluno("Orlando", 345);
Aluno aluno6 = new Aluno("Rafaela", 942);
Aluno aluno7 = new Aluno("Amanda", 650);
ArrayList alunos = new ArrayList();
alunos.add(aluno1);
alunos.add(aluno2);
alunos.add(aluno3);
alunos.add(aluno4);
alunos.add(aluno5);
alunos.add(aluno6);
alunos.add(aluno7);
System.out.println("Imprimindo alunos antes da ordenação");
Iterator iTer1 = alunos.iterator();
while (iTer1.hasNext()){
System.out.println(iTer1.next());
}
Collections.sort(alunos);
System.out.println("\nImprimindo alunos depois da ordenação");
Iterator iTer2 = alunos.iterator();
while (iTer2.hasNext()){
System.out.println(iTer2.next());
}
}
}
23
Veja abaixo a saída
TesteAluno.java.
gerada
pela
execução
da
classe
Imprimindo alunos antes da ordenação
nome: Orlando
RA: 123
nome: Rafael
RA: 258
nome: Amanda
RA: 642
nome: Bruna
RA: 634
nome: Orlando
RA: 345
nome: Rafaela
RA: 942
nome: Amanda
RA: 650
Imprimindo alunos depois da ordenação
nome: Amanda
RA: 642
nome: Amanda
RA: 650
nome: Bruna
RA: 634
nome: Orlando
RA: 123
nome: Orlando
RA: 345
nome: Rafael
RA: 258
nome: Rafaela
RA: 942
24
Exercícios Sobre Coleções
1)
Crie uma classe chamada TesteString e dentro da
mesma faça o seguinte:
 Crie um método main;
 Dentro do main, crie 10 variáveis do tipo
String com nomes de times de futebol;
 Armazene estas strings em um arrayList;
 Remova o elemento que está na posição seis
do arrayList;
 Utilize o método get() para obter cada um
dos elementos do arrayList e imprima os
mesmos na tela.
2)
Utilize a classe Java gerada no exercício anterior
e substitua o método get() por um Iterator.
3)
O objetivo deste exercício é implementar a relação
entre uma pessoa e seus endereços. Para isto crie
três classes Java: Pessoa.java, Endereco.java e
TestePessoa.java.
Na classe Pessoa faça o seguinte:
 Crie dois atributos privados: Um do tipo
String para o nome da pessoa e outro do
tipo ArrayList para armazenar os vários
endereços da Pessoa.
 Crie todos os getters e setters para estes
atributos.
 Crie
um
construtor
alternativo
para
iniciar o atributo nome.
 Crie um método chamado "imprimirEnderecos1"
e dentro do mesmo utilize o método get()
do ArrayList para obter cada um dos
endereços da Pessoa e imprima os mesmos na
tela. Utilize toString().
 Crie um método chamado "imprimirEnderecos2"
e dentro do mesmo utilize um Iterator para
obter cada um dos endereços da Pessoa e
imprima
os
mesmos
na
tela.
Utilize
toString().
Na classe Endereco faça o seguinte:
 Crie três atributos privados: um do tipo
String para o logradouro e outro também do
tipo String para o complemento e um do
tipo int para o número.
25


Crie os métodos getters e setters para
cada um dos atributos.
Sobrescreva o método toString() da classe
Object para gerar uma String com os três
atributos da classe.
Na classe TestePessoa faça o seguinte:
 Crie um método main.
 Dentro do main crie um objeto da classe
Pessoa e outro da classe ArrayList.
 Crie um laço de repetição e utilize os
métodos
da
classe
JOptionPane
para
solicitar ao usuário o logradouro, número
e complemento.
 Armazene estas informações em um objeto da
classe Endereco e armazene este endereço
no ArrayList.
 Pergunte ao usuário se o mesmo deseja
informar
mais
endereços
e
em
caso
afirmativo repita o processo.
 Se o usuário não quiser mais informar
endereços, encerre o laço de repetição.
 O objeto do tipo ArrayList que foi
utilizado para guardar os endereços deve
ser armazenado no objeto da classe pessoa
que foi criado anteriormente.
 Chame o método imprimirEnderecos1 e em
seguida chame o método imprimirEnderecos2,
ambos da classe Pessoa.
4)
Crie uma classe Java chamada TesteHashSet.java e
dentro da mesma faça o seguinte:
 Crie um atributo privado chamado código (int).
 Crie os métodos para acessar e alterar o valor
deste atributo.
 Sobrescreva o método equals da classe Object e
dentro do mesmo retorne "true" se o código
passado com parâmetro for igual ao código do
objeto e "false" caso contrário.
 Sobrescreva o método hashCode da classe Object
e dentro do mesmo retorne o valor do atributo
código.
 Crie um método main.
 Dentro do main faça um laço de repetição e
peça para o usuário digitar um número que será
código de uma pessoa.
 Armazene este código em um objeto da classe
TesteHashSet e armazene o objeto em um
hashSet.
26



5)
Caso o código já tenha sido armazenado no
hashSet, imprima um aviso ao usuário e peça
para fornecer outro. OBS: Não se esqueça que é
da própria natureza de um hashSet não permitir
a inclusão de elementos repetidos.
Depois que o usuário não desejar mais informar
códigos, encerre o laço de repetição.
Utilize um Iterator para imprimir na tela
todos os códigos informados pelo usuário.
Utilize a classe Pessoa.java abaixo e crie uma
classe chamada TestePessoa.java. Dentro da classe
TestePessoa, crie um método main e faça o seguinte:
 Crie vários objetos da classe Pessoa (com
CPF e nome);
 Crie um objeto da classe HashMap;
 Crie um método chamado inserir que recebe
como parâmetro um CPF, um objeto da classe
Pessoa e o objeto da classe HashMap;
 Dentro deste método inseria o par CPFPessoa no HashMap. Antes de
inserir
certifique-se que o par CPF-Pessoa já não
foi inserido anteriormente. Caso o par já
tenha sido inserido, não insira o mesmo;
 Dentro do main faça um laço de repetição
para imprimir na tela o par CPF-Pessoa;
27
Download