从屌丝到架构师的飞越(集合篇)-迭代器

一.介绍

迭代器(iterator)有时又称游标(cursor)是程序设计的软件设计模式,可在容器(container,例如链表或阵列)上遍访的接口,设计人员无需关心容器的内容。

迭代器(iterator)是一种对象,它能够用来遍历标准模板库容器中的部分或全部元素,每个迭代器对象代表容器中的确定的地址。迭代器修改了常规指针的接口,所谓迭代器是一种概念上的抽象:那些行为上像迭代器的东西都可以叫做迭代器。然而迭代器有很多不同的能力,它可以把抽象容器和通用算法有机的统一起来。

二.内容

集合用来持有数据,一定会设计出对数据的增、删、改、查四个常用方法,而查是集合中最常用的功能。Collection接口继承了Iterable接口,具备了可迭代功能iterator方法,该方法用于迭代集合。所以,所有单列集合由于是Collection的直接或间接实现类,均具有该方法。

这里涉及到以下内容共同完成集合的迭代:

Collection接口的iterator方法,所以单列集合实现类均有该方法

iterator方法的返回值类型Iterator接口类型

Iterator接口的两个方法:hasNext与next方法

1.迭代常规步骤

(1)通过集合获取这个集合的迭代器

(2)结合使用迭代器的hashNext与next完成集合迭代

如:

ArryList<String> list = new ArryList <String>();

hs.add("i love java");

hs.add("i like java");

//返回迭代器

Iterator<String> iterator = list.iterator();

//调用hasNext与next完成集合迭代

while (iterator.hasNext()) {

String string = iterator.next();

System.out.println(string);

}

2.Collection接口的Iterator

方法声明为:

Iterator<集合中数据类型>  iterator()

用来返回专属于该集合对象的迭代器对象(Iterator的子类对象)。

3.Iterator接口

该接口规定了迭代集合所需要的方法

4.Iterator接口的两个方法:hasNext与next方法

Iterator规定了两个方法,集合对象产生的迭代器对象正是通过这两个方法帮助集合进行迭代工作的。

调用迭代器的hasNext方法判断是否有下一个元素

调用迭代器的next获取下一个元素

5.迭代集合元素图解:

6.代码演示

importjava.util.ArrayList;

importjava.util.Collection;

importjava.util.Iterator;

/*

* Iterator<E> iterator() 返回在此 collection 的元素上进行迭代的迭代器。

*

* Iterator 就是帮你去做遍历集合操作 . 

*

* iterator() 返回的就是 Iterator接口的子类对象.

*/

public class Demo2 {

public static void main(String[] args) {

Collection  c  = new ArrayList();

c.add("111");

c.add("222");

c.add("333");

c.add("444");

// 遍历集合.  获取其中每一个元素.

// 1.获取迭代器对象  .

Iterator iterator = c.iterator();  // Iterator 接口  指向 子类对象.

// 2.调用迭代器的方法,获取集合中的元素.

//  Object next = iterator.next();

//  System.out.println(next);

// 

//  Object next2 = iterator.next();

//  System.out.println(next2);

// 

//  Object next3 = iterator.next();

//  System.out.println(next3);

// 

//  Object next4 = iterator.next();

//  System.out.println(next4);

// 

//  Object next5 = iterator.next(); //NoSuchElementException

//  System.out.println(next5);

while(iterator.hasNext()){

Object next = iterator.next();

System.out.println(next);

}

}

}

7.迭代器遍历集合总结

importjava.util.Collection;

importjava.util.Iterator;

importjava.util.ArrayList;

/*

* 1.hasNext 方法和  next方法 说明 . 遍历之前,有一个指针指向初始位置,第一个元素的前面,

*  hasNext,判断是否在指针后面有元素,有返回true ,没有返回false .

*  如果有 , 就可以通过 next() 获取下一个元素了.

* 2.syso(c); 我也能看所有的元素, 那我为什么还要遍历呢? 

* 3.toString() 在哪重写的呢? 你管的着么!!  要找找他爹,他爷爷

*

*/

public class Demo3 {

public static void main(String[] args) {

Collection c = new ArrayList<>();

c.add("aaa");

c.add("abbbbb");

c.add("cccc");

c.add("xxxx ");

// 遍历集合

// 1.获取迭代器

Iterator iterator = c.iterator();

// 2.通过迭代器获取元素 .

while (iterator.hasNext()) { // 是否有下一个.

Object next = iterator.next(); // 获取下一个元素

System.out.println(next);

}

}

}

8.保存自定义对象练习(迭代器移除元素)

public class Student {

String name;  // 姓名 

int score;  // 分数

public Student() {

super();

// TODO Auto-generated constructor stub

}

public Student(String name, int score) {

super();

this.name = name;

this.score = score;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

publicintgetScore() {

return score;

}

public void setScore(int score) {

this.score = score;

}

@Override

public String toString() {

return "学生 [姓名=" + name + ", 分数=" + score + "]";

}

}

importjava.util.ArrayList;

importjava.util.Collection;

importjava.util.Iterator;

/*

* 给你集合 ,保存 很多 学生对象. 学生类中, 包含了姓名和分数. 

*

* 学生1 ("老王" , 66) ;

* 学生2 ("金莲" , 28) ;

* 学生3 ("西门" , 99) ;

*

* 1.把所有对象保存集合.

* 2.遍历集合,把60分以下的同学,移除掉.

* 3.再遍历的时候,只有 60分以上的同学了.

*/

public class Test {

public static void main(String[] args) {

//1. 创建学生对象

Student student1 = new Student("老王" , 66);

Student student2 = new Student("金莲" , 28);

Student student3 = new Student("西门" , 99);

Student student4 = new Student("大郎" , 100);

// 2.创建集合

Collection<Student> c = new ArrayList<>();

// 3.添加元素

c.add(student1);

c.add(student2);

c.add(student3);

c.add(student4);

System.out.println(c);

// 遍历集合,判断分数 .

//a.获取迭代器

Iterator<Student> it  = c.iterator();

//b. 使用迭代器遍历

while (it.hasNext()) {

Student stu  = it.next();

System.out.println(stu);

//获取分数

int score = stu.getScore();

//判断分数

if(score <60){

// 移除学生 

//c.remove(stu);

it.remove(); // 移除当前迭代的元素. (迭代器移除方法可以避免并发修改异常)

}

}

// 再遍历集合

Iterator<Student> iterator = c.iterator();

while (iterator.hasNext()) {

Student student = iterator.next();

System.out.println(student.getName() +" --- "+ student.getScore());

}

}

}

9.三种遍历集合方式对比:

importjava.util.ArrayList;

importjava.util.Collection;

importjava.util.Iterator;

/*

*  1.集合变成数组  .遍历数组 

*  2.迭代器  -- 必须掌握

*  3.增强for  -- 必须掌握

*/

public class Demo2 {

public static void main(String[] args) {

Collection<Object> c = new ArrayList<>();

c.add(111);

c.add(222);

c.add(333);

//1.变成数组

Object[] array = c.toArray();

for (inti = 0; i<array.length; i++) {

System.out.println(array[i]);

}

System.out.println("============");

//2.迭代器

Iterator<Object> iterator = c.iterator();

while (iterator.hasNext()) {

Object next = iterator.next();

System.out.println(next);

}

System.out.println("============");

//3.增强for

for (Object object : array) {

System.out.println(object);

}

}

}

10.并发修改异常(扩展)

迭代的常规用法中我们要尽量避免在迭代过程中为集合添加/删除数据。否则会报错,原因是Java抛出了并发修改异常。

迭代过程中并发修改异常的原因为迭代器中”记忆”的集合长度与集合中实际长度不同,而导致出现索引与实际元素不符甚至无限循环的情况发生。

所以在使用Iterator时,避免类似操作,for循环底层为迭代器实现,所以也需要避免类似操作。

有些迭代器避免了这样的问题,如ListIterator,但该类并不通用也不常用,实际开发中很少使用,只需要简单了解。

java中提供了很多个集合,它们在存储元素时,采用的存储方式不同。我们要取出这些集合中的元素,可通过一种通用的获取方式来完成。

importjava.util.ArrayList;

importjava.util.Collection;

importjava.util.Iterator;

importjava.util.List;

importjava.util.ListIterator;

/*

*  并发修改异常:当你 遍历集合并操作集合,添加或者移除元素的使用,可能会报出并发修改异常.

*  处理方式:添加,移除 ,使用迭代器的方法. 迭代器中的remove. 

*  查看异常信息: 第一行是 异常的说明 _空指针 ,角标越界, 并发..... 

*      详细异常信息, 从下往上看, 能看懂哪行就是你发生异常的地方,基本上就是你写错代码.

*      Iterator.next()继续迭代的时候报错, 那么我们提供一种解决方案, 可以修改,但是不再遍历集合.

*  解决方案: 

*  1.采用 Iterator中的方法 去操作集合  -- 推荐 !

*  2.使用非Iterator中的方法操作, 那么再操作之后 ,加 break; 

*/

public class Demo {

public static void main(String[] args) {

Collection<String> c = new ArrayList<>();

c.add("aaa");

c.add("bbb");

c.add("ccc");

c.add("ddd");

System.out.println(c);

Iterator<String> iterator = c.iterator();

while (iterator.hasNext()) {

String string=  iterator.next();

// 如果存在bbb ,那么添加一个EEE

if (string.equals("bbb")) {

c.add("bbb");

break;

}

}

System.out.println(c);                                          //java.util.ConcurrentModificationException  并发修改异常

List l  = new ArrayList<>();

ListIteratorlistIterator = l.listIterator();

}

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容