Maison > Java > javaDidacticiel > Méthode d'implémentation de l'itération de l'itérateur de collection Java

Méthode d'implémentation de l'itération de l'itérateur de collection Java

高洛峰
Libérer: 2017-01-23 17:00:26
original
1193 Les gens l'ont consulté

Nous utilisons souvent l'interface d'itération fournie par JDK pour itérer les collections Java.

Iterator iterator = list.iterator();
while(iterator.hasNext()){
String string = iterator.next();
//do something
}
Copier après la connexion

En fait, nous pouvons simplement comprendre l'itération comme un parcours, qui est une classe de méthodes standardisée pour parcourir tous les objets dans divers conteneurs. C'est un modèle de conception très typique. Le modèle Iterator est la méthode d’accès standard pour itérer sur les classes de collection. Il peut abstraire la logique d'accès de différents types de classes de collection, évitant ainsi d'exposer la structure interne de la collection au client. C'est ainsi que nous procédons lorsqu'il n'y a pas d'itérateurs. Comme suit :

Pour les tableaux, nous utilisons des indices pour traiter :

int[] arrays = new int[10];
for(int i = 0 ; i < arrays.length ; i++){
int a = arrays[i];
//do something
}
Copier après la connexion

Pour ArrayList, voici comment nous le traitons :

List<String> list = new ArrayList<String>();
for(int i = 0 ; i < list.size() ; i++){
String string = list.get(i);
//do something
}
Copier après la connexion

Pour les deux méthodes, nous connaissons toujours à l'avance la structure interne de la collection. Le code d'accès et la collection elle-même sont étroitement couplés, et la logique d'accès ne peut pas être séparée de la classe de collection et du code client. .sortez. En même temps, chaque collection correspond à une méthode de parcours et le code client ne peut pas être réutilisé. Dans les applications pratiques, il est assez difficile d’intégrer les deux ensembles ci-dessus. Ainsi, afin de résoudre les problèmes ci-dessus, le mode Iterator est né, qui utilise toujours la même logique pour parcourir la collection. Cela élimine le besoin pour le client lui-même de maintenir la structure interne de la collection, et tous les états internes sont gérés par Iterator. Le client ne traite jamais directement avec la classe de collection. Il contrôle toujours l'Iterator et lui envoie les commandes "forward", "backward" et "get the current element" pour parcourir indirectement toute la collection.

Ce qui précède n'est qu'une brève explication du modèle Iterator. Jetons un coup d'œil à l'interface Iterator en Java pour voir comment elle est implémentée.

1. java.util.Iterator

En Java, Iterator est une interface qui ne fournit que des règles de base pour l'itération. Dans le JDK, il est défini comme ceci. : Itérateur pour itérer sur la collection. Les itérateurs remplacent l'énumération dans Java Collections Framework. Il existe deux différences entre les itérateurs et les énumérations :

1. Les itérateurs permettent à l'appelant d'utiliser une sémantique bien définie pour supprimer des éléments de la collection pointée par l'itérateur lors de l'itération.

2. Le nom de la méthode a été amélioré.

L'interface est définie comme suit :

public interface Iterator {
  boolean hasNext();
  Object next();
  void remove();
}
Copier après la connexion

Parmi eux :

Object next() : Renvoie le itérateur vient de traverser Une référence à un élément, la valeur de retour est Object, qui doit être convertie dans le type dont vous avez besoin

boolean hasNext() : Déterminez s'il y a des éléments accessibles dans le conteneur

🎜>

void remove() : Supprime l'élément qui vient de traverser l'itérateur

for(Iterator it = c.iterator(); it.hasNext(); ) {
  Object o = it.next();
   //do something
}
Copier après la connexion
Pour nous, nous n'avons généralement besoin que d'utiliser next() et hasNext() pour terminer l'itération . Comme suit :


Comme expliqué précédemment, Iterator a un grand avantage, c'est-à-dire que nous n'avons pas besoin de connaître les résultats internes de l'ensemble. La structure interne et l'état de. l'ensemble est maintenu par Iterator, via unification. Les méthodes hasNext() et next() sont utilisées pour déterminer et obtenir l'élément suivant. Quant à l'implémentation interne spécifique, nous n'avons pas à nous en préoccuper. Mais en tant que programmeur qualifié, il est absolument nécessaire pour nous de comprendre l'implémentation d'Iterator. Analysons le code source d'ArrayList.


2. Implémentation de l'itérateur de chaque collection


Ce qui suit est une analyse de l'implémentation de l'itérateur d'ArrayList. En fait, si nous comprenons la structure des données d'ArrayList, Hashset et TreeSet, l'implémentation interne, ils auront également une bonne idée de la façon dont ils implémentent Iterator. Parce que l'implémentation interne d'ArrayList utilise des tableaux, il suffit d'enregistrer l'index de la position correspondante, et l'implémentation de sa méthode est relativement simple.


2.1. Implémentation Iterator d'ArrayList

private class Itr implements Iterator<E> {
//do something
}
Copier après la connexion
Dans ArrayList, nous définissons d'abord une classe interne Itr, qui implémente l'interface Iterator, comme suit :

public Iterator<E> iterator() {
return new Itr();
}
Copier après la connexion
La méthode iterator() d'ArrayList implémente :


Donc, ce qui est renvoyé en utilisant la méthode ArrayList.iterator() est le Itr( ), donc ce dont nous devons nous soucier maintenant, c'est l'implémentation de la classe interne Itr() :

int cursor;
int lastRet = -1;
int expectedModCount = modCount;
Copier après la connexion
Trois variables de type int sont définies à l'intérieur d'Itr : curseur, lastRet, attenduModCount. Où le curseur représente la position d'index de l'élément suivant, lastRet représente la position d'index de l'élément précédent

public boolean hasNext() {
return cursor != size;
}
Copier après la connexion
D'après les définitions de curseur et lastRet, nous pouvons voir que lastRet est toujours un de moins que le curseur, donc hasNext () La méthode d'implémentation est extrêmement simple, il vous suffit de déterminer si le curseur et lastRet sont égaux.

public E next() {
checkForComodification();
int i = cursor; //记录索引位置
if (i >= size) //如果获取元素大于集合元素个数,则抛出异常
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1; //cursor + 1
return (E) elementData[lastRet = i]; //lastRet + 1 且返回cursor处元素
}
Copier après la connexion
L'implémentation de next() est en fait relativement simple. Renvoyez simplement l'élément à la position d'index du curseur, puis modifiez le curseur et lastRet

< 🎜><🎜>

checkForComodification() 主要用来判断集合的修改次数是否合法,即用来判断遍历过程中集合是否被修改过。modCount 用于记录 ArrayList 集合的修改次数,初始化为 0,,每当集合被修改一次(结构上面的修改,内部update不算),如 add、remove 等方法,modCount + 1,所以如果 modCount 不变,则表示集合内容没有被修改。该机制主要是用于实现 ArrayList 集合的快速失败机制,在 Java 的集合中,较大一部分集合是存在快速失败机制的,这里就不多说,后面会讲到。所以要保证在遍历过程中不出错误,我们就应该保证在遍历过程中不会对集合产生结构上的修改(当然 remove 方法除外),出现了异常错误,我们就应该认真检查程序是否出错而不是 catch 后不做处理。

final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
Copier après la connexion

对于 remove() 方法的是实现,它是调用 ArrayList 本身的 remove() 方法删除 lastRet 位置元素,然后修改 modCount 即可。

public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
Copier après la connexion

以上所述是小编给大家介绍的Java集合Iterator迭代的实现方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对PHP中文网的支持!

更多Java集合Iterator迭代的实现方法相关文章请关注PHP中文网!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal