samedi 10 octobre 2009

Dans le .NET Framework, on retrouve l'interface IEnumerable (ainsi que sa version générique, IEnumerable<T> depuis la version 2.0). Toute classe implémentant cette interface pourra être parcourue avec un foreach.

Java possède, depuis sa version 1.5, un équivalent, l'interface Iterable. Une classe implémentant Iterable pourra être parcourue avec un for.

En C#, j'ai tendance à utiliser le plus possible IEnumerable: c'est le dénominateur commun. Alors quand je me suis mis à faire du Java, j'ai décidé d'employer Iterable pour les mêmes raisons. Sauf que j'ai découvert quelque chose d'étrange.

Avec .NET, les tableaux implémentent IEnumerable. On peut donc passer un tableau à une méthode qui attend un IEnumerable en paramètre. Or, en Java, les tableaux n'implémentent pas Iterable. On peut les parcourir comme un Iterable, mais c'est probablement du à une "patch" du compilateur. Je n'ai aucune idée de pourquoi est-ce que c'est le cas, mais toujours est-il qu'on ne peut donc pas faire la même chose qu'avec .NET.

Mais ce n'est pas vraiment un problème. Il suffit de coder un adaptateur! Et c'est ce que j'ai fait:


import java.util.Iterator;
import java.util.NoSuchElementException;

/**
* Un adaptateur permettant d'utiliser un tableau là où un Iterable<T> est requis
* @author Etienne de Martel
* @param <T> Le type d'un élément du tableau
*/
public class IterableArray<T> implements Iterable<T>
{
// Un itérateur sur un tableau
private class ArrayIterator implements Iterator<T>
{
T[] _array;
int _index;

public ArrayIterator(T[] array)
{
_array = array;
_index = 0;
}

@Override
public boolean hasNext()
{
return _index < _array.length;
}

@Override
public T next()
{
if(!hasNext())
throw new NoSuchElementException();
return _array[_index++];
}

// Cet itérateur est en lecture seule
@Override
public void remove()
{
throw new UnsupportedOperationException();
}

}

private T[] _array;

/**
* Construit un nouvel adaptateur
* @param array Le tableau autour duquel l'adaptateur sera construit
* @throws NullPointerException Le tableau passé en paramêtre est null
*/
public IterableArray(T[] array) throws NullPointerException
{
if(array == null)
throw new NullPointerException("array cannot be null");
_array = array;
}

@Override
public Iterator<T> iterator()
{
return new ArrayIterator(_array);
}

}


Voilà. Have fun.

1 commentaires:

grinwik a dit…

Bonjour,

Il existe la méthode Arrays.asList() (java.util) qui répond à cette problématique.

Enregistrer un commentaire