Astuce Java #5 : for-each sur une map

Petite astuce pour iterer sur une Map dans une boucle for-each, en attendant Java 7.

Il s'agit de considérer une Map comme une collection de Map.Entry :
Map<Integer, String> myMap = new HashMap<Integer, String>();
// ...
for (Map.Entry entry : myMap.entrySet()) {
    System.out.println(entry.getKey() + "=" + entry.getValue());
}


Via A better way to iterate java maps.

Permalink  |  Commentaires (0)

Java 7 : Amélioration de la boucle for-each, deuxième édition

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 :

Permalink  |  Commentaires (0)

Java 7 : Amélioration de la boucle for-each

Stephen Colebourne viens de publier une proposition concernant une amélioration de la boucle for-each en Java.

Petit historique :
La boucle for-each à été introduite en Java 5. Cette nouvelle boucle permettait (et permet toujours) d'itérer très facilement sur un tableau, une Collection ou un Iterator.
Collection<String> strings;
[...]
for (String s : strings) {
    System.out.println(s);
}

L'amélioration de celle-ci devrait permettre d'itérer sur une Map de la même manière que sur une Collection ou un tableau.

La nouvelle syntaxe qui permettrait ceci devrait ressembler à ça :
Map<String,Object> objects;
[...]
for (String key, Object o : objects) {
    System.out.println(k + "=" + o);
}

D'où une grande simplification dans le parcours des Map.

En plus de ça, Stephen ne s'est pas arrêté là. Il a déjà mis à disposition une version de javac modifiée, basée sur Kijaro, permettant d'utiliser cette nouvelle boucle.

Permalink  |  Commentaires (0)