Peut-on écrire notre propre iterator en Java?

Si j’ai une liste contenant [alice, bob, abigail, charlie] et que je veux écrire un iterator tel qu’il itère sur des éléments commençant par ‘a’, puis-je écrire le mien? Comment puis je faire ça ?

Sûr. Un iterator n’est qu’une implémentation de l’interface java.util.Iterator . Si vous utilisez un object itérable existant (par exemple, une LinkedList ) de java.util , vous devrez le sous-classer et remplacer sa fonction iterator afin de pouvoir renvoyer votre propre ou pour envelopper un iterator standard dans votre instance spéciale d’ Iterator (qui a l’avantage d’être plus largement utilisée), etc.

La meilleure option réutilisable consiste à implémenter l’interface Iterable et à remplacer l’iterator de méthode ().

Voici un exemple d’une classe de type ArrayList implémentant l’interface, dans laquelle vous écrasez la méthode Iterator ().

 import java.util.Iterator; public class SOList implements Iterable { private Type[] arrayList; private int currentSize; public SOList(Type[] newArray) { this.arrayList = newArray; this.currentSize = arrayList.length; } @Override public Iterator iterator() { Iterator it = new Iterator() { private int currentIndex = 0; @Override public boolean hasNext() { return currentIndex < currentSize && arrayList[currentIndex] != null; } @Override public Type next() { return arrayList[currentIndex++]; } @Override public void remove() { throw new UnsupportedOperationException(); } }; return it; } } 

Cette classe implémente l'interface Iterable à l'aide de Generics . Étant donné que vous avez des éléments dans le tableau, vous pourrez obtenir une instance d'un iterator, qui est l'instance nécessaire utilisée par la boucle "foreach", par exemple.

Vous pouvez simplement créer une instance anonyme de l'iterator sans créer d'extension Iterator et tirer parti de la valeur de currentSize pour vérifier où vous pouvez naviguer sur le tableau (par exemple, vous avez créé un tableau avec une capacité de 10, mais vous n'en avez que 2). éléments à 0 et 1). L'instance aura son compteur de propriétaire où il se trouve et tout ce que vous avez à faire est de jouer avec hasNext (), qui vérifie si la valeur actuelle n'est pas null, et next (), qui retournera l'instance de votre currentIndex. Voici un exemple d'utilisation de cette API ...

 public static void main(Ssortingng[] args) { // create an array of type Integer Integer[] numbers = new Integer[]{1, 2, 3, 4, 5}; // create your list and hold the values. SOList stackOverflowList = new SOList(numbers); // Since our class SOList is an instance of Iterable, then we can use it on a foreach loop for(Integer num : stackOverflowList) { System.out.print(num); } // creating an array of Ssortingngs Ssortingng[] languages = new Ssortingng[]{"C", "C++", "Java", "Python", "Scala"}; // create your list and hold the values using the same list implementation. SOList languagesList = new SOList(languages); System.out.println(""); // Since our class SOList is an instance of Iterable, then we can use it on a foreach loop for(Ssortingng lang : languagesList) { System.out.println(lang); } } // will print "12345 //C //C++ //Java //Python //Scala 

Si vous le souhaitez, vous pouvez également le parcourir en utilisant l'instance Iterator:

 // navigating the iterator while (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 

La documentation foreach se trouve à l' adresse http://download.oracle.com/javase/1,5.0/docs/guide/language/foreach.html . Vous pouvez jeter un oeil à une implémentation plus complète de mon code personnel Google .

Maintenant, pour obtenir les effets de ce dont vous avez besoin, je pense que vous devez twigr un concept de filtre dans l'iterator ... Puisque l'iterator dépend des valeurs suivantes, il serait difficile de retourner true sur hasNext (), puis filtrer l'implémentation next () avec une valeur qui ne commence pas par un caractère "a" par exemple. Je pense que vous devez jouer avec un Intermédiaire secondaire basé sur une liste filtrée avec les valeurs avec le filtre donné.

Bon exemple pour Iterable pour calculer factoriel

 FactorialIterable fi = new FactorialIterable(10); Iterator iterator = fi.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } 

peu de code pour Java 1.8

 new FactorialIterable(5).forEach(System.out::println); 

Classe Iterable personnalisée

 public class FactorialIterable implements Iterable { private final FactorialIteartor factorialIteartor; public FactorialIterable(Integer value) { factorialIteartor = new FactorialIteartor(value); } @Override public Iterator iterator() { return factorialIteartor; } @Override public void forEach(Consumer action) { Objects.requireNonNull(action); Integer last = 0; for (Integer t : this) { last = t; } action.accept(last); } } 

Classe Iterator personnalisée

 public class FactorialIteartor implements Iterator { private final Integer mNumber; private Integer mPosition; private Integer mFactorial; public FactorialIteartor(Integer number) { this.mNumber = number; this.mPosition = 1; this.mFactorial = 1; } @Override public boolean hasNext() { return mPosition <= mNumber; } @Override public Integer next() { if (!hasNext()) return 0; mFactorial = mFactorial * mPosition; mPosition++; return mFactorial; } } 

Vous pouvez implémenter votre propre iterator. Votre iterator pourrait être construit pour envelopper l’iterator renvoyé par la liste, ou vous pourriez garder un curseur et utiliser la méthode get (int index) de List. Il vous suffit d’append la logique à la méthode suivante de votre iterator ET la méthode hasNext pour prendre en compte vos critères de filtrage. Vous devrez également décider si votre iterator prendra en charge l’opération de suppression.

C’est le code complet pour écrire un iterator tel qu’il itère sur les éléments commençant par ‘a’:

 import java.util.Iterator; public class AppDemo { public static void main(Ssortingng args[]) { Bag bag1 = new Bag<>(); bag1.add("alice"); bag1.add("bob"); bag1.add("abigail"); bag1.add("charlie"); for (Iterator it1 = bag1.iterator(); it1.hasNext();) { Ssortingng s = it1.next(); if (s != null) System.out.println(s); } } } 

Classe Iterator personnalisée

 import java.util.ArrayList; import java.util.Iterator; public class Bag { private ArrayList data; public Bag() { data = new ArrayList<>(); } public void add(T e) { data.add(e); } public Iterator iterator() { return new BagIterator(); } public class BagIterator implements Iterator { private int index; private Ssortingng str; public BagIterator() { index = 0; } @Override public boolean hasNext() { return index < data.size(); } @Override public T next() { str = (String) data.get(index); if (str.startsWith("a")) return (T) data.get(index++); index++; return null; } } }