Iterador

Origem: Wikipédia, a enciclopédia livre.
(Redirecionado de Iterator)
Ir para: navegação, pesquisa

Os Padrões de Projeto também conhecidos como Design Patterns (em inglês) são soluções já encontradas, testadas e comprovadas e que podemos aplicar aos projetos sem ter que reinventar a roda. Diversos Padrões de Projeto já foram catalogados e são um conjunto de boas práticas que devemos seguir e utilizar em projetos de software orientados a objetos.

Padrões de Projetos basicamente descrevem soluções para problemas recorrentes no desenvolvimento de sistemas de software orientados a objetos. Um padrão de projeto estabelece um nome e define o problema, a solução, quando aplicar esta solução (contexto) e suas consequências.

Além disso, os Padrões de Projeto também definem um vocabulário comum que facilita a comunicação, documentação e aprendizado dos sistemas de software.

Os padrões de projetos são classificados como:

  • Criacionais – definem a criação de objetos;
  • Estruturais – definem a composição de classes e objetos;
  • Comportamentais – definem a interação entre classes e objetos.

Descrição[editar | editar código-fonte]

Iteradores externos e o padrão iterador[editar | editar código-fonte]

Um iterador externo pode ser imaginado como um tipo de ponteiro que possui duas operações primárias: referenciar um elemento particular na coleção de objetos (chamado elemento de acesso) e modificar a si mesmo para apontar para o próximo elemento (chamado elemento de travessia). Também deve existir uma maneira de criar um iterador para apontar para algum primeiro elemento bem como alguma maneira de determinar quando o iterador esgotou todos os elementos no container. Dependendo da linguagem e do uso pretendido, iteradores podem também fornecer operações adicionais ou exibir comportamentos diferentes.

O propósito primário de um iterador é permitir que um usuário processe cada elemento de um container enquanto isola o usuário da estrutura interna de um container. Isto permite que o container armazene elementos da maneira que ele desejar permitindo que o usuário trate-o como se ele fosse uma simples lista ou sequencia. Uma classe iterador normalmente é projetada em estreita coordenação com a classe container correspondente. Normalmente, o container fornece os métodos para criação de iteradores.

Observe que um contador de loop algumas vezes é referenciado como um iterador de loop. Um contador de loop, entretanto, apenas fornece a funcionalidade de travessia e não a funcionalidade de acesso ao elemento.

Geradores[editar | editar código-fonte]

Uma maneira de implementar iteradores é usar um tipo especial de subrotina, conhecida como um gerador, que pode produzir valores para o seu chamador várias vezes (em vez de retornar apenas um). A maioria dos iteradores são naturalmente expressíveis como geradores, mas devido aos geradores preservarem seu estado local entre as chamadas, eles são particularmente bem adaptados para iteradores stateful complexos, como atravessadores de árvore. Um exemplo de um gerador que retorna os números de Fibonacci usando declaração de produção (yield) da linguagemPython pode ser visto abaixo:

 def fibonacci():
     a, b = 0, 1
     while True:
         yield a
         a, b = b, a+b

 for numero in fibonacci():  # Utilização do gerador como um iterador
     print numero

Iteradores implícitos[editar | editar código-fonte]

Algumas linguagens orientadas a objetos como C#, Delphi (versões mais recentes), Go, Java (versões mais recentes), Lua, Perl, Python, Ruby, fornecem uma maneira intrínseca de iteração através de elementos de um objeto container sem a introdução de um objeto iterador explícito. Um objeto iterador real pode existir na realidade, mas se ele existir ele não é exposto dentro do código fonte da linguagem.

Iteradores implícitos são geralmente manifestados por uma declaração "foreach" (ou equivalente), como no seguinte exemplo em Python:

for valor in iteravel:
    print valor

Ou outras vezes eles podem ser criados por um objeto coleção propriamente dito, como neste exemplo em Ruby:

iteravel.each do |valor|
  puts valor
end

Este estilo de iteração é algumas vezes chamado "iteração interna" devido seu código executar completamente dentro do contexto do objeto iterável (que controla todos os aspectos da iteração) e o programador apenas fornecer a operação para executar em cada etapa (usando uma função anônima).

As linguagens que suportam compreensão de lista ou construções similares podem também fazer uso de iteradores implícitos durante a construção da lista de resultado, como em Python:

nomes = [pessoa.nome for pessoa in lista if pessoa.feminino]

Algumas vezes o natureza oculta implícita é apenas parcial. A linguagem C++ possui poucos templates de função, como for_each(), que permitem iteração implícita similar. Entretanto eles ainda requerem objetos interadores explícitos como sua entrada inicial. Porém uma vez inicializado a iteração subsequente ocorre implicitamente sem o uso continuado de qualquer objeto iterador exposto.

Em diferentes linguagens de programação[editar | editar código-fonte]

Java[editar | editar código-fonte]

Como sendo um padrão para percorrer listas, conjuntos, mapas etc: 

É o que você chamaria de "cursor" se estivesse escrevendo stored procedures em algum banco SQL. Portanto não é um conceito novo ou extraordinariamente difícil de manipular. 

Se você sabe que o seu List é um ArrayList, então não há problemas em usar o índice em vez de usar um Iterator. Para todos os outros tipos (LinkedList, Set, Map etc.) você tem de usar o Iterator. 

E de qualquer maneira você continua a usar o for:

// digamos que coleção seja uma coleção de BlaBleBli for (Iterator it = colecao.iterator(); it.hasNext(); ) {     BlaBleBli obj = (BlaBleBli) it.next(); }

Em Java 5, o "iterator" pode até ficar escondido:

for (BlaBleBli obj : colecao) {

No exemplo abaixo temos a classe principal MenuItem que é simplesmente um item de um menu que possui um nome, este poderia ser um menu que apareceria na seção de menu de um site, por exemplo.

class MenuItem {
   String nome;            
MenuItem(String nome) {
           this.nome = nome;       
}  
} 
interface Iterator {
   boolean hasNext();
   Object next();
 } 
public class MenuIterator implements Iterator {    MenuItem[] itens;       
int posicao = 0;
           public MenuIterator(MenuItem[] itens) { 
   this.itens = itens;     
}          
public Object next() {     
   MenuItem menuItem = itens[posicao];             posicao++;              
return menuItem;   
}          
public boolean hasNext() { 
   if (posicao >= itens.length || itens[posicao] == null) {             
   return false;   
   } else {        
           return true;            
}  
}  
} 

Python[editar | editar código-fonte]

Iteradores em Python são uma parte fundamental da linguagem e em muitos casos passam despercebidos, pois são utilizados implicitamente na declaração for (foreach), em compreensões de listas e em expressões geradoras. Todos os tipos de coleção padrões nativos de Python suportam iteração, bem como muitas classes que são parte da biblioteca padrão. O seguinte exemplo mostra uma iteração implícita típica sobre uma sequência:

 for valor in sequencia:
     print(valor)

Dicionários Python (uma forma de matriz associativa) também podem ser iterados diretamente, quando as chaves de dicionário são retornadas; ou o método items de um dicionário pode ser iterado sobre onde ele produz pares chave,valor correspondentes como uma tupla:

for chave in dicionario:
    valor = dicionario[chave]
    print(chave, valor)
for chave, valor in dicionario.items():
    print(chave, valor)

Iteradores no entanto podem ser usados e definidos explicitamente. Para qualquer tipo de seqüência iterável ou classe, a função nativa iter() é usada para criar um objeto iterador. O objeto iterador pode então ser iterado com a função next(), que usa o método __ next__ () internamente, que retorna o próximo elemento no recipiente. (A declaração anterior é aplicável em Python 3.x. Em Python 2.x, o método next() é equivalente.) Uma exceção StopIteration será lançada quando não restarem mais elementos. O exemplo a seguir mostra uma iteração sobre uma seqüência equivalente usando iteradores explícitos:

it = iter(sequencia)
while True:
    try:
        valor = it.next() # em Python 2.x
        valor = next(it) # em Python 3.x
    except StopIteration:
        break
    it = iter(it)
    print(valor)

Qualquer classe definida pelo usuário pode suportar iteração padrão (implícita ou explícita), pela definição de um método __iter__() que retorna um objeto iterador. O objeto iterador, então, precisa definir um método __next__() que retorna o próximo elemento e um método __iter__() que retorna o próximo objeto iterador a ser usado.

Geradores do Python implementam este protocolo de iteração.


Ícone de esboço Este artigo sobre programação de computadores é um esboço. Você pode ajudar a Wikipédia expandindo-o.