java迭代器和for循环区别_迭代器和增强for循环
Iterator迭代器的使用:
迭代:Iterator,即collection集合元素的通用获取方式
java.util.Iterator接口。迭代器(对集合进行遍历)
有两个常用的方法
Boolean hasNext()如果仍有元素可以迭代,则返回true
判断集合中还有没有下一个元素,有就返回true,没有就返回false
E next()返回迭代的下一个元素
取出集合中的下一个元素
Iterator迭代器,是一个接口,我们无法直接使用,需要Iterator接口的实现类对象,获取实现类的方式比较特殊
Collection接口中有一个方法,叫Iterator(),这个方法返回的就是迭代器的实现类对象
Iterator iterator()返回在此collection的元素上进行迭代的迭代器
迭代器的使用步骤(重点)
1、使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收(多态)
2、使用Iterator接口中的方法hasNext判断还有没有下一个元素
3、使用Iterator接口中的方法next取出集合中的下一个元素
package Iterator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class Demo01Collection {
public static void main(String[] args) {
//创建一个集合对象
Collection coll=new ArrayList<>();
coll.add("星星");
coll.add("仰望星空");
coll.add("最美的太阳");
coll.add("这就是爱");
//1、使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收(多态)
//Iterator的接口也是有泛型的,迭代器的泛型跟着集合走,集合是什么泛型,迭代器就是什么泛型
//多态 接口 实现类对象
Iterator it=coll.iterator();
//发现使用迭代器取出集合中元素的代码是一个重复的过程
//所以我们可以使用循环优化
//不知道集合中有多少元素,使用while集合
//循环结束的条件,hasNext方法返回false
while (it.hasNext()){
String e=it.next();
System.out.println(e);
}
// //2、使用Iterator接口中的方法hasNext判断还有没有下一个元素
// boolean b=it.hasNext();
// System.out.println(b);//true
//
// // 3、使用Iterator接口中的方法next取出集合中的下一个元素
// String s=it.next();
// System.out.println(s);
//
// //2、使用Iterator接口中的方法hasNext判断还有没有下一个元素
// b=it.hasNext();
// System.out.println(b);//true
// // 3、使用Iterator接口中的方法next取出集合中的下一个元素
// s=it.next();
// System.out.println(s);
// 2、使用Iterator接口中的方法hasNext判断还有没有下一个元素
// b=it.hasNext();
// System.out.println(b);//true
// // 3、使用Iterator接口中的方法next取出集合中的下一个元素
// s=it.next();
// System.out.println(s);
// 2、使用Iterator接口中的方法hasNext判断还有没有下一个元素
// b=it.hasNext();
// System.out.println(b);//true
// // 3、使用Iterator接口中的方法next取出集合中的下一个元素
// s=it.next();
// System.out.println(s);
//
// b=it.hasNext();
System.out.println(b);没有元素,返回false
// 3、使用Iterator接口中的方法next取出集合中的下一个元素
s=it.next();没有元素,在取出元素会抛出NoSuchElementException没有元素异常
System.out.println(s);
}
}
Iterator(迭代器)实现原理
这里我们来看看Java里AbstractList实现Iterator的源代码:
public abstract class AbstractList extends AbstractCollection implements List { // List接口实现了Collection, Iterable
protected AbstractList() {
}
public Iterator iterator() {
return new Itr(); // 这里返回一个迭代器 }
private class Itr implements Iterator { // 内部类Itr实现迭代器
int cursor = 0;
int lastRet = -1;
int expectedModCount = modCount;
public boolean hasNext() { // 实现hasNext方法
return cursor != size();
}
public E next() { // 实现next方法
checkForComodification();
try {
E next = get(cursor);
lastRet = cursor++;
return next;
} catch (IndexOutOfBoundsException e) {
checkForComodification();
throw new NoSuchElementException();
}
}
public void remove() { // 实现remove方法
if (lastRet == -1)
throw new IllegalStateException();
checkForComodification();
try {
AbstractList.this.remove(lastRet);
if (lastRet < cursor)
cursor--;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException e) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
}
可以看到,实现next()是通过get(cursor),然后cursor++,通过这样实现遍历。
这部分代码不难看懂,唯一难懂的是remove操作里涉及到的expectedModCount = modCount;
在网上查到说这是集合迭代中的一种“快速失败”机制,这种机制提供迭代过程中集合的安全性。
从源代码里可以看到增删操作都会使modCount++,通过和expectedModCount的对比,迭代器可以快速的知道迭代过程中是否存在list.add()类似的操作,存在的话快速失败!
在第一个例子基础上添加一条语句:
import java.util.*;
public class Muster {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
Iterator it = list.iterator();
while(it.hasNext()){
String str = (String) it.next();
System.out.println(str);
list.add("s"); //添加一个add方法
}
}
}
运行结果:
a
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at com.hasse.Muster.main(Muster.java:11)
这就会抛出一个下面的异常,迭代终止。
增强for循环
增强for循环的作用: 简化迭代器的书写格式。(注意:增强for循环的底层还是使用了迭代器遍历。)
增强for循环的适用范围: 如果是实现了Iterable接口的对象或者是数组对象都可以使用增强for循环。
增强for循环的缺点:增强for循环和iterator遍历的效果是一样的,也就说增强for循环的内部也就是调用iteratoer实现的,但是增强for循环有些缺点,例如不能在增强循环里动态的删除集合内容、不能获取下标等。
增强for循环的格式:
for(数据类型 变量名 :遍历的目标){
//数据类型 变量名:声明一个变量用来接收遍历目标遍历后的元素
}
增强for循环要注意的事项:
增强for循环底层也是使用了迭代器获取的,只不过获取迭代器由jvm完成,不需要我们获取迭代器而已,所以在使用增强for循环变量元素的过程中不准使用集合对象对集合的元素个数进行修改。
迭代器遍历元素与增强for循环变量元素的区别:使用迭代器遍历集合的元素时可以删除集合的元素,而增强for循环变量集合的元素时,不能调用迭代器的remove方法删 除 元素。
普通for循环与增强for循环的区别:普通for循环可以没有遍历的目标,而增强for循环一定要有遍历的目标。
int[] arr = {5,11,2,4,9,18};
普通for循环的遍历方式
for(int i = 0 ; i
System.out.println("元素:"+ arr[i]);
}
//使用增强for循环实现
for(int item :arr){
System.out.println("元素:"+ item);
}
HashSet set = new HashSet();
//添加元素
set.add("张狗蛋");
set.add("张全蛋");
set.add("张傻蛋");
//使用迭代器遍历Set的集合.
Iterator it = set.iterator();
while(it.hasNext()){
String temp = it.next();
System.out.println("元素:"+ temp);
it.remove();
}
//使用增强for循环解决
for(String item : set){
System.out.println("元素:"+ item);
}
注意: Map集合没有实现Iterable接口,所以map集合不能直接使用增强for循环,如果需要使用增强for循环需要借助于Collection的集合。
HashMap map = new HashMap();
map.put("01","甲");
map.put("02","乙");
map.put("03","丙");
map.put("04","丁");
Set> entrys = map.entrySet();
for(Map.Entry entry :entrys){
System.out.println("键:"+ entry.getKey()+" 值:"+ entry.getValue());
}
java迭代器和for循环区别_迭代器和增强for循环相关推荐
- java 循环依赖_浅谈Spring解决循环依赖的三种方式
引言:循环依赖就是N个类中循环嵌套引用,如果在日常开发中我们用new 对象的方式发生这种循环依赖的话程序会在运行时一直循环调用,直至内存溢出报错.下面说一下Spring是如果解决循环依赖的. 第一种: ...
- python的for循环语句_干货丨Python的循环语句基础讲解!
我们知道计算机程序语言一般是按照顺序执行的,那么编程语言就提供了各种控制结构,允许更复杂的执行路径,其中循环语句的作用就是允许我们执行一个语句或语句组多次. 在Python中循环语句的类型主要有以下几 ...
- for循环优化_昨天还在for循环里写加号拼接字符串的那个同事,今天已经不在了
引言 都说 StringBuilder 在处理字符串拼接上效率要强于 String,但有时候我们的理解可能会存在一定的偏差.最近我在测试数据导入效率的时候就发现我以前对 StringBuilder 的 ...
- python 引用计数 循环引用_引用计数无法解决循环引用,CPython为何还使用它?
取消excel表中的循环引用的步2113骤如下:1.打开一个5261Excel文件.打开之后,4102在操作表中的单元格时,1653出现了循环引用警告.2.点击左上角的 文件 菜单,在出现的菜单中点击 ...
- python迭代器和for循环区别_java迭代器和for循环优劣
在进行迭代的时候,程序运行的效率也是我们挑选迭代方法的重要原因.目前有三种迭代方法:for循环.迭代器和Foreach.前两者相信大家都非常熟悉,为了更加直观分析效率的不同,我们还加入Foreach一 ...
- python迭代器和for循环区别_python迭代器和for循环区别,
详细内容 迭代器(iterator):迭代器对象必须同时实现__iter__和__next__方法才是迭代器.对于迭代器来说,__iter__ 返回的是它自身 self,__next__ 则是返回迭代 ...
- python迭代器和for循环区别_python迭代器和for循环区别
迭代器(iterator):迭代器对象必须同时实现__iter__和__next__方法才是迭代器.对于迭代器来说,__iter__ 返回的是它自身 self,__next__ 则是返回迭代器中的下一 ...
- java 协程线程的区别_为什么 Java 坚持多线程不选择协程?
谢邀. 先说结论:协程是非常值得学习的概念,它是多任务编程的未来.但是Java全力推进这个事情的动力并不大. 先返回到问题的本源.当我们希望引入协程,我们想解决什么问题.我想不外乎下面几点:节省资源, ...
- java和c语言的区别_单片机为什么一直用C语言,不用其他编程语言?只有学过的知道...
单片机为什么还在用C语言编程?答案是:C语言是最适合单片机编程的高级语言. 这个问题的意思应该是:现在有很多很好用的高级语言,如java,python,VC等等,为什么这些语言不能用来编写单片机程序呢 ...
最新文章
- 再学 GDI+[33]: TGPPen - 画笔的几何变换 - SetTransform
- python基础学习笔记(八)
- python--常用模块:collections 、time、random
- mysql查询条件字段值末尾有空格的问题
- 高中计算机基础知识,高中计算机会考基本知识点
- 特征提取(Feature Detection)之——HOG (Histogram of Oriented Gradient)特征
- 漫画:什么是 “元宇宙” ?
- php msgid排重,如何应用php数组对百万数据停止排重
- MySQL操作之JSON数据类型操作详解
- mysql 开启远程访问_QxOrm 访问 MySQL
- DataGrid + JS 的應用示例
- 我开始学习golang编程语言-1
- uc云观媒体服务平台_自媒体平台UC云观开放收益功能,自媒体作者有收入了
- python绘图——绘制正负区分的柱形图[ax.bar()]
- cos三次方积分_cos三次方的定积分
- 塔望 用食品改变世界
- pytorch中张量的阶数理解
- sourceTree 完全卸载
- 深入浅出地理解STM32中的中断系统——从原理到简单工程示例——保姆级教程
- python3 中文手册
热门文章
- C# 获取当月第一天 或者当月最后一天
- 令克软件与纳斯达克交易所达成战略合作,携手助力金融IT发展
- SpringBoot+支付宝:实现沙箱支付全过程
- [vido]羽飞老师RHCE认证视频汇总贴(09月20日更新中……)
- MK趋势检验+Kendalls taub等级相关+稳健回归(Sens slope estimator等)
- Error: The apk for your currently selected variant (app-release.apk) is not signed
- 探索HyperLogLog算法(含Java实现)
- tailwindcss 一览表
- 2022前端面试题附答案.
- antd自定义form表单控件