J'en avais
déjà parlé, Stephen Colebourne avait fait une première proposition concernant la boucle for-each en Java
Cette amélioration concernait l'utilisation de cette boucle avec des objets de type
Map.
Un rapide exemple de code pour mémoire :
Map<String,Object> objects;
// [...]
for (String key, Object o : objects) {
System.out.println(k + "=" + o);
}
Stephen
reviens aujourd'hui sur sa proposition, avec une nouvelle fonctionnalité : Le contrôle d'accès sur une boucle de type for-each.
Cette nouvelle fonctionnalité est basée sur des inconvénients de cette boucle, entre autres :
- L'impossibilité d'accéder à l'index de l'objet actuellement parcouru
- L'impossibilité de supprimer l'objet courant
Dans les deux cas, des solutions étaient envisageables. Notamment passer par une boucle classique, en utilisant un
Iterator. Mais on perdait tout l'intérêt de cette nouvelle boucle.
La solution proposée est plutôt simple. Il s'agirait de permettre au développeur d'accéder à certaines fonctionnalités de l'
Iterator qui parcourt la
Collection. La syntaxe proposée est la suivante :
Collection<String> coll = new ArrayList<String>();
for (String str : coll : it) {
System.out.println("coll[" + it.index() + "] = " + str);
}
Un autre exemple :
List<String> list = new ArrayList<String>();
for (String str : list : it) {
if (str == null || it.isFirst()) {
it.remove();
}
}
La nouvelle syntaxe introduirait donc une nouvelle variable (optionnelle, pour des raisons de comptabilité), qui permettrait d'avoir plus de contrôle sur la boucle.
Voici un premier aperçu des méthodes qui devraient être fournies à travers cette variable (tirées de la
proposition originale) :
public interface IterableControl<E> {
E set(E newValue);
E remove();
int index();
int originalIndex();
boolean isFirst();
boolean isLast();
int size();
}
Une rapide description de chacune de ces fonctions :
set() : Change la valeur de l'élément courant. Cette opération ne serait pas supportée pour les itérations sur les types Iterable, Collection et Set.
remove() : Supprime l'élément courant. Cette opération ne serait pas supportée sur les tableaux.
index() : Renvoie l'index de l'élément courant.
originalIndex() : Renvoie l'index original de l'élément courant. "Original" signifie "Sans ajustements lors des suppressions d'éléments".
isFirst() : Renvoie true si et seulement si l'élément courant est le premier élément de la boucle.
isLast() : Renvoie true si et seulement si l'élément courant est le dernier élément de la boucle.
size() : Renvoie la taille courante de la collection ou du tableau parcouru.
La question actuellement posée dans la proposition est "Est-ce qu'il faut passer par une interface spécifique, ou juste appeler les méthodes correspondantes directement dans la boucle ?".
Pour plus d'informations :