Iterator Professor: Hyggo Almeida Iterator Utilização de estruturas de dados Vector, ArrayList, HashSet, ... Vector collection; ArrayList collection; HashSet collection; public void classeXusando(Vector col){...} public void classeWusando(ArrayList col){...} public void classeZusando(HashSet col){...} 2 E se... Eu quiser a mudar a estrutura de dados?? Vector collection; HashSet!!! ArrayList collection; public void classeXusando(Vector col){...} public void classeWusando(ArrayList col){...} Vector!!! HashSet collection; public void classeZusando(HashSet col){...} 3 Iterator Problema Como isolar o uso de uma estrutura de dados de sua representação interna de forma a poder mudar a estrutura sem afetar quem a usa??? Para determinadas estruturas, pode haver formas diferentes de “varredura”. Como encapsular a forma exata de varredura??? Solução Usar um Iterador!!! A idéia do iterador é retirar da coleção a responsabilidade de acessar e varrer a estrutura colocar a responsabilidade num novo objeto separado chamado iterador 4 Iterator A classe Iterador Implementa a interface Iterator Mantém qualquer informação de estado necessária para saber até onde a iteração (varredura) já foi (mantém o cursor) Como criar um iterador? Não se pode usar new diretamente pois o iterador a ser criado depende da coleção a ser varrida Solução: a coleção tem um factory method para criar um iterador Exemplo em java: Vector.iterator() 5 Iterator Iterador do Vector public Iterator iterator() { return new Iterator() { // classe interna anônima int cursor = 0; public boolean hasNext() { return cursor < size(); } public Object next() { try { Object next = get(cursor); cursor++; return next; } catch(IndexOutOfBoundsException e) { throw new NoSuchElementException(); } } }; } Decorator e Iterator 6 Iterator Como funciona??? Vector Estrutura de dados 0 1 2 3 4 5 Decorator e Iterator “João” “Maria” “Carlos” “Paulo” “José” “João” Iterador(cursor) Iterador(cursor) 0 Iterador(cursor) 1 Iterador(cursor) 2 Iterador(cursor) 3 Iterador(cursor) 4 Iterador(cursor) 5 6 Cliente Varredura crescente hasNext() = false 7 Iterator Posso mudar a forma de varrer!!! Sem mudar a estrutura! Iterador(cursor) Cliente Vector Estrutura de dados 0 1 2 3 4 5 “João” “Maria” “Carlos” “Paulo” “José” “João” 0 Iterador(cursor) Varredura pares!!! 1 Iterador(cursor) 2 Iterador(cursor) 3 hasNext() = false 8 Iterator HashSet Posso mudar a estrutura sem mudar a forma de varrer! Cliente Iterador(cursor) 0 1 2 3 4 “João” “Maria” “Carlos” “Paulo” “José” 0 Iterador(cursor) Varredura pares!!! 1 Iterador(cursor) 2 Iterador(cursor) 3 hasNext() = false “João” 9 Iterator Conseqüências É possível acessar a coleção de objetos sem saber a fonte dos objetos Aplicabilidade Uma classe necessita acessar o conteúdo de uma coleção sem se tornar dependente da classe que implementa aquela coleção Uma classe necessita de uma maneira uniforme de acessar o conteúdo de múltiplas coleções Também chamado de Cursor Decorator e Iterator 10 Iterator Vamos implementar um EvenIterator para retornar apenas os índices pares de uma coleção de MyNumber’s e um OddIterator para os índices ímpares. Use a interface java.util.Iterator Use classes internas Cliente printNumbers(Iterator); Decorator e Iterator NumCollection evenIterator():Iterator; oddIterator():Iterator; iterator():Iterator; MyNumber numbers: Vector; value:int; addNumber(myNumber); evenIterator():Iterator; oddIterator():Iterator; iterator():Iterator; toString(); 11 Iterator Mão na massa!!! return new Iterator(){ int cursor = 0; Pares public void remove() { numbers.remove(cursor); } public boolean hasNext() { return (cursor < numbers.size()); } { public Object next() { try { Object next = numbers.get(cursor); cursor+=2; return next; } catch(IndexOutOfBoundsException e) throw new NoSuchElementException(); } } }; Decorator e Iterator Cliente.main NumCollection col = new NumCollection(); col.addNumber(new MyNumber(0)); col.addNumber(new MyNumber(1)); col.addNumber(new MyNumber(2)); col.addNumber(new MyNumber(3)); printNumbers(col.evenIterator()); Cliente.printNumbers private static void printNumbers(Iterator iterator) { while (iterator.hasNext()) { System.out.println(iterator.next()); } 12 Dúvidas? ? Decorator e Iterator 13