Quand j'étudiais Stream et pour Each, je suis tombé sur un mot inconnu appelé itérateur interne, donc un mémo à ce moment-là. C'est probablement approprié parce que je l'ai compris moi-même.
Ce qui m'a surpris lorsque j'ai appris le mot itérateur interne, c'est qu'il existe deux types d'itérateurs: les itérateurs internes et les itérateurs externes. Puis je me suis demandé ce que je connaissais de l'itérateur, alors j'ai d'abord étudié l'itérateur.
Iterator (anglais: iterator) est une abstraction du traitement itératif pour chaque élément d'un tableau ou d'une structure de données collective similaire (collection ou conteneur) dans un langage de programmation. Dans le langage de programmation actuel, il apparaît comme un objet ou une grammaire. Dans JIS, il est traduit par un répéteur (Hampukushi) [1] [2].
Citation: Iterator-Wikipedia
Est-ce une abstraction du traitement itératif? J'ai l'impression d'avoir compris cela. Il existe deux types de cette abstraction, externe et interne. Regardons maintenant la différence entre les deux.
En Java, l'objet qui implémente la famille d'interfaces java.util.Iterator est l'itérateur externe. Iterator depuis Java 1.5 prend en charge les génériques.
Citation: Iterator-Wikipedia
En d'autres termes, ce que j'ai reconnu comme un itérateur était un itérateur externe. Ainsi, l'implémentation de l'itérateur externe ressemble à ceci.
Itérateur externe
Iterator<Hoge> iterator =Celui qui implémente Iterable.iterator()
while (iterator.hasNext()) {
// iterator.next()Quelque chose à faire
}
Je l'ai écrit de manière assez appropriée, mais en implémentant une interface appelée Iterable et en ayant un Iterator, il est possible d'abstraire le processus itératif. Puisque la partie répétitive (while) est exposée à l'extérieur, est-elle appelée un itérateur externe?
Le type de méthode de répétition dans lequel un bloc Ruby qui exprime le traitement de chaque élément est passé à la méthode de l'objet conteneur et la méthode rappelle le traitement de chaque élément est appelé "itérateur interne".
L'itérateur interne ne crée pas de classes supplémentaires et est facile à utiliser et à créer. Cependant, si le langage ne prend pas en charge la fermeture, il sera nécessaire de concevoir des moyens de partager des informations entre le corps de la boucle et l'extérieur, et comme le montre l'exemple du langage C, l'utilisabilité en tant que boucle se détériorera. Pour cette raison, des itérateurs externes sont utilisés en C ++ et Java qui n'ont pas de fermetures.
Citation: Matsumoto Naoden Programming Okite 5th (2)
Je ne suis pas sûr, alors je vais regarder la mise en œuvre.
Itérateur interne
List<Integer> list =Liste de quelque chose;
list.forEach(n -> n + 1);
//Imaginaire pour chacun
forEach(En traitement) {
for (répétition) {
//Processus d'appel;
}
}
En d'autres termes, la répétition est à l'intérieur et passe le traitement que vous souhaitez effectuer. C'est pourquoi je l'appelle un itérateur interne. En Java, il n'y a pas de fonction de première classe, alors passez une interface fonctionnelle.
Donc, ce dont je ne suis pas sûr ici, c'est qu'il est difficile d'implémenter un itérateur interne s'il ne prend pas en charge les fermetures. Pourquoi avez-vous besoin d'une fermeture?
Je ne savais pas grand-chose sur les fermetures au départ, alors j'ai cherché. J'ai compris qu'une fonction contient des variables autres qu'à l'intérieur de la fonction en tant que portée. J'ai beaucoup recherché ici aussi, alors j'aimerais écrire un autre article.
fermeture
function createCounter() {
let count = 0;
return function() {
count++;
console.log(count);
};
}
let counter = createCounter();
counter(); // 1
counter(); // 2
Avec JS, ça ressemble à ça.
Au début, je ne savais pas pourquoi j'en avais besoin. D'une certaine manière, j'ai compris en recherchant la fermeture. Exemple de code Java pour le moment.
Itérateur interne et fermeture
final List<Integer> list =Liste de quelque chose
final Integer n =Un certain nombre;
list.forEach(value -> value + n);
//Imaginaire pour chacun
forEach(En traitement) {
for (répétition) {
//Processus d'appel;
}
}
À ce stade, en raison du mécanisme de fermeture, n peut être utilisé en entrant dans la portée même dans le processus passé à forEach. S'il n'y a pas de clôture, il est nécessaire de prévoir un mécanisme pour passer des arguments ou de l'avoir comme champ à répéter. En d'autres termes, la fermeture facilite la mise en œuvre.
Il existe deux types d'itérateurs: les itérateurs externes et les itérateurs internes. L'itérateur interne semble plus intelligent personnellement. Cependant, sans fermeture, la mise en œuvre d'un itérateur interne est lourde.
Quand j'étudie habituellement, je prends des notes, alors j'ai écrit un article sur cette base. Je ne peux rien écrire de plus approprié que ce que les gens peuvent voir, et la source de la citation est-elle vraiment correcte? Je dois y réfléchir. Eh bien, cette fois, je l'ai écrit comme un essai, donc je pense qu'il y a quelque chose d'approprié, mais je veux prendre plus de temps quand j'écrirai quelque chose la prochaine fois.
Aussi, j'ai principalement écrit sur Java, mais il semble que la fermeture en Java soit un peu différente des autres langages fonctionnels. J'ai vu un article disant: "Java 8 lambda n'est pas une fermeture, mais vous pouvez faire ce que vous voulez avec une fermeture, et vous ne pouvez pas faire ce que vous ne pouvez pas faire, donc il n'y a rien de mal à cela." Je ne suis pas sûr de cela, alors je vais enquêter davantage.
Recommended Posts