Si j'ai une liste contenant [alice, bob, abigail, charlie]
et que je veux écrire un itérateur tel qu'il itère sur des éléments commençant par «a», puis-je écrire le mien? Comment puis je faire ça ?
Si j'ai une liste contenant [alice, bob, abigail, charlie]
et que je veux écrire un itérateur tel qu'il itère sur des éléments commençant par «a», puis-je écrire le mien? Comment puis je faire ça ?
Réponses:
Sûr. Un itérateur n'est qu'une implémentation de l' java.util.Iterator
interface. Si vous utilisez un objet itérable existant (par exemple, a LinkedList
) de java.util
, vous devrez soit le sous-classer et remplacer sa iterator
fonction afin de renvoyer la vôtre, soit fournir un moyen d'encapsuler un itérateur standard dans votre Iterator
instance spéciale (qui a l'avantage d'être plus largement utilisé), etc.
Iterator
instance spéciale ..." (et merci). :-)
La meilleure option réutilisable est d'implémenter l'interface Iterable et de remplacer la méthode iterator ().
Voici un exemple d'une classe de type ArrayList implémentant l'interface, dans laquelle vous remplacez la méthode Iterator ().
import java.util.Iterator;
public class SOList<Type> implements Iterable<Type> {
private Type[] arrayList;
private int currentSize;
public SOList(Type[] newArray) {
this.arrayList = newArray;
this.currentSize = arrayList.length;
}
@Override
public Iterator<Type> iterator() {
Iterator<Type> it = new Iterator<Type>() {
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 . Considérant 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'itérateur sans créer d'étendre Iterator et profiter de la valeur de currentSize pour vérifier jusqu'à l'endroit où vous pouvez naviguer sur le tableau (disons que vous avez créé un tableau d'une capacité de 10, mais vous n'en avez que 2 éléments à 0 et 1). L'instance aura son compteur propriétaire de l'endroit où elle se trouve et tout ce que vous avez à faire est de jouer avec hasNext (), qui vérifie si la valeur actuelle n'est pas nulle, et next (), qui renverra l'instance de votre currentIndex. Voici un exemple d'utilisation de cette API ...
public static void main(String[] args) {
// create an array of type Integer
Integer[] numbers = new Integer[]{1, 2, 3, 4, 5};
// create your list and hold the values.
SOList<Integer> stackOverflowList = new SOList<Integer>(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 Strings
String[] languages = new String[]{"C", "C++", "Java", "Python", "Scala"};
// create your list and hold the values using the same list implementation.
SOList<String> languagesList = new SOList<String>(languages);
System.out.println("");
// Since our class SOList is an instance of Iterable, then we can use it on a foreach loop
for(String 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 mise en œuvre plus complète à mon code google pratique personnelle .
Maintenant, pour obtenir les effets de ce dont vous avez besoin, je pense que vous devez brancher un concept de filtre dans l'itérateur ... Puisque l'itérateur dépend des valeurs suivantes, il serait difficile de retourner true sur hasNext (), puis filtre 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 Interator secondaire basé sur une liste filtrée avec les valeurs avec le filtre donné.
for instance
, est-ce un jeu de mots?
Bon exemple pour Iterable pour calculer factoriel
FactorialIterable fi = new FactorialIterable(10);
Iterator<Integer> iterator = fi.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
Code court pour Java 1.8
new FactorialIterable(5).forEach(System.out::println);
Classe Iterable personnalisée
public class FactorialIterable implements Iterable<Integer> {
private final FactorialIterator factorialIterator;
public FactorialIterable(Integer value) {
factorialIterator = new FactorialIterator(value);
}
@Override
public Iterator<Integer> iterator() {
return factorialIterator;
}
@Override
public void forEach(Consumer<? super Integer> action) {
Objects.requireNonNull(action);
Integer last = 0;
for (Integer t : this) {
last = t;
}
action.accept(last);
}
}
Classe Iterator personnalisée
public class FactorialIterator implements Iterator<Integer> {
private final Integer mNumber;
private Integer mPosition;
private Integer mFactorial;
public FactorialIterator(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;
}
}
Voici le code complet pour écrire un itérateur tel qu'il itère sur les éléments qui commencent par 'a':
import java.util.Iterator;
public class AppDemo {
public static void main(String args[]) {
Bag<String> bag1 = new Bag<>();
bag1.add("alice");
bag1.add("bob");
bag1.add("abigail");
bag1.add("charlie");
for (Iterator<String> it1 = bag1.iterator(); it1.hasNext();) {
String 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<T> {
private ArrayList<T> data;
public Bag() {
data = new ArrayList<>();
}
public void add(T e) {
data.add(e);
}
public Iterator<T> iterator() {
return new BagIterator();
}
public class BagIterator<T> implements Iterator<T> {
private int index;
private String 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;
}
}
}
Vous pouvez implémenter votre propre Iterator. Votre itérateur peut être construit pour encapsuler l'itérateur retourné par la liste, ou vous pouvez garder un curseur et utiliser la méthode get (int index) de la liste. Il vous suffit d'ajouter une 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 itérateur prendra en charge l'opération de suppression.
Voici la réponse complète à la question.
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
class ListIterator implements Iterator<String>{
List<String> list;
int pos = 0;
public ListIterator(List<String> list) {
this.list = list;
}
@Override
public boolean hasNext() {
while(pos < list.size()){
if (list.get(pos).startsWith("a"))
return true;
pos++;
}
return false;
}
@Override
public String next() {
if (hasNext())
return list.get(pos++);
throw new NoSuchElementException();
}
}
public class IteratorTest {
public static void main(String[] args) {
List<String> list = Arrays.asList("alice", "bob", "abigail", "charlie");
ListIterator itr = new ListIterator(list);
while(itr.hasNext())
System.out.println(itr.next()); // prints alice, abigail
}
}
ListIterator
est l'itérateur du tableau qui renvoie les éléments commençant par «a». NoSuchElementException
exception valide .