iterator相关知识
-
IteratorIterator迭代器: 当使用迭代器遍历元素,并删除元素时,要使用迭代器内部的remove, 不能使用集合对象的remove. @Test public void testIteratorError(){ Map<String,String> map = new HashMap<>(); map.put("k1","v1"); map.put("k2","v2"); map.put("k3","v3"); map.put("k4","v4"); map.put("k5","v5"); Collection<String> collection = map.values(); //增强型for循环. 内部使用的是Iterator进行迭代. for (String s : collection) { if(s == "v2"){ //使用
-
迭代器Iterator的注释Java中的Iterator功能比较简单,并且只能单向移动: (1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。注意:iterator()方法是java.lang.Iterable接口,被Collection继承。 (2) 使用next()获得序列中的下一个元素。 (3) 使用hasNext()检查序列中是否还有元素。 (4) 使用remove()将迭代器新返回的元素删除。 Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个
-
SPL迭代器接口(二)—Iterator InterfaceIterator Interface:直接继承自Traversable接口的两个基本迭代器接口之一。 Iterator接口允许一个类实现一个基本的迭代功能,从而使它可以被循环访问,根据键值访问和回滚。 示例代码: <?php //自定义数组容器实现迭代器接口 class MyIterator implements Iterator { protected $data = array('唐朝','宋朝','元朝'); //存放数据 protected $index ; //存放当前指针 public function current() { return $this->data[$this->index]; } //指针+1 public function
-
阮一峰的iterator遍历器Iterator 遍历器的概念 JavaScript原有的表示 “集合”的数据结构,主要是数组 array和对象object ,ES6 又添加了Map和 Set, 这样就有了四种数据集合了,用户还可以组合使用它们,定义自己的数据结构,比如数组的成员是Map,Map的成员是对象,这样就需要一种统一的接口机制,来处理所有不同的数据结构。 Iterator 遍历器就是这样一种机制,他是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署Iterator接口。就可以完成遍历操作(即依次操作处理该数据结构的
iterator相关课程
iterator相关教程
- 3. 迭代协议 使用迭代器遍历访问可迭代对象,要求迭代器和可迭代对象遵循迭代协议,迭代协议如下:可迭代对象 iterable 提供成员方法 __iter__,该方法返回用于遍历的迭代器 iteratorclass Iterable: def __iter__(self):迭代器 iterator 提供成员方法 __next__,该方法返回下一个被遍历的元素class Iterator: def __next__(self):异常 StopIteration,当遍历完全部的元素后,成员方法 __next__ 抛出一个特殊的异常 Stop Iteration 表示遍历结束内置函数 iter,用于获取可迭代对象对应的迭代器def iter(iterable): iterator = iterable.__iter__() return iterator在第 1 行,iter 的输入参数是可迭代对象 iterable在第 2 行,调用成员方法 __iter__在第 3 行,返回迭代器 iterator内置函数 next,用于获取下一个被遍历的元素def next(iterator): item = iterator.__next__() return item在第 1 行,next 的输入参数是迭代器 iterator在第 2 行,调用成员方法 __next__在第 3 行,返回被遍历的元素根据以上的迭代协议,即可将 for … in 循环翻译为如下等价代码:iterator = iter(iterable)while True: try: item = next(iterator) print(item) except StopIteration: break
- 4.4 LinkedHashMap LinkedHashMap 记录了元素保存的顺序,因此在遍历的时候可以按照当时的顺序读取,一般用于我们需要保留元素顺序的场景。Map<String, String> hashMap = new HashMap<String, String>();hashMap.put("水果", "苹果");hashMap.put("蔬菜", "白菜");hashMap.put("坚果", "核桃");Iterator<Map.Entry<String, String>> iterator = hashMap.entrySet().iterator();while(iterator.hasNext()) { Map.Entry entry = iterator.next(); String key = (String) entry.getKey(); String value = (String) entry.getValue(); System.out.println("key:" + key + ",value:" + value);}对于无序的 HashMap,依次输出key: 蔬菜,value: 白菜key: 水果,value: 苹果key: 坚果,value: 核桃Map<String, String> linkedHashMap = new LinkedHashMap<String,String>();linkedHashMap.put("水果", "苹果");linkedHashMap.put("蔬菜", "白菜");linkedHashMap.put("坚果", "核桃");Iterator<Map.Entry<String, String>> iterator = linkedHashMap.entrySet().iterator();while(iterator.hasNext()) { Map.Entry entry = iterator.next(); String key = (String) entry.getKey(); String value = (String) entry.getValue(); System.out.println("key:" + key + ",value:" + value);}对于有序的 LinkedHashMap,依次输出key: 水果,value: 苹果key: 蔬菜,value: 白菜key: 坚果,value: 核桃
- 1.1 什么是迭代器 迭代器 iterator 是一个特殊的对象,用于遍历访问可迭代对象 iterable。Python 通过迭代器 iterator 实现 for … in 循环语句,用户编写的 for … in 循环代码如下:for item in iterable: print(item)这段 for … in 循环代码会被翻译为如下:iterator = iter(iterable)while True: try: item = next(iterator) print(item) except StopIteration: break在第 1 行,内置函数 iter 获取可迭代对象 iterable 的迭代器 iterator在第 4 行,内置函数 next 获取迭代器 iterator 返回的下一个元素在第 6 行,当迭代器遍历完全部元素后,抛出一个特殊的异常 StopIteration,表示迭代结束
- 2.1 语法使用 for (const iterator of iterable) { // 执行语句}参数解释:参数描述iterator在每次迭代中,将不同属性的值分配给变量,用于循环中语句的使用;iterable被迭代枚举的对象。
- 6. Sequences 原理源码完全解析 //使用序列fun main(args: Array<String>){ (0..100) .asSequence() .map { it + 1 } .filter { it % 2 == 0 } .find { it > 3 }}//使用普通集合fun main(args: Array<String>){ (0..100) .map { it + 1 } .filter { it % 2 == 0 } .find { it > 3 }}通过 decompile 上述例子的源码会发现,普通集合操作会针对每个操作都会生成一个 while 循环,并且每次都会创建新的集合保存中间结果。而使用序列则不会,它们内部会无论进行多少中间操作都是共享同一个迭代器中的数据,想知道共享同一个迭代器中的数据的原理吗?请接着看内部源码实现。6.1 使用集合普通操作反编译源码 public static final void main(@NotNull String[] args) { Intrinsics.checkParameterIsNotNull(args, "args"); byte var1 = 0; Iterable $receiver$iv = (Iterable)(new IntRange(var1, 100)); //创建新的集合存储map后中间结果 Collection destination$iv$iv = (Collection)(new ArrayList(CollectionsKt.collectionSizeOrDefault($receiver$iv, 10))); Iterator var4 = $receiver$iv.iterator(); int it; //对应map操作符生成一个while循环 while(var4.hasNext()) { it = ((IntIterator)var4).nextInt(); Integer var11 = it + 1; //将map变换的元素加入到新集合中 destination$iv$iv.add(var11); } $receiver$iv = (Iterable)((List)destination$iv$iv); //创建新的集合存储filter后中间结果 destination$iv$iv = (Collection)(new ArrayList()); var4 = $receiver$iv.iterator();//拿到map后新集合中的迭代器 //对应filter操作符生成一个while循环 while(var4.hasNext()) { Object element$iv$iv = var4.next(); int it = ((Number)element$iv$iv).intValue(); if (it % 2 == 0) { //将filter过滤的元素加入到新集合中 destination$iv$iv.add(element$iv$iv); } } $receiver$iv = (Iterable)((List)destination$iv$iv); Iterator var13 = $receiver$iv.iterator();//拿到filter后新集合中的迭代器 //对应find操作符生成一个while循环,最后末端操作只需要遍历filter后新集合中的迭代器,取出符合条件数据即可。 while(var13.hasNext()) { Object var14 = var13.next(); it = ((Number)var14).intValue(); if (it > 3) { break; } } }6.2 使用序列 (Sequences) 惰性操作反编译源码1、整个序列操作源码 public static final void main(@NotNull String[] args) { Intrinsics.checkParameterIsNotNull(args, "args"); byte var1 = 0; //利用Sequence扩展函数实现了fitler和map中间操作,最后返回一个Sequence对象。 Sequence var7 = SequencesKt.filter(SequencesKt.map(CollectionsKt.asSequence((Iterable)(new IntRange(var1, 100))), (Function1)null.INSTANCE), (Function1)null.INSTANCE); //取出经过中间操作产生的序列中的迭代器,可以发现进行map、filter中间操作共享了同一个迭代器中数据,每次操作都会产生新的迭代器对象,但是数据是和原来传入迭代器中数据共享,最后进行末端操作的时候只需要遍历这个迭代器中符合条件元素即可。 Iterator var3 = var7.iterator(); //对应find操作符生成一个while循环,最后末端操作只需要遍历filter后新集合中的迭代器,取出符合条件数据即可。 while(var3.hasNext()) { Object var4 = var3.next(); int it = ((Number)var4).intValue(); if (it > 3) { break; } } }2、抽出其中这段关键 code,继续深入:SequencesKt.filter(SequencesKt.map(CollectionsKt.asSequence((Iterable)(new IntRange(var1, 100))), (Function1)null.INSTANCE), (Function1)null.INSTANCE);3、把这段代码转化分解成三个部分://第一部分val collectionSequence = CollectionsKt.asSequence((Iterable)(new IntRange(var1, 100)))//第二部分val mapSequence = SequencesKt.map(collectionSequence, (Function1)null.INSTANCE)//第三部分val filterSequence = SequencesKt.filter(mapSequence, (Function1)null.INSTANCE)4、解释第一部分代码:第一部分反编译的源码很简单,主要是调用 Iterable 中扩展函数将原始数据集转换成 Sequence 对象。public fun <T> Iterable<T>.asSequence(): Sequence<T> { return Sequence { this.iterator() }//传入外部Iterable<T>中的迭代器对象}更深入一层:@kotlin.internal.InlineOnlypublic inline fun <T> Sequence(crossinline iterator: () -> Iterator<T>): Sequence<T> = object : Sequence<T> { override fun iterator(): Iterator<T> = iterator()}通过外部传入的集合中的迭代器方法返回迭代器对象,通过一个对象表达式实例化一个 Sequence,Sequence 是一个接口,内部有个 iterator () 抽象函数返回一个迭代器对象,然后把传入迭代器对象作为 Sequence 内部的迭代器,也就是相当于给迭代器加了 Sequence 序列的外壳,核心迭代器还是由外部传入的迭代器对象,有点偷梁换柱的概念。5、解释第二部分的代码:通过第一部分,成功将普通集合转换成序列 Sequence,然后现在进行 map 操作,实际上调用了 Sequence 扩展函数 map 来实现的val mapSequence = SequencesKt.map(collectionSequence, (Function1)null.INSTANCE)进入 map 扩展函数:public fun <T, R> Sequence<T>.map(transform: (T) -> R): Sequence<R> { return TransformingSequence(this, transform)}会发现内部会返回一个 TransformingSequence 对象,该对象构造器接收一个 Sequence 类型对象,和一个 transform 的 lambda 表达式,最后返回一个 Sequence 类型对象。我们先暂时解析到这,后面会更加介绍。6、解释第三部分的代码:通过第二部分,进行 map 操作后,然后返回的还是 Sequence 对象,最后再把这个对象进行 filter 操作,filter 也还是 Sequence 的扩展函数,最后返回还是一个 Sequence 对象。val filterSequence = SequencesKt.filter(mapSequence, (Function1)null.INSTANCE)进入 filter 扩展函数:public fun <T> Sequence<T>.filter(predicate: (T) -> Boolean): Sequence<T> { return FilteringSequence(this, true, predicate)}会发现内部会返回一个 FilteringSequence 对象,该对象构造器接收一个 Sequence 类型对象,和一个 predicate 的 lambda 表达式,最后返回一个 Sequence 类型对象。我们先暂时解析到这,后面会更加介绍。7、Sequences 源码整体结构介绍代码结构图 :图中标注的都是一个个对应各个操作符类,它们都实现 Sequence 接口首先,Sequence 是一个接口,里面只有一个抽象函数,一个返回迭代器对象的函数,可以把它当做一个迭代器对象外壳。public interface Sequence<out T> { /** * Returns an [Iterator] that returns the values from the sequence. * * Throws an exception if the sequence is constrained to be iterated once and `iterator` is invoked the second time. */ public operator fun iterator(): Iterator<T>}Sequence 核心类 UML 类图这里只画出了某几个常用操作符的类图注意:通过上面的 UML 类关系图可以得到,共享同一个迭代器中的数据的原理实际上就是利用 Java 设计模式中的状态模式 (面向对象的多态原理) 来实现的,首先通过 Iterable 的 iterator () 返回的迭代器对象去实例化 Sequence,然后外部调用不同的操作符,这些操作符对应着相应的扩展函数,扩展函数内部针对每个不同操作返回实现 Sequence 接口的子类对象,而这些子类又根据不同操作的实现,更改了接口中 iterator () 抽象函数迭代器的实现,返回一个新的迭代器对象,但是迭代的数据则来源于原始迭代器中。8、接着上面 TransformingSequence、FilteringSequence 继续解析.通过以上对 Sequences 整体结构深入分析,那么接着 TransformingSequence、FilteringSequence 继续解析就非常简单了。我们就以 TransformingSequence 为例://实现了Sequence<R>接口,重写了iterator()方法,重写迭代器的实现internal class TransformingSequence<T, R>constructor(private val sequence: Sequence<T>, private val transformer: (T) -> R) : Sequence<R> { override fun iterator(): Iterator<R> = object : Iterator<R> {//根据传入的迭代器对象中的数据,加以操作变换后,构造出一个新的迭代器对象。 val iterator = sequence.iterator()//取得传入Sequence中的迭代器对象 override fun next(): R { return transformer(iterator.next())//将原来的迭代器中数据元素做了transformer转化传入,共享同一个迭代器中的数据。 } override fun hasNext(): Boolean { return iterator.hasNext() } } internal fun <E> flatten(iterator: (R) -> Iterator<E>): Sequence<E> { return FlatteningSequence<T, R, E>(sequence, transformer, iterator) }}9、源码分析总结序列内部的实现原理是采用状态设计模式,根据不同的操作符的扩展函数,实例化对应的 Sequence 子类对象,每个子类对象重写了 Sequence 接口中的 iterator () 抽象方法,内部实现根据传入的迭代器对象中的数据元素,加以变换、过滤、合并等操作,返回一个新的迭代器对象。这就能解释为什么序列中工作原理是逐个元素执行不同的操作,而不是像普通集合所有元素先执行 A 操作,再所有元素执行 B 操作。这是因为序列内部始终维护着一个迭代器,当一个元素被迭代的时候,就需要依次执行 A,B,C 各个操作后,如果此时没有末端操作,那么值将会存储在 C 的迭代器中,依次执行,等待原始集合中共享的数据被迭代完毕,或者不满足某些条件终止迭代,最后取出 C 迭代器中的数据即可。
- 3. 示例代码 function* generatorFunction() { console.log('开始执行') yield 'Hello, ' console.log('暂停后再次执行') yield 'World!'}let iterator = generatorFunction()此时,通过 function* 语法创建了一个生成器函数,调用这个函数并赋值给变量 iterator,我们已经知道这是个对象。console.log(iterator.next().value)// 开始执行// Hello, 调用 iterator 对象上的 next() 方法,首先打印出 开始执行,然后遇到了 yield Hello,,yield 会将后面的值返回,生成器生成一个对象 { value: 'Hello, ', done: false },函数停止运行,直到再次调用 next() 方法。console.log(iterator.next().value)// 暂停后再次执行// World!再次调用 next() 方法,函数内继续执行,打印出 暂停后再次执行,遇到 yield 'World!',生成对象 { value: 'World!', done: false },函数停止运行,直到再次调用 next() 方法。console.log(iterator.next())再次调用 next() 方法,这次函数内没有返回值,也就是默认返回 undefined, 生成对象 { value: 'undefined', done: true }。
iterator相关搜索
-
inline
inner join
innerhtml
innerjoin
input
input readonly
input 属性
inputstream
inputtype
input属性
insert
insert into
insert into select
insertbefore
insertinto
insert语句
inspect
instance
instant
instr