Se eu tiver uma lista contendo [alice, bob, abigail, charlie]e quiser escrever um iterador de forma que itere sobre os elementos que começam com 'a', posso escrever o meu próprio? Como eu posso fazer isso ?
Certo. Um iterador é apenas uma implementação da java.util.Iteratorinterface. Se você estiver usando um objeto iterável existente (digamos, a LinkedList) de java.util, você precisará subclassificá-lo e sobrescrever sua iteratorfunção para que você retorne a sua, ou fornecer um meio de agrupar um iterador padrão em sua Iteratorinstância especial (que tem a vantagem de ser mais amplamente utilizado), etc.
boa resposta .... +1 No entanto, você não é forçado a subclasse LinkedList. Você pode escrever um CustomIterator que é instanciado com o novo CustomIterator (somelist), uma vez que as interfaces não dizem nada sobre construtores.
gd1
1
@Giacomo: Isso é o que eu quis dizer com "... ou fornecer um meio de agrupar um iterador padrão em sua Iteratorinstância especial ..." (e obrigado). :-)
TJ Crowder
196
A melhor opção reutilizável é implementar a interface Iterable e substituir o iterador do método ().
Aqui está um exemplo de uma classe como ArrayList implementando a interface, na qual você substitui o método Iterator ().
Esta classe implementa a interface Iterable usando Genéricos . Considerando que você tem elementos para o array, você poderá obter uma instância de um Iterator, que é a instância necessária usada pelo loop "foreach", por exemplo.
Você pode simplesmente criar uma instância anônima do iterador sem criar estendendo Iterator e aproveitar o valor de currentSize para verificar até onde você pode navegar sobre a matriz (digamos que você criou uma matriz com capacidade de 10, mas você tem apenas 2 elementos em 0 e 1). A instância terá seu contador proprietário de onde está e tudo que você precisa fazer é brincar com hasNext (), que verifica se o valor atual não é nulo, e o next (), que retornará a instância de seu currentIndex. Abaixo está um exemplo de uso desta API ...
publicstaticvoid main(String[] args){// create an array of type IntegerInteger[] numbers =newInteger[]{1,2,3,4,5};// create your list and hold the values.SOList<Integer> stackOverflowList =newSOList<Integer>(numbers);// Since our class SOList is an instance of Iterable, then we can use it on a foreach loopfor(Integer num : stackOverflowList){System.out.print(num);}// creating an array of StringsString[] languages =newString[]{"C","C++","Java","Python","Scala"};// create your list and hold the values using the same list implementation.SOList<String> languagesList =newSOList<String>(languages);System.out.println("");// Since our class SOList is an instance of Iterable, then we can use it on a foreach loopfor(String lang : languagesList){System.out.println(lang);}}// will print "12345//C//C++//Java//Python//Scala
Se desejar, você também pode iterar sobre ele usando a instância Iterator:
// navigating the iteratorwhile(allNumbers.hasNext()){Integer value = allNumbers.next();if(allNumbers.hasNext()){System.out.print(value +", ");}else{System.out.print(value);}}// will print 1, 2, 3, 4, 5
Agora, para obter os efeitos do que você precisa, acho que você precisa conectar um conceito de filtro no Iterator ... Como o iterador depende dos próximos valores, seria difícil retornar true em hasNext () e, em seguida, filtre a implementação next () com um valor que não comece com um caractere "a", por exemplo. Acho que você precisa brincar com um Interator secundário com base em uma lista filtrada com os valores com o filtro fornecido.
30 outras pessoas não acharam isso um trocadilho :)
Marcello de Sales
2
É uma boa prática lançar exceção de operação sem suporte de nossos métodos implementados. Acho que é uma boa ideia lançar uma exceção de operação não suportada do método remove ()!
darshan
2
Desculpe @darshan, mas esta solução diz respeito a "como escrever iteradores" ... Se o foco fosse "escrever código perfeitamente escrito", isso estaria lá!
Marcello de Sales de
não está claro porque a verificação 'arrayList [currentIndex]! = null' é necessária dentro de hasNext (). alguém pode explicar.
Bhushan Karmarkar
12
Bom exemplo de Iterable para calcular fatorial
FactorialIterable fi =newFactorialIterable(10);Iterator<Integer> iterator = fi.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}
Você pode implementar seu próprio Iterator. Seu iterador pode ser construído para envolver o Iterador retornado pela Lista, ou você pode manter um cursor e usar o método get (int index) de List. Você só precisa adicionar lógica ao próximo método de seu Iterator E ao método hasNext para levar em consideração seus critérios de filtragem. Você também terá que decidir se o seu iterador suportará a operação de remoção.
ListIterator é o iterador para a matriz que retorna os elementos que começam com 'a'.
Não há necessidade de implementar uma interface Iterable. Mas essa é uma possibilidade.
Não há necessidade de implementar isso genericamente.
Ele satisfaz totalmente o contrato para hasNext () e next (). ou seja, se hasNext () diz que ainda há elementos, next () retornará esses elementos. E se hasNext () não diz mais elementos, ele retorna uma NoSuchElementExceptionexceção válida .
Respostas:
Certo. Um iterador é apenas uma implementação da
java.util.Iterator
interface. Se você estiver usando um objeto iterável existente (digamos, aLinkedList
) dejava.util
, você precisará subclassificá-lo e sobrescrever suaiterator
função para que você retorne a sua, ou fornecer um meio de agrupar um iterador padrão em suaIterator
instância especial (que tem a vantagem de ser mais amplamente utilizado), etc.fonte
Iterator
instância especial ..." (e obrigado). :-)A melhor opção reutilizável é implementar a interface Iterable e substituir o iterador do método ().
Aqui está um exemplo de uma classe como ArrayList implementando a interface, na qual você substitui o método Iterator ().
Esta classe implementa a interface Iterable usando Genéricos . Considerando que você tem elementos para o array, você poderá obter uma instância de um Iterator, que é a instância necessária usada pelo loop "foreach", por exemplo.
Você pode simplesmente criar uma instância anônima do iterador sem criar estendendo Iterator e aproveitar o valor de currentSize para verificar até onde você pode navegar sobre a matriz (digamos que você criou uma matriz com capacidade de 10, mas você tem apenas 2 elementos em 0 e 1). A instância terá seu contador proprietário de onde está e tudo que você precisa fazer é brincar com hasNext (), que verifica se o valor atual não é nulo, e o next (), que retornará a instância de seu currentIndex. Abaixo está um exemplo de uso desta API ...
Se desejar, você também pode iterar sobre ele usando a instância Iterator:
A documentação do foreach está localizada em http://download.oracle.com/javase/1,5.0/docs/guide/language/foreach.html . Você pode dar uma olhada em uma implementação mais completa em meu código de prática pessoal do Google .
Agora, para obter os efeitos do que você precisa, acho que você precisa conectar um conceito de filtro no Iterator ... Como o iterador depende dos próximos valores, seria difícil retornar true em hasNext () e, em seguida, filtre a implementação next () com um valor que não comece com um caractere "a", por exemplo. Acho que você precisa brincar com um Interator secundário com base em uma lista filtrada com os valores com o filtro fornecido.
fonte
for instance
, isso é um trocadilho?Bom exemplo de Iterable para calcular fatorial
Código curto para Java 1.8
Classe Iterable Customizada
Classe Iterator Customizado
fonte
Este é o código completo para escrever um iterador de forma que itere sobre os elementos que começam com 'a':
Classe Iterator Customizado
fonte
Você pode implementar seu próprio Iterator. Seu iterador pode ser construído para envolver o Iterador retornado pela Lista, ou você pode manter um cursor e usar o método get (int index) de List. Você só precisa adicionar lógica ao próximo método de seu Iterator E ao método hasNext para levar em consideração seus critérios de filtragem. Você também terá que decidir se o seu iterador suportará a operação de remoção.
fonte
Aqui está a resposta completa para a pergunta.
ListIterator
é o iterador para a matriz que retorna os elementos que começam com 'a'.NoSuchElementException
exceção válida .fonte