迭代器

前两天学习了数据结构与算法中的有关线性表的内容,在自己写代码实现各种表的时候,都会用到迭代器对表进行遍历,之前并没有过多了解迭代器,借此机会好好学习一下。

迭代器常用与集合遍历,集合遍历包括三种,分别是迭代器遍历、增强for遍历以及lambda表达式遍历。不禁要想,之前我们遍历最常用的就是for循环,为什么这里没有了呢,是因为索引问题。我们之前遍历数组,数组是可以通过索引查找元素的,所以用不同的for循环就行。但是在集合Collection中,List集合有索引,但Set集合没有索引,因此就不能用for循环了,就有了上述三种遍历方法。

先来学习迭代器遍历。迭代器无非也是从头开始遍历集合,查找元素,不过迭代器不依赖索引,这是其特点。迭代器是一个对象(Iterator),我们是用它之前就要创建迭代器对象,可以简单的将其理解为是一个指针,指向集合的第一个元素(就可以按照数组,理解为索引0)。

Iterator<E> iterator()//返回一个迭代器对象

创建好一个Iterator后,指针会指向0索引,然后要判断这个位置是否有元素,有专门的判断方法。有返回true,没有返回false。

boolean hasNext()

之后就可以获取当前指针指向的元素,那想获取下一个元素的话我们是不是应该将指针往后移一位呀,这里又会用到一个方法,同时帮助我们实现这两个功能。

E next()

那我们该如何获取这个集合中的每一个元素呢?将while()循环和迭代器结合,就可以获取到集合中的每一个元素.

Iterator<String> it = list.iterator();
while(it.hasNext()){
	String str = it.next();
  	System.out.println(str);
}

迭代器细节注意点:

1.当指针已经指向空了,也就是到末尾的后面了,此时你要是非要继续获取元素,运行会报错,报NoSuchElementException,就是说已经没有元素给你取了。像我们遍历数组,索引查出了范围,会报索引越界的错误,但是集合没有索引,因此就报的没有数据的错误。

2.迭代完毕后,指针不会复位,要想重新迭代你就得再创建个迭代器对象

3.循环中只能用一次.next()方法。这个是为什么呢?看下面这段代码就知道了,collection中要是有偶数个元素是没问题的,要是奇数个元素就出错了,比如现在指针已经指向了eee,while判断后进入循环,第一个next()拿到了eee,那此刻指针是不是已经出去到,到了集合的范围外,那你在使用next()获取元素就肯定错了呀。

public static void main(String[] args) {
        //1.创建集合并添加元素
        Collection<String > collection = new ArrayList<>();
        collection.add("aaa");
        collection.add("bbb");
        collection.add("ccc");
        collection.add("ddd");
        collection.add("eee");

        Iterator<String> iterator = collection.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());//aaa ccc eee
            System.out.println(iterator.next());//bbb ddd null
        }
    }

4.在循环中,不能使用集合的方法进行增加或者删除。你要是不听劝用了,运行会报错ConcurrentModificationException,并发修改异常。如果想删除,可以用Iterator提供的remove()方法。

下面来看看在集合中,迭代器的原码是怎么实现的,我是在ArrrayList中找的。

发现有一个方法iterator(),它的返回值是一个Iterator的接口,因此要return一个Iterator对象。在ArrayList中,sun公司定义类一个内部类,我们知道内部类依然可以做接口实现和类的继承,这个内部类叫做Itr,实现了Iterator接口。

public Iterator<E> iterator() {
  //返回接口实现类的对象
   return new Itr();
}

    /**
     * An optimized version of AbstractList.Itr
     */
//内部类
//无法直接访问这个内部类,因为已经私有了,只能通过iterator()这个方法获得内部类的对象。
private class Itr implements Iterator<E> {
	//要重写方法
	public boolean hasNext(){
		return false;
	}
  
	public Object next(){
		return null;
	}
  	
  	public void remove(){
	
	}
}

那现在我们再来看一下 Iterator<String> iterator = collection.iterator();这句代码。collection.iterator()这里我们得到了一个对象,是哪个对象,是不是内部类对象,也就是Iterator这个接口实现类的对象,所以这个对象能调用接口中的方法,只不过是实现类中重写后的方法。

以上就是Iterator的基本内容,下面我将写写有关增强for遍历的内容。

增强for的底层就是迭代器,为了简化迭代器而书写的。

集合可以根据其存储结构分成两大类,分别是单列集合java.lang.Collection和双列集合java.lang.Map,只有的单列集合和数组才能用增强for遍历。

for(元素的数据类型 变量名:数组或集合){

}

for(String s : list){
	System.out.println(s);//s为第三方变量
}

增强for中的一个小细节,其中s仅仅是一个第三方变量而已,修改s不会改变原来的数据。不过是遍历集合的时候将元素用第三方变量记录而已。

又会了很多东西呀,一点点积累好兄弟们。

#如何看待2023届秋招##你的秋招进展怎么样了##0offer是寒冬太冷还是我太菜##我的求职思考#
java基础知识 文章被收录于专栏

我是一个转码的小白,平时会在牛客中做选择题,在做题中遇到不会的内容就会去找视频或者文章学习,以此不断积累知识。这个专栏主要是记录一些我通过做题所学到的基础知识,希望能对大家有帮助

全部评论

相关推荐

07-01 17:14
中北大学 Java
兄弟们是真是假
牛客46374834...:我在boss上投java岗从来没成功过
点赞 评论 收藏
分享
那一天的Java_J...:他本来公司就是做这个的,不就是正常的游戏客户端和服务器开发,软硬件联动,有啥恶心不恶心的,提前告诉你就是怕你接受不了,接受不了就没必要再往后走流程浪费时间,虽然这公司是一坨。
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-02 15:39
点赞 评论 收藏
分享
评论
33
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务