Transparências - LES - PUC-Rio

Report
Orientação a Objetos com Java
Carlos Lucena
[email protected]
Cidiane Lobato
[email protected]
Karla Damasceno
[email protected]
Andrew
[email protected]
Conceitos de Orientação a Objetos
Objetos
• Objeto de Software: uma entidade identificada com
estado e comportamento específicos.
• O estado é mantido através de variáveis; o
comportamento é implementado por métodos.
Objeto Bicicleta
Objeto Genérico
© LES/PUC-Rio
3
Objetos
• No modelo de um objeto, as variáveis são mantidas no
centro, ou núcleo, do objeto.
• Os métodos “rodeiam” e “escondem” o núcleo do objetos
dos outros objetos em uma programa.
• O “empacotamento” das variáveis de um objeto por seus
métodos é denominado encapsulamento.
• Esta concepção de um núcleo de variáveis protegido pelos
métodos de um objeto é considerada por muitos como a
representação ideal de um objeto de software.
© LES/PUC-Rio
4
Mensagens
• Objetos interagem e se comunicam através de mensagens.
• Quando um objeto A deseja que um objeto B execute um de
seus métodos, A envia uma mensagem a B.
• Informações passadas através de uma mensagem são os
parâmetros do método a ser executado.
© LES/PUC-Rio
5
Classes
• Classe: é um modelo que define as variáveis e os métodos
comuns a todos os objetos de um certo tipo.
Classe
Objetos
© LES/PUC-Rio
6
Classes
• Uma variável de classe contém informação compartilhada
por todas as instâncias de uma classe.
© LES/PUC-Rio
7
Herança
• Herança: relacionamento entre classes através do qual as
variáveis e os métodos de uma superclasse são herdados
por suas subclasses.
© LES/PUC-Rio
8
Herança
• Subclasse: uma classe que deriva de outra classe.
• Superclasse: ancestral direto de uma classe ou quaisquer
ascendentes de uma classe.
• Uma subclasse herda todas as variáveis e métodos de sua
superclasse. Contudo, a subclasse pode não ter acesso
aos elementos herdados.
• Herança Múltipla: cada classe possui mais de uma
superclasse direta.
© LES/PUC-Rio
9
Herança
• Subclasses podem adicionar variáveis e métodos àqueles
herdados da superclasse.
• Subclasses também podem sobrescrever métodos
herdados, fornecendo implementação especializada para
estes métodos.
• A árvore de herança ou hierarquia de classes pode ser tão
profunda quanto necessário.
• Em geral, quanto mais abaixo na hierarquia, mais
especializado é o comportamento de uma classe.
© LES/PUC-Rio
10
Interface
• Interface: é um contrato na forma de uma coleção de
métodos e declarações de constantes.
• Quando uma classe implementa uma interface, se
compromete a fornecer uma implementação para todos os
métodos declarados na interface.
• Uma classe pode implementar múltiplas interfaces.
© LES/PUC-Rio
11
Classe X Interface
• Para compreender a diferença entre classe e interface, é
necessário antes entender o conceito de tipo de objeto:
– define o conjunto de solicitações às quais ele pode atender;
– define o que o objeto é capaz de fazer;
– representa a interface do objeto;
– é uma promessa de serviços.
• Então o tipo de um objeto é o mesmo que sua classe?
– A classe de um objeto define o estado interno de um objeto e a
implementação de suas operações.
– A classe define como o objeto é implementado.
– Representa a implementação do objeto.
– É o cumprimento de uma promessa de serviços.
© LES/PUC-Rio
12
Classe X Interface
• Sem compreender tipo e classe, não há como entender
herança de tipo e herança de implementação...
• Herança de classe (ou de implementação):
– Define a implementação de um objeto em função da
implementação de outro.
– Mecanismo para compartilhamento de código.
• Herança de tipo (ou de interface):
– Define quando um objeto pode ser utilizado no lugar do outro...
– ...cumprindo a mesma promessa que o outro prometeu.
© LES/PUC-Rio
13
Classe X Interface
Herança de Classe
Implementação da mesma forma que o outro implementa!!!
Herança de Tipo
Implementação do que o outro promete!!!
Herança de Classe X Herança de Tipo
A herança de implementação também implica herança de tipo!!!
© LES/PUC-Rio
14
Mas então... Quando usar herança?
• O objeto é “um tipo especial de”...
Transação
Reserva
Dispositivo
Compra
Mouse
Teclado
• e não “um papel assumido por”!
Pessoa
Tripulante
Passageiro
© LES/PUC-Rio
Agente
15
Mas então... Quando usar herança?
• O objeto nunca tem que mudar para outra classe!
Dispositivo
Mouse
Um Tripulante de um vôo pode
ser Passageiro de outro.
Teclado
Um Mouse nunca
vai se tornar um
Teclado
Pessoa
Tripulante
© LES/PUC-Rio
Passageiro
Agente
16
Mas então... Quando usar herança?
• As subclasses não sobrescrevem métodos da superclasse
(apenas adicionam!).
Superclasse
desenhar()
testar()
Sobrescreve tudo!?
Pra que herdar???
Superclasse
desenhar()
testar()
SubclasseA
SubclasseB
SubclasseA
SubclasseB
imprimir()
executar()
desenhar()
testar()
desenhar()
testar()
Novas funcionalidades...
Compartilha código!
© LES/PUC-Rio
17
Outros conceitos… Polimorfismo
• Polimorfismo: termo usado para significar que uma
chamada de método pode ser executada de várias “formas”
(ou polimorficamente), sendo que quem decide a “forma” é
o objeto que recebe a chamada.
• Por exemplo:
– Se um objeto "a" chama um método grita() de um objeto "b",
então o objeto "b" decide a forma de implementar o método.
– A chamada b.grita() vai ser um grito humano se "b" for um
humano e será um grito de macaco, se o objeto "b" for um
macaco. O que importa, portanto, é o tipo do objeto "b".
© LES/PUC-Rio
18
Outros conceitos… Relacionamentos
• Para que objetos se comuniquem eles precisam se
relacionar. São possíveis os seguintes tipos de
relacionamento:
– Herança; 
– Associação;
• Agregação;
– Composição;
– Dependência.
• Uma seqüência de comunicação entre objetos para a
realização de um serviço é denominada delegação.
© LES/PUC-Rio
19
Relacionamentos entre Classes
• Herança: relacionamento entre itens gerais (superclasse) e
itens mais específicos (subclasses). 
– Por exemplo: em uma universidade, Comando e Matrícula.
• Associação: relacionamento que indica que os objetos de
uma classe estão vinculados a objetos de outra classe.
– Por exemplo: no “DAR” de uma universidade, existem
associações entre Turma e Aluno, Professor e Disciplina, etc.
• Agregação: tipo de associação utilizada para indicar um
relacionamento ”todo-parte”; um objeto “parte” pode fazer
parte de vários objetos “todo”.
– Por exemplo, Pedido e Item, Universidade e Curso, etc.
© LES/PUC-Rio
20
Relacionamentos entre Classes
• Composição: é uma variante semanticamente mais ”forte”
da agregação em que objetos “parte” só pertencem a um
único “todo” e têm o tempo de vida coincidente com o dele.
– Por exemplo, Notebook e Teclado, Window e Frame, etc.
• Dependência: relacionamento de utilização entre dois
itens, no qual a alteração de um (o item independente)
pode afetar o outro (o item dependente).
– Por exemplo, Cliente e Fornecedor, etc.
© LES/PUC-Rio
21
Conceitos de Orientação
a Objetos em Java
Classes em Java
• Classe: é um modelo que define as variáveis e os métodos
comuns a todos os objetos de um certo tipo.
© LES/PUC-Rio
23
Classes em Java
• A classe anterior contém o código que implementa o ciclo de
vida dos objetos instanciados a partir da classe:
– construtores para inicialização de novos objetos;
– variáveis que mantém o estado da classe e de seus objetos;
– métodos que implementam o comportamento da classe e de
seus objetos.
• Além dos elementos acima (construtores, variáveis e
métodos), é possível especificar outras informações:
– nome de uma possível superclasse;
– implementação de interfaces;
– se a classe pode ser herdada, etc.
© LES/PUC-Rio
24
Classes em Java
Elemento
Função
public
(Opcional) Classe é publicamente acessível
abstract
(Opcional) Classe não pode ser instanciada
final
(Opcional) Classe não pode ter subclasses
class NameOfClass
(Obrigatório) Nome da classe
extends Super
(Opcional) Superclasse da classe
implements Interfaces
(Opcional) Interfaces implementadas pela classe
{ ClassBody }
(Obrigatório) Fornece a funcionalidade da classe
© LES/PUC-Rio
25
Classes em Java
• public: declara que a classe pode ser usada por qualquer
outra classe. Sem “public”, uma classe pode ser usada
somente por classes no mesmo pacote.
• abstract: especifica uma classe abstrata a partir da qual
não é possível criar uma instância (ex. abstract class
Number: class Integer e class Float).
• final: a classe não pode possuir subclasses (ex. String).
• extends Super: identifica Super como superclasse;
• implements Interfaces: enumera as interfaces
implementadas pela classe.
© LES/PUC-Rio
26
Interfaces de Java
• Interface: é uma coleção nomeada de definições de
métodos, sem as respectivas implementações.
• Diferenças entre Interfaces e Classes Abstratas:
– uma interface não pode implementar métodos, ao passo que
uma classe abstrata pode;
– uma classe pode implementar muitas interfaces mas não pode
ter mais que uma superclasse;
– uma interface não é parte da hierarquia de classes;
– classes não-relacionadas podem implementar a
mesma interface.
© LES/PUC-Rio
27
Herança em Java
© LES/PUC-Rio
28
Herança em Java
• A classe Object é o topo da hierarquia de classes, sendo
cada classe sua descendente.
• Portanto, uma variável Object pode armazenar uma
referência para qualquer objeto (uma classe ou vetor).
• A classe Object provê comportamentos compartilhados por
todos os objetos sendo executados na JVM.
• Por exemplo, todas as classes herdam o método “toString”
da classe Object, que retorna uma representação em string
para um objeto.
© LES/PUC-Rio
29
Polimorfismo em Java
• Presente em todas as chamadas de métodos:
– um objeto "a" possui uma referência para o objeto "b", e
realiza a chamada b.m(), que pode ser executa de várias
formas, dependendo do tipo de “b”. Seguem exemplos:
class A {
void façaAlgo() {
//O objeto "a" cria o objeto "b"
Gritador b;
if(...) {
b = new Humano();
} else {
b = new Macaco();
}
b.grita(); // chamada polimórfica
}
}
© LES/PUC-Rio
30
Polimorfismo em Java
class A {
void façaAlgo() {
// O objeto "a" recebe o objeto "b" de um objeto "c“.
// "c" é um objeto qualquer para o qual se tem referência.
Gritador b = c.meDêUmGritador();
b.grita(); // chamada polimórfica
}
}
class A {
//O objeto "a" recebe o objeto "b" numa chamada de método.
void façaAlgo(Gritador b) {
b.grita(); // chamada polimórfica
}
}
• Não existe polimorfismo em métodos de classe!
© LES/PUC-Rio
31
Polimorfismo em Java
• O polimorfismo existe em chamadas a métodos definidos
em interfaces e superclasses. Exemplo com interfaces:
interface Gritador { void grita(); }
class Humano implements Gritador {
public void grita() {System.out.println("AAHHAAHHAAHHA"); // Me
Tarzan!}
}
class Macaco implements Gritador {
public void grita() {System.out.println("IIHIIHHIIHHII"); // Me
Cheetah! }
}
© LES/PUC-Rio
32
Polimorfismo em Java
• A herança de implementação também permite fazer polimorfismo,
porque permite criar classes que implementam o mesmo tipo.
class UmGritador {
public grita() { System.out.println("Buuuuu"); }
}
class Humano extends UmGritador {
public void grita() { System.out.println("AAHHAAHHAAHHAA"); }
}
• Ao herdar, a subclasse Humano faz o override (substituição,
sobrecarga de) alguns métodos. A classe Humano decidiu gritar de
forma diferente! 
© LES/PUC-Rio
33
Polimorfismo em Java
• Para fazer polimorfismo, é melhor usar herança de tipo ou
herança de implementação?
– É preferível usar herança de tipo para fazer polimorfismo e
– usar herança de implementação apenas para fatorar código
comum entre várias classes.
• Em outras palavras:
– defina comportamentos ("ser um gritador") com tipos abstratos
(interfaces) e use-os no polimorfismo;
– defina implementações (“como gritar”) com classes e use
superclasses para fatorar implementações comuns.
© LES/PUC-Rio
34
Relacionamentos entre Classes em Java
• Herança: em Java, é implementada através dos operadores
implements (herança de tipo) e extends (herança de
implementação). Ex: Gritador, Humano e Macaco.
• Associação: em Java, é implementada através da
declaração de atributos.
– Quanto o atributo é uma coleção, tem-se uma agregação ou
composição de objetos.
– Ex.: no “DAR” de uma universidade, a associação entre
Professor e Disciplina, etc.
class Professor{
Collection
disciplinas;
...
}
class Disciplina{
Professor
professor;
...
}
Agregação
Associação Simples
© LES/PUC-Rio
35
Relacionamentos entre Classes em Java
• Dependência: em Java, existe tal relacionamento entre
duas classes quando:
– uma classe utiliza outra somente como parâmetro de
entrada na assinatura de ao menos uma de suas operações;
– uma classe utiliza outra somente como variável local de ao
menos um de seus métodos.
• Por exemplo, no “DAR” de uma universidade, entre as
classes Universidade e Departamento:
class Universidade{
Collection
departamentos;
...
}
class Universidade{
...
getDisciplinas(Departamento d)...
}
Dependência
Agregação
© LES/PUC-Rio
36
Aplicação ClickMeApp
• ClickMeApp: possui um componente GUI chamado
ClickMe; um círculo aparece quando clicamos com o mouse
dentro da área do componente ClickMe.
• São compiladas as classes ClickMeApp, ClickMe e Spot.
Outras classes fornecidas por Java são utilizadas.
© LES/PUC-Rio
37
Aplicação ClickMeApp: Classe Spot
public class Spot {
//instance variables
private int size;
public int x, y;
//constructor
public Spot() { x = -1; y = -1; size = 1; }
//methods for access to the size instance variable
public void setSize(int newSize) {
if (newSize >= 0) { size = newSize; }
}
public int getSize() {
return size;
}
}
© LES/PUC-Rio
38
Aplicação ClickMeApp: Classe ClickMe (I)
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import java.awt.*;
import java.awt.event.*;
public class ClickMe extends JComponent
implements MouseListener {
private Spot spot = null;
private static final int RADIUS = 7;
private Color spotColor = new Color(107, 116, 2); //olive
//...
© LES/PUC-Rio
39
Aplicação ClickMeApp: Classe ClickMe (II)
//...
/** Creates and initializes the ClickMe component. */
public ClickMe() {
addMouseListener(this);
//Hint at good sizes for this component.
setPreferredSize(new Dimension(RADIUS * 30, RADIUS * 15));
setMinimumSize(new Dimension(RADIUS * 4, RADIUS * 4));
//Request a black line around this component.
setBorder(BorderFactory.createLineBorder(Color.BLACK));
}
//...
© LES/PUC-Rio
40
Aplicação ClickMeApp: Classe ClickMe (III)
/**
* Paints the ClickMe component. This method is
* invoked by the Swing component-painting system.
*/
public void paintComponent(Graphics g) {
/**
* Copy the graphics context so we can change it.
* Cast it to Graphics2D so we can use antialiasing.
*/
Graphics2D g2d = (Graphics2D)g.create();
//...
© LES/PUC-Rio
41
Aplicação ClickMeApp: Classe ClickMe (IV)
//Turn on antialiasing so that painting is smooth.
g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
//Paint the background.
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, getWidth() - 1, getHeight() - 1);
//Paint the spot.
if (spot != null) {
int radius = spot.getSize();
g2d.setColor(spotColor);
g2d.fillOval(spot.x - radius, spot.y - radius, radius *
2, radius * 2);
}
} //...
© LES/PUC-Rio
42
Aplicação ClickMeApp: Classe ClickMe (V)
//Methods required by the MouseListener interface.
public void mousePressed(MouseEvent event) {
if (spot == null) {
spot = new Spot();
spot.setSize(RADIUS);
}
spot.x = event.getX();
spot.y = event.getY();
repaint();
}
public void mouseClicked(MouseEvent event) {}
public void mouseReleased(MouseEvent event) {}
public void mouseEntered(MouseEvent event) {}
public void mouseExited(MouseEvent event) {}
}
© LES/PUC-Rio
43
Aplicação ClickMeApp: Classe ClickMeApp (I)
import javax.swing.SwingUtilities;
import javax.swing.JLabel;
import javax.swing.JFrame;
import java.awt.BorderLayout;
public class ClickMeApp implements Runnable {
/* This constructor creates an instance of ClickMeApp, which
creates and shows a window containing a ClickMe component. */
public ClickMeApp() {
/* Tells the event-dispatching thread (used to display and
handle events of a Swing GUI) to call the run method of "this"
(the ClickMeApp object this constructor created). The
argument to invokeLater must implement the Runnable
interface, which guarantees that it defines the run method. */
SwingUtilities.invokeLater(this);
} //...
© LES/PUC-Rio
44
Aplicação ClickMeApp: Classe ClickMeApp (II)
/**
* Creates and shows the GUI. This method should be
* invoked on the event-dispatching thread.
*/
public void run() {
createAndShowGUI();
}
/**
* Brings up a window that contains a ClickMe component.
* For thread safety, this method should be invoked from
* the event-dispatching thread.
*/
private static void createAndShowGUI() { //...
© LES/PUC-Rio
45
Aplicação ClickMeApp: Classe ClickMeApp (III)
//Make sure we have nice window decorations.
JFrame.setDefaultLookAndFeelDecorated(true);
//Create and set up the window.
JFrame frame = new JFrame("ClickMeApp");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Set up the layout manager.
frame.setLayout(new BorderLayout());
//Add the ClickMe component.
ClickMe component = new ClickMe();
frame.add(component, BorderLayout.CENTER);
//...
© LES/PUC-Rio
46
Aplicação ClickMeApp: Classe ClickMeApp (IV)
//Add an explanatory label.
frame.add(new JLabel("Click within the rectangle."),
BorderLayout.SOUTH);
//Display the window.
frame.pack();
frame.setVisible(true);
}
//This method is automatically executed.
public static void main(String[] args) {
//Create an instance of ClickMeApp.
new ClickMeApp();
}
}
© LES/PUC-Rio
47
Generics - Introdução
• Até a versão 1.4 do Java (JDK 1.4) as classes de coleção
(Vector, Hashtable , Array e etc) guardavam objetos do tipo
Object.
• Objetos de quaisquer classes podiam ser inseridos em uma
coleção, uma vez que todas as classes são descendentes de
Object.
• Quando um objeto era retirado da coleção era necessário
descobrir o seu tipo e, então, realizar um cast.
© LES/PUC-Rio
48
Cast de Um Elemento de Uma Coleção
import java.util.*;
public class ClasseX
{
private Vector lista=new Vector();
public void op1()
{
String p;
// código do método
for(int i=0;i<lista.size();i++)
{
p=(String) lista.get(i);
}
}
}
© LES/PUC-Rio
49
Generics - Motivação
• Este tipo de programação não é segura, pois apenas em
tempo de execução é possível saber o tipo de um elemento
de uma coleção.
• No exemplo anterior, se lista.get(i) não for um objeto do
tipo String ocorrerá uma exceção.
• Para tornar a programação mais segura, a Sun introduziu o
conceito de generics a partir da versão 1.5 do Java.
• Com o uso dos generics é possível definir que uma coleção
armazene um tipo específico de objetos.
• Dessa forma, não será necessário realizar um cast quando
se retirar um elemento de uma coleção, permitido assim
que a verificação de tipos seja feita em tempo de
compilação.
© LES/PUC-Rio
50
Declaração
• O primeiro passo para criar uma coleção de um determinado
tipo é declarar a coleção e o tipo desejado entre chaves
angulares:
private Vector<Integer> lista;
• O segundo passo é criar um objeto Vector que armazene
apenas objetos do tipo Integer:
lista=new Vector<Integer>();
© LES/PUC-Rio
51
Iteração
• Veja que agora para iterar sobre uma coleção e obter os
elementos armazenados na mesma, não é mais necessário
realizar um cast:
Integer p;
// código do método
for(int i=0;i<lista.size();i++)
{
p=lista.get(i);
System.out.println(p);
}
© LES/PUC-Rio
52
Exemplo Completo
import java.util.*;
public class ClasseX
{
private Vector<Integer> lista;
public void op1()
{
Integer p;
// código do método
for(int i=0;i<lista.size();i++)
{
p=lista.get(i);
System.out.println(p);
}
}
ClasseX(Integer s)
{
lista=new Vector<Integer>();
lista.add(s);
}
}
© LES/PUC-Rio
53
API Orientada a Objetos de Java
Hierarquia de Collections
Introdução
• Coleção: é um objeto que agrupa múltiplos elementos em
uma única unidade para armazenar, recuperar e manipular
dados agregados.
• Representa itens de dados que formam um grupo “natural”,
como uma caixa de emails ou uma lista telefônica.
• Implementações de coleção em versões Java pré-1.2
incluíam Vector, Hashtable e Array, mas não existia ainda
um “framework de coleções”.
© LES/PUC-Rio
55
Introdução
• Framework de coleções: é uma arquitetura unificada para
representar e manipular coleções, contendo:
– interfaces: tipos abstratos de dados que representam
coleções. Permitem que coleções sejam manipuladas
independentemente de sua representação;
– implementações: implementações concretas das interfaces de
coleção. São estruturas de dados reusáveis;
– algoritmos: métodos que realizam computações úteis, tais
como busca e ordenação sobre objetos que implementam as
interfaces de coleção. São ditos “polimórficos”: o mesmo
método pode ser usado em diferentes implementações da
interface de coleção apropriada. São funções reusáveis.
© LES/PUC-Rio
56
Interfaces
• Formam uma hierarquia de diferentes tipos de coleções que
permitem a manipulação de dados independentemente de
sua representação.
• Set é um tipo especial de Collection, SortedSet é um tipo de
Set, etc. Note que a hierarquia consiste de duas árvores
diferentes: um Map não é um Collection verdadeiro.
© LES/PUC-Rio
57
Interfaces
• Todas as interfaces de coleção são genéricas.
– public interface Collection<E>...
– <E> significa que a interface é genérica.
• Quando uma instância de Collection é declarada, deve-se
especificar o tipo de objeto contido na coleção:
– List<String> list = new ArrayList<String>;
• Isto permite verificar em tempo de compilação se o tipo de
objeto a ser armazenado na coleção está correto.
© LES/PUC-Rio
58
Interfaces
• Collection: a raiz da hierarquia de coleções.
– É usada quando uma generalidade máxima é necessária.
– Java não provê implementações diretas desta interface.
• Set: coleção que não pode conter elementos duplicados.
– Modela a abstração matemática de conjuntos.
– Exemplo: processos executando em uma máquina.
• List: chamada de seqüência, é uma coleção não ordenada.
– Pode conter elementos duplicados.
– O usuário de List pode controlar a posição em que um
elemento é inserido e acessa elementos através de um índice.
– Corresponde à noção de “vetores”.
© LES/PUC-Rio
59
Interfaces
• Queue: coleção de elementos com prioridades associadas.
– Provê operações de inserção, extração e inspeção.
– Tipicamente ordena elementos no esquema FIFO.
– Entre as exceções, estão as “filas de prioridade”.
• Map: objeto que mapeia chaves e valores.
– Não pode conter chaves duplicadas.
– Corresponde ao uso de Hashtables.
• SortedSet: Set com elementos em ordem ascendente.
• SortedMap: Map com chaves em ordem ascendente.
© LES/PUC-Rio
60
Interface Collection: Operações
public interface Collection<E> extends Iterable<E> {
//Basic operations
int size();
boolean isEmpty();
boolean contains(Object element);
boolean add(E element); //optional
boolean remove(Object element); //optional
Iterator iterator();
//Bulk operations
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c); //optional
boolean removeAll(Collection<?> c); //optional
boolean retainAll(Collection<?> c); //optional
void clear(); //optional
//Array operations
Object[] toArray();
<T> T[] toArray(T[] a);
}
© LES/PUC-Rio
61
Interface Collection: Iterador
• Iterador: objeto que permite percorrer uma coleção e
remover elementos seletivamente.
public interface Iterator<E> {
boolean hasNext();
E next();
void remove(); //optional
}
– hasNext() retorna true se a iteração possui mais elementos e
next() retorna o próximo elemento na iteração.
– remove() remove o último elemento retornado pelo next():
pode ser chamado somente uma vez por next() e levanta uma
exceção caso esta regra seja violada.
© LES/PUC-Rio
62
Interface Collection: Iterador
• O seguinte método mostra como usar um Iterator para
filtrar uma coleção, isto é, remover elementos específicos.
static void filter(Collection c) {
for (Iterator i = c.iterator(); i.hasNext(); )
if (!cond(i.next())) i.remove();
}
• O código acima é polimórfico: funciona para qualquer
Collection (sem levar em conta a implementação)!
© LES/PUC-Rio
63
Interface Collection e Arrays
• Os métodos toArray são providos como uma ponte entre
coleções e APIs antigas baseadas em arrays.
• A forma mais simples cria um novo array de Object; a mais
complexa permite que o chamador especifique o tipo.
– Suponha que “c” é um Collection; então o uso mais simples:
Object[] a = c.toArray()
– Sabe-se que “c” contém strings; então a forma complexa:
String[] a = c.toArray(new String[0])
© LES/PUC-Rio
64
Interface Set: Implementações
• Set implementa a abstração matemática de conjuntos:
contém somente métodos herdados de Collection e
adiciona a restrição de que duplicações não são possíveis.
• Java dispõe de três implementações de Set:
– HashSet: elementos em uma tabela hash, melhor performance
e nenhuma garantia quanto à ordem de iteração.
– TreeSet: elementos em uma árvore vermelho-preto,
substancialmente mais lento que HashSet e ordena elementos
baseados em seus valores.
– LinkedHashSet: elementos em uma tabela hash associada a
uma lista encadeada, apenas um pouco mais lento que HashSet
e ordena elementos por ordem de inserção.
© LES/PUC-Rio
65
Interface Set: Operações
public interface Set<E> extends Collection<E> {
//Basic operations
int size();
boolean isEmpty();
boolean contains(Object element);
boolean add(E element); //optional
boolean remove(Object element); //optional
Iterator iterator();
//Bulk operations
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c); //optional
boolean removeAll(Collection<?> c); //optional
boolean retainAll(Collection<?> c); //optional
void clear(); //optional
//Array operations
Object[] toArray();
<T> T[] toArray(T[] a);
}
© LES/PUC-Rio
66
Interface Set: Operacões
• Adaptação de métodos Collection para Set ( “s” é um Set):
– s.size(): retorna a cardinalidade de “s”;
– s.isEmpty(): retorna um booleano indicando se “s” é {};
– s.add(E): adiciona elemento especificado a “s” se este não está
presente e retorna booleano indicando se houve adição;
– s.remove (Object): remove elemento especificado de “s” e
retorna booleano indicando se houve remoção;
– s.iterator(): retorna um Iterator de s;
– s1.containsAll(s2): retorna true se s2 é subconjunto de s1;
– s1.addAll(s2): transforma s1 na união de s1 e s2;
– s1.retainAll(s2): transforma s1 na interseção de s1 e s2;
– s1.removeAll(s2): transforma s1 na diferença entre s1 e s2;
– s.toArray(): o mesmo que para Collection.
© LES/PUC-Rio
67
Interface Set: Exemplo
• O programa seguinte toma palavras em args[] e imprime:
– uma mensagem que indica se há duplicação de palavras,
– o múmero de palavras distintas e
– uma lista das plavras duplicadas eliminadas.
import java.util.*;
public class FindDups {
public static void main(String args[]) {
Set<String> s = new HashSet<String>();
for (String a : args)
if (!s.add(a))
System.out.println("Duplicate: " + a);
System.out.println(s.size()+" distinct words: "+s);
}
}
© LES/PUC-Rio
68
Interface Set: Exemplo
• Note que o código sempre se refere ao Collection por Set
(interface) em vez de HashSet (implementação).
– Esta prática é fortemente recomendada, porque torna possível
flexibilizar a mudança de tipo de implementação apenas pela
mudança do construtor.
– Ao contrário, se variáveis referentes a uma coleção ou a
parâmetros usados são declarados a partir de tipos de
implementação, todas elas deverão também ser modificadas.
– Isto vale para o uso de interfaces e implementações em geral!
© LES/PUC-Rio
69
Interface Set: Exemplo
• Saída do programa; ex. “java FindDups i came i saw i left”:
Duplicate: i
Duplicate: i
4 distinct words: [i, left, saw, came]
• Observe que HashSet não dá garantias quanto à ordem dos
elementos no Set. Para obter as palavras em ordem
alfabética, basta modificar HashSet para TreeSet.
• Por ex., nova saída para “java FindDups i came i saw i left”:
Duplicate word: i
Duplicate word: i
4 distinct words: [came, i, left, saw]
© LES/PUC-Rio
70
Interface Set: Exemplo
• Voltando ao programa FindDups...
import java.util.*;
public class FindDups2 {
public static void main(String args[]) {
Set<String> uniques = new HashSet<String>();
Set<String> dups = new HashSet<String>();
for (String a : args)
if (!uniques.add(a)) dups.add(a);
uniques.removeAll(dups);
System.out.println("Unique words: " + uniques);
System.out.println("Duplicate words: " + dups);
}
}
• Nova saída para “java FindDups2 i came i saw i left”:
Unique words: [left, saw, came]
Duplicate words: [i]
© LES/PUC-Rio
71
Interface List: Implementações
• List é um Collection ordenado que pode conter duplicações.
• Em adição às operações herdadas de Collection, List inclui
as seguintes operações:
– acesso posicional: manipulação de elementos baseada na
posição numérica destes na lista;
– busca: procura por um objeto especificado na lista e retorna
sua posição numérica;
– iteração: extende a semântica de Iterator a fim de tirar
vantagem da natureza seqüencial da lista;
– de intervalo: operações em intervalos arbitrários da lista.
• Java dispõe de duas implementações para List: ArrayList e
LinkedList (ArrayList possui a melhor performance).
© LES/PUC-Rio
72
Interface List: Operações
public interface List<E> extends Collection<E> {
//Positional access
E get(int index);
E set(int index, E element); //optional
boolean add(E element); //optional
void add(int index, E element); //optional
E remove(int index); //optional
abstract boolean addAll(int index, Collection<? extends E> c);
//optional
//Search
int indexOf(Object o);
int lastIndexOf(Object o);
//Iteration
ListIterator<E> listIterator();
ListIterator<E> listIterator(int index);
//Range-view
List<E> subList(int from, int to);
}
© LES/PUC-Rio
73
Interface List: Operações
• Operações herdadas de Collection têm a mesma semântica.
– Apenas remove() sempre remove a primeira ocorrência na
lista do elemento especificado.
– As operações add e addAll sempre adicionam os novos
elementos no final da lista.
• Operações posicionais: get, set, add e remove têm a mesma
semântica de operações em vetores.
– set e remove retornam valor antigo sobrescrito ou removido;
– addAll insere elementos começando na posição especificada.
• Operações de busca: indexOf e lastIndexOf têm a mesma
semântica de operações em vetores.
© LES/PUC-Rio
74
Interface List: Operações
• Operações de iteração: List provê um iterator sofisticado
que permite percorrer a lista em ambas direções, modificar
a lista durante a iteração e obter posição do iterador.
public interface ListIterator<E> extends Iterator<E> {
boolean hasNext();
E next();
boolean hasPrevious();
E previous();
int nextIndex();
int previousIndex();
void remove(); //optional
void set(E o); //optional
void add(E o); //optional
}
© LES/PUC-Rio
75
Interface List: Operações
• Operações de intervalo: subList(int fromIndex, int toIndex)
retorna uma visão de List que corresponde ao intervalo que
vai de “fromIndex”, inclusive, para a “toIndex”, exclusive.
© LES/PUC-Rio
76
Referências
[1] Tutorial da Sun Microsystems.
http://java.sun.com/docs/books/tutorial/java/TOC.html
© LES/PUC-Rio
77

similar documents