迭代器-foreach&Iterator的联系与区别

在程序开发中,经常需要遍历集合中的所有元素。针对这种需求,JDK专门提供了一个接口java.util.IteratorIterator接口也是Java集合中的一员,但它与CollectionMap接口有所不同,Collection接口与Map接口主要用于存储元素,而Iterator主要用于迭代访问(即遍历)Collection中的元素,因此**Iterator对象也被称为迭代器。

1.JavaSE阶段,我们接触过哪些循环?

在此之前,我们学习到for循环、while循环、do…while循环,在需要重复执行某些的代码时,循环才会使用。

2.foreach是什么?

foreach是增强版的for循环,这种循环方式是在JDK1.5引入进来的。

语法格式:

for(集合的元素类型 集合的元素名 : 集合名称){

}

for(数组的元素类型 数组的元素名 : 数组名称){

}

说明:集合、数组的元素名都是自定义的名字。

3.foreach相比for有哪些优势?

①foreach循环代码更加的简洁;

②foreach没有下标信息;

③foreach不能用于修改元素(基本数据类型),可以修改元素的属性(引用数据类型)。

代码演示01:

package com.daxia.case3;

import org.junit.Test;

/*数组--foreach循环应用 */

public class ForeachTest {
	@Test
	public void test01() {
		int[] array = { 1, 2, 3, 4, 5, 6 };
		for (int num : array) {
			System.out.print(num+" ");  //打印结果: 1 2 3 4 5 6 
		}
	}
}
代码演示02:
/*集合--foreach循环应用 */
public class ForeachTest {
	@Test
	public void test02() {
		Collection<String> col = new ArrayList();
		col.add("林大侠");
		col.add("猪猪侠");
		col.add("牛牛侠");
		col.add("哈哈侠");
		for (String num2 : col) {
			System.out.print(num2+" ");//打印结果: 林大侠 猪猪侠 牛牛侠 哈哈侠 

		}
	}
}

代码演示03:

import org.junit.Test;
/*数组--foreach循环应用 */
public class ForeachTest {
	@Test
	public void test03() {
		int[] array = { 1, 2, 3, 4, 5, 6 };
		// 遍历数组中元素3的下标
		for (int num : array) {
			if(num == 3){
				System.out.print("找到元素3的下标了(验证foreach没有下标信息)");	
			}	
		}
	}
}

代码演示04:

import org.junit.Test;
/*数组--foreach循环应用 */
public class ForeachTest {
	@Test
	public void test04() {
		int[] array = { 1, 2, 3, 4, 5, 6 };
		// 遍历数组元素,修改3的值
		for (int num : array) {
			if (num == 3) {
				num = 8;//无法修改,可以看做对于基本数据类型,形参不能修改实参的值
				System.out.print("foreach不能用于修改元素!");
			}	
		}
		System.out.println(Arrays.toString(array));//foreach不能用于修改元素![1, 2, 3, 4, 5, 6]--还是原值
	}
}

代码演示05:

package com.daxia.case3;

import java.util.ArrayList;
import java.util.Collection;
import org.junit.Test;
/*集合--foreach循环应用 */
public class ForeachTest {
	@Test
	public void test05() {
		Collection<Student> col = new ArrayList();
		col.add(new Student("林大侠"));
		col.add(new Student("猪猪侠"));
		col.add(new Student("牛牛侠"));
		col.add(new Student("哈哈侠"));
		for (Student stu : col) {
			if ("林大侠".equals(stu.getName())) {
				stu.setName("熊猫侠");
				;// 对于引用数据类型,可以修改
			}
		}
		System.out.println(col);
//[Student [name=熊猫侠], Student [name=猪猪侠],Student [name=牛牛侠], Student [name=哈哈侠]]
							
	}
}

class Student {
	private String name;

	public Student() {
		super();
	}

	public Student(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + "]";
	}

}
4.foreach与Iterator存在哪些关系?

(1)java.lang.Iterable:可迭代的接口 Iterator iterator() —构造方法
java.util.Iterator:迭代器接口

(2) Collection:接口

Collection继承了Iterable接口,所以Collection系列的集合有Iterator iterator() 方法。
实现了Iterarable接口的类型,就允许对象成为 “foreach” 语句的目标。

(3)foreach底层也是使用Iterator迭代器进行迭代的。

▲同理,Iterator迭代时,要删除元素的话使用,Iterator自己的remove方法(用自己的,丰衣足食)
▲同理,foreach迭代时,也不能调用Collection的remove(xx)方法。

✘切记:在用Iterator迭代和foreach迭代时都不要使用Collection的remove,add等会修改Collection的元素个数的操作。否则要么会报错,要么会有意外。

5.Iterator常用的方法?

迭代器:用于遍历集合中的元素,java.util.Iterator:接口
①boolean hasNext() :是否有下一个元素
②E next() :取出下一个
③void remove() :删除刚刚遍历的元素(方法是默认的

★Iterator迭代器的对象,不是我们程序员手动创建的,而且在用它遍历集合时,通过调用集合的iterator()得到它的对象。

Collection系列的集合都有一个方法: Iterator iterator()

6.Collection的remove(obj)和Iterator迭代器的remove()的区别?

①Collection的remove(obj):直接删除对象,无需遍历,代码更简洁,缺点是无法根据条件删除
①Iterator迭代器的remove():遍历的同时删除,代码复杂,优点是可以根据条件删除

代码演示06:

public class IteratorTest01 {
	public static void main(String[] args) {
		Collection<String> col = new ArrayList();
		col.add("林大侠");
		col.add("猪猪侠");
		col.add("牛牛侠");
		col.add("哈哈哈侠");
		// 【知识点一】Collection缺点是无法根据条件删除
		// 删除集合中四个字的名字
		// col.remove(o);无法完成功能

		Iterator<String> iterator = col.iterator();
		while (iterator.hasNext()) {
			String element = iterator.next();
			if (element.length() == 3) {
				//col.remove(element);
				iterator.remove();//成功删除
			}
		}
		System.out.println(col);//[林大侠, 猪猪侠, 牛牛侠]
	}
}

注意:不用在Iterator迭代器迭代过程中,调用Collection的remove(obj)方法,要么会报错(并发修改的错误),要么行为不确定。

在这里插入图片描述

7.modCount变量的作用?

✔modCount变量的作用:保证用Iterator迭代器遍历集合的过程中,集合的数据是稳定。(保证并发操作时,快速失败的检查机制

▲ 在ArrayList等集合中有一个变量modCount,它用来记录集合的结构被修改的次数。
当我们给集合添加和删除操作时,会导致modCount++。
▲ 在用Iterator迭代器遍历集合时,创建集合迭代器的对象时,用一个变量记录当前集合的modCount int expectedModCount = modCount;并且在迭代器每次next()迭代元素时,都要检查 expectedModCount != modCount, 如果不相等了,那么说明你调用了Iterator迭代器以外的Collection的add,remove等方法,修改了集合的结构,使得modCount++,值变了, 就会抛出ConcurrentModificationException。

总之,我们不能在本线程或其他线程再调用Collection的add,remove等方法来修改集合。 要保证遍历数据的稳定性。

#轻松一刻

在这里插入图片描述


☝上述分享来源个人总结,如果分享对您有帮忙,希望您积极转载;如果您有不同的见解,希望您积极留言,让我们一起探讨,您的鼓励将是我前进道路上一份助力,非常感谢!我会不定时更新相关技术动态,同时我也会不断完善自己,提升技术,希望与君同成长同进步!

☞本人博客:https://coding0110lin.blog.csdn.net/  欢迎转载,一起技术交流吧!

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值