Pergunta

Eu só aprendi sobre como as estruturas de dados implementa Java Collections Framework em listas ligadas. Pelo que eu entendo, Iterators são uma forma de percorrer através dos itens em uma estrutura de dados como uma lista. Porque é que esta interface usada? Por que os métodos hasNext(), next() e remove() não diretamente codificado para a própria implementação estrutura de dados?

Do site do Java: link de texto

interface pública Iterator

Um iterador sobre uma coleção. iterator toma o lugar da enumeração na Java quadro coleções. Iterators diferem enumerações de duas maneiras:

  • Iterators permitir que o chamador para remover elementos da subjacente coleção durante a iteração com semântica bem definida.
  • Os nomes de métodos foram melhorados.
Esta interface é um membro das coleções de Java Framework.

Eu tentei pesquisando em torno e não consigo encontrar uma resposta definitiva. Alguém pode lançar alguma luz sobre por que Sun escolheu para usá-los? É por causa do projeto melhor? Maior segurança? Boas práticas OO?

Qualquer ajuda será muito apreciada. Obrigado.

Foi útil?

Solução

Porque é que esta interface usada?

Como ele suporta as operações básicas que permitiriam que um programador cliente para interagir sobre qualquer tipo de coleção (nota: não é necessariamente uma Collection no sentido Object).

Por que os métodos ... não diretamente codificada para a estrutura de dados própria implementação?

Eles são, eles estão apenas marcado como particular para que você não pode chegar para eles e muck com eles. Mais especificamente:

  • Você pode implementar ou subclasse um Iterator tal que faz algo que os quartos standard não fazer, sem ter que alterar o objeto real que itera sobre.
  • Objetos que podem ser percorridos mais não precisa ter suas interfaces confuso com métodos de travessia, em particular métodos de qualquer altamente especializados.
  • Você pode distribuir Iterators para porém muitos clientes que você deseja, e cada cliente pode atravessar em seu próprio tempo, em seu próprio ritmo.
  • Iterators Java do pacote java.util em particular irá lançar uma exceção se o armazenamento que backs-los é modificado enquanto você ainda tem um Iterator fora. Essa exceção permite que você saiba que o Iterator pode agora voltar objetos inválidos.

Para programas simples, nada disso, provavelmente, parece valer a pena. O tipo de complexidade que os torna úteis virá para cima de você rapidamente, no entanto.

Outras dicas

Você pergunta: "Por que os métodos hasNext (), next () e remove () não diretamente codificado para a própria implementação estrutura de dados?"

.

O framework Java Collections escolhe para definir a interface Iterator como exteriorizada para a própria coleção. Normalmente, uma vez que cada coleção implementa a interface Iterable Java, um programa Java vai chamar iterator para criar o seu próprio iterador para que ele possa ser usado em um loop. Como outros têm para fora pontas, Java 5 nos permite o uso direto do iterador, com um for-each loop.

A externalização do iterador para sua coleção permite ao cliente controlar como um itera através de uma coleção. Um caso de uso que eu posso pensar de onde isso é útil é quando se tem um uma coleção ilimitada, como todas as páginas da web na Internet para o índice.

No livro GoF clássico, o contraste entre iteradores internos e externos é soletrado para fora claramente.

A questão fundamental é decidir qual conrols partido da iteração, o iterador ou o cliente que utiliza o iterador. Quando os controles do cliente A iteração, o iterador é chamado um iterador externo, e quando os controles iterator it, o iterador é um iterador interno. Os clientes que usam um iterador externo deve avançar a travessia e solicitar o próximo elemento explicitamente a partir do iterator. Em contraste, as mãos do cliente um iterador interno de uma operação para executar, e o iterador aplica essa operação a cada elemento ....

iterators externas são mais flexíveis do que iteradores internos. É fácil comparar duas coleções para a igualdade com um iterador externo, por exemplo, mas é praticamente impossível com iteradores internos ... Mas, por outro lado, iteradores internos são mais fáceis de usar, porque eles definem a lógica iteração para você.

Para um exemplo de como iterators interno funcionar, consulte API Enumerable de Ruby, que tem métodos de iteração internos, como each. Em Ruby, a idéia é passar um bloco de código (fechamento ou seja, a) para um iterador interno para que uma coleção pode cuidar de sua própria iteração.

é importante para manter a coleção além do ponteiro. os pontos de iterador em um lugar específico em uma coleção e, portanto, não é uma parte integrante da coleção. Desta forma, para um exemplo, você pode usar vários iteradores sobre a mesma coleção.

O lado negativo desta separação é que o iterador não tem conhecimento de alterações feitas na coleção que itera por diante. para que você não pode mudar a estrutura da coleta e esperar que o iterador para continuá-lo do trabalho sem "reclamações".

Usando a interface Iterator permite que qualquer classe que implementa os seus métodos para atuar como iteradores. A noção de uma interface em Java é ter, de certa forma, uma obrigação contratual de fornecer certas funcionalidades em uma classe que implements a interface, para agir de uma forma que é exigido pela interface. Desde as obrigações contratuais devem ser cumpridas a fim de ser uma classe válida, outras classes que vêem o implements classe da interface e, assim, tranquilizou saber que a classe terá aquelas certas funcionalidades.

Neste exemplo, ao invés de implementar os métodos (hasNext(), next(), remove()) na própria classe LinkedList, a classe LinkedList irá declarar que implements a interface Iterator, para que outros saibam que o LinkedList pode ser usado como um iterador. Por sua vez, a classe LinkedList irá implementar os métodos da interface Iterator (tais como hasNext()), para que ele possa funcionar como um iterador.

Em outras palavras, a implementação de uma interface é uma noção de programação orientada a objetos para que os outros saibam que uma determinada classe tem o que é preciso para ser o que afirma ser.

Esta noção é aplicada por ter métodos que devem ser implementados por uma classe que implementa a interface. Isso garante que outras classes que deseja usar a classe que implementa a interface Iterator que vai de fato ter métodos que Iterators deve ter, como hasNext().

Além disso, deve-se notar que desde que Java não tem herança múltipla, o uso da interface pode ser usado para emular esse recurso. Ao implementar várias interfaces, pode-se ter uma classe que é uma subclasse de herdar algumas características, mas também "herdar" as características de outro através da implementação de uma interface. Um exemplo seria, se eu quisesse ter uma subclasse da classe LinkedList chamado ReversibleLinkedList que pode iterar em ordem inversa, eu posso criar uma interface chamada ReverseIterator e impor que fornecem um método previous(). Desde o LinkedList já implementa Iterator, a nova lista reversível teria aplicado ambas as interfaces Iterator e ReverseIterator.

Você pode ler mais sobre interfaces de O que é uma interface? de The Java Tutorial a partir do Sol.

Várias instâncias de um interator podem ser usados ??simultaneamente. Abordá-los como cursores locais para os dados subjacentes.

BTW: as interfaces que favorecem mais de implementações concretas perde o acoplamento

Procure o padrão de design iterador, e aqui: http://en.wikipedia.org/wiki / Iterator

Porque você pode ser iteração sobre algo que não é uma estrutura de dados. Digamos que eu tenho uma aplicação em rede que puxa resultados de um servidor. Posso voltar um invólucro Iterator em torno desses resultados e transmitir-lhes através de qualquer código padrão que aceita um objeto Iterator.

Pense nisso como uma parte fundamental de um bom projeto MVC. Os dados tem que começar a partir do Modelo (ou seja, estrutura de dados) para a vista de alguma forma. Usando um Iterator como um intermediário garante que a implementação do Modelo nunca é exposta. Você poderia estar mantendo um LinkedList na memória, puxando informações a partir de um algoritmo de descriptografia, ou embalar chamadas JDBC. Ele simplesmente não importa para a vista, porque a vista só se preocupa com a interface Iterator.

Um papel interessante discutir os prós e contras do uso de iteradores:

http://www.sei.cmu.edu /pacc/CBSE5/Sridhar-cbse5-final.pdf

Eu acho que é uma boa prática para OO. Você pode ter código que lida com todos os tipos de iteradores, e até mesmo dá-lhe a oportunidade de criar suas próprias estruturas de dados ou apenas classes genéricas que implementam a interface iterator. Você não precisa se preocupar com o tipo de aplicação está por trás disso.

Apenas M2C, se você não estava ciente: você pode evitar diretamente usando a interface iterator em situações onde o para-cada loop será suficiente.

Em última análise, porque Iterator captura uma abstração de controle que é aplicável a um grande número de estruturas de dados. Se você é acima em sua categoria teoria fu, você pode ter sua mente soprado por este papel: a Essência do Padrão Iterator .

Bem, parece que o primeiro ponto permite multi-threaded (rosca ou solteiro, se você estragar) aplicações a não precisa bloquear a coleção por violações de simultaneidade. Em .NET, por exemplo, você não pode enumerar e modificar uma coleção (ou lista ou qualquer IEnumerable), ao mesmo tempo sem bloquear ou herdar de IEnumerable e substituindo métodos (temos exceções).

Iterator simplesmente adiciona uma forma comum de que vai sobre uma coleção de itens. Um dos recursos mais interessantes é o i.remove (), no qual você pode remover elementos da lista que você está interagindo sobre. Se você apenas tentou remover itens de uma lista normalmente teria efeitos estranhos ou lançar e exceção.

A interface é como um contrato para todas as coisas que a implementam. Você está basicamente dizendo .. qualquer coisa que implementa um iterador é garantido para ter estes métodos que se comportam da mesma maneira. Você também pode usá-lo para passar em torno de iterador tipos se isso é tudo o que importa tratar em seu código. (Você pode não importa que tipo de lista é .. você só quer passar um Iterator) Você poderia colocar todos esses métodos de forma independente nas coleções, mas você não está garantindo que eles se comportam da mesma ou que eles ainda têm o mesmo nome e assinaturas.

Iterators são um dos muitos padrões de design disponíveis em java. padrões de projeto pode ser pensado como conveniente blocos de construção, estilos, o uso de seu código / estrutura.

Para ler mais sobre o padrão de projeto Iterator consulte a este site que fala sobre Iterator, assim como muitos outros padrões de projeto. Aqui está um trecho do site no Iterator: http://www.patterndepot.com/ colocar / 8 / Behavioral.html

O Iterator é um dos mais simples e mais utilizadas do projeto padrões. O padrão Iterator permite -lhe percorrer uma lista ou recolha de dados usando um padrão interface sem ter que saber o detalhes do interno representações de que os dados. No disso, você também pode definir especial iterators que executam alguma especial processamento e devolução só especificado elementos da coleta de dados.

Iterators pode ser usado contra qualquer tipo de coleção. Eles permitem que você defina um algoritmo contra uma coleção de itens independentemente da implementação subjacente. Isto significa que pode processar uma lista, Set, String, Arquivo, Array, etc.

Dez anos a partir de agora você pode mudar a sua implementação Lista para uma melhor implementação e o algoritmo irá ainda executar perfeitamente contra ela.

Iterator é útil quando você está lidando com coleções em Java.

Use For-Cada loop (Java1.5) para iteração sobre uma coleção ou matriz ou lista.

A interface java.util.Iterator é usado no Java Collections Framework para permitir a modificação da coleção enquanto ainda iteração através dele. Se você só quer limpa iteração sobre uma coleção inteira, use um para-cada vez, mas uma cabeça de Iterators é a funcionalidade que você começa: a remoção opcional () operação, e ainda melhor para a interface List Iterator, que oferece adicionar () e set () operações também. Ambas estas interfaces permitem que você iterar uma coleção e mudá-lo estruturalmente ao mesmo tempo. Tentando modificar uma coleção durante a iteração através dele com um for-each jogaria um ConcurrentModificationException, geralmente porque a coleção é inesperadamente modificado!

Dê uma olhada na classe ArrayList

Tem 2 aulas particulares dentro dela (classes internas) chamado ITR e ListItr

Eles implementar interfaces Iterator eo ListIterator respectivamente

public class ArrayList ..... {// encerrando classe

  private class Itr implements Iterator<E> {

        public E next() {
            return ArrayList.this.get(index++); //rough, not exact
        }

        //we have to use ArrayList.this.get() so the compiler will
        //know that we are referring to the methods in the 
        //enclosing ArrayList class

        public void remove() {
            ArrayList.this.remove(prevIndex);
        }

        //checks for...co mod of the list
        final void checkForComodification() {  //ListItr gets this method as well
             if (ArrayList.this.modCount != expectedModCount) { 
                 throw new ConcurrentModificationException();
             }
        }
  }

  private class ListItr extends Itr implements ListIterator<E> {
         //methods inherted....
        public void add(E e) {
            ArrayList.this.add(cursor, e);
        }

        public void set(E e) {
            ArrayList.this.set(cursor, e);
        }
  }

}

Quando você chamar os métodos iterator () e ListIterator (), eles retornam uma nova instância da classe privada Itr ou ListItr, e uma vez que estas classes internas estão "dentro" da classe ArrayList encerrando, eles podem modificar livremente o ArrayList sem disparar um ConcurrentModificationException, a menos que você alterar a lista ao mesmo tempo (conccurently) através do jogo () add () ou remove () métodos da classe ArrayList.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top