本篇是我对于foreach语句(增强for)的总结:

我的总结流程如下:

1.先整体说明增强for遍历集合与数组之间的区别。

2.通过一维数组来说明(给出反编译的源码,形成对照)。

3.通过二维数组来说明(给出反编译的源码,形成对照)。

4.通过三维数组来说明(给出反编译的源码,形成对照)。

5.通过集合来说明(给出反编译的源码,形成对照)。

6.反编译的介绍以及网站分享。

7.结束。

一.增强for遍历集合与数组之间的区别

其实之前在我还没有学习到迭代器之前我已经总结过这个知识点了,但是在我了解过迭代器之后,我决定将之删掉重写.问过很多人,都说foreach语句无非就是一直在使用迭代器,可是在我真正测试了之后,才发现,并不像大多数人想的那样。

因为我了解到了迭代器的使用只能是在集合中(下面是API文档中的一些解释):

并且对之有所了解的都应该知道,迭代器只是一个接口,他的使用是要通过其实现类来完成的,而只有Collection集合或者其子类才能通过调用iterator方法返回一个实现类对象。

所以说,只有集合是通过迭代器来遍历的,但是数组就不是了,因为数组与集合并不是同一个概念。

再来说说数组与集合的不同之处吧:

1.集合的长度可变,而数组的长度是不可变的。

2.集合可以存储对象与基本类型数据,但是数组只能存储基本类型数据。

二.通过一维数组来说明

普通代码:

public class Demo9 {
public static void main(String[] args) {
int[] a= {1,2,3,4,4,5};
for(int i:a) {
System.out.println(i);
}
}
}

反编译后的代码:

public class Demo10 {

   public static void main(String[] args) {
int[] a = new int[]{1, 2, 3, 4, 4, 5}; //按照计算机的创建数组的标准格式创建一个数组
int[] var5 = a; //相当于复制a数组
int var4 = a.length; //记录a数组的长度
for(int var3 = 0; var3 < var4; ++var3) {
int i = var5[var3]; //将a数组元素逐个赋值给i
System.out.println(i);
} }
}

通过反编译代码,很明显可以看到,对于数组使用增强for与迭代器是没有任何关系的(这篇就翻过啦,哈哈),我把解释全部写在反编译的代码中了。

三.通过二维数组来说明(这将是我说明的重点)

普通代码:

public class Demo6 {
public static void main(String[] args) {
int[][] a= {{1,2,3},{2,5,3}};
for(int i[]:a) { //此处用了两次foreach语句,具体原因我们通过反编译代码说明
for(int e:i) {
System.out.println(e);
}
}
System.out.println(a.length);
}
}

反编译代码:

public class Demo5 {

 public static void main(String[] args) {
int[][] a = new int[][]{{1, 2, 3}, {2, 5, 3}}; //这里仍是一个标准的二维数组创建格式
int[][] var5 = a; //又复制了一遍数组
int var4 = a.length; //把a的长度2给了var4
for(int var3 = 0; var3 < var4; ++var3) { //这个循环进行两次
int[] i =var5[var3]; //此处是我理解的一个困难之处,但是我已克服,会在下面说出我的见解
int[] var9 = i; //又复制了一次数组
int var8 = i.length; //给长度
for(int var7 = 0; var7 < var8; ++var7)
{
int e = var9[var7]; //这里就和一维数组完全一样了
System.out.println(e);
} } }
}

我会通过语言描述,将我所理解到的,二维数组的foreach遍历中的我之前不理解但现在已解决的地方说出来:

             int[] i =var5[var3];
int[] var9 = i;
i.length=3;
i数组输出出来是二维数组中的一维数组(就是每一个大括号中的内容)

此处最初令我十分不解。因为我大一上学期是学c语言的,在我的脑海中数组这些知识都应该是通用的,但是我却没见过这种方式,在我最初的理解中,我之所以遇到困难,是因为我一直纠结于将一个地址直接给一个数组是不合适的,但是我后来又试了一下,发现如果我们将代码写成这样就很好理解了。

             int[] i =new int[5];
i=var5[var3];

因为我想通过这样的方式来帮助我理解的话,我事先必须先定义一个数组,出于尝试的态度,我将它的初始长度设为5,但上文代码中,我们知道最后i的长度是3,最先我以为这里的i是被覆盖了,后来才发现并不是这样,因为var5[var3]是二位数组的行的首地址,所以只是改变了i的指向,他所指向的变成了a数组的每一行的行首,所以他就相当于,通过遍历,不断地复制二维数组每一行的元素。

当然有人会问了,你怎么去确定,他的长度为啥就一定是与二维数组第一行长度一样?

其实,我们会发现在二维数组中,每一行的首地址都是不一样的,我所谓的不一样是没有规律的,就是他们并不是整个二维数组连在一起的,而是以行为单位的连在一起的。

四.通过三维数组说明问题

普通代码:

public class Demo10 {
public static void main(String[] args) {
int[][][] a= {{{1,2,3},{2,3}},{{2,3},{2,6}},{{3,4},{5,6}}};
for(int[][] b:a) {
for(int[] c:b) {
for(int d:c) {
System.out.println(d);
}
}
}
} }

此处我决定只是通过普通代码的方式来说明问题,因为计算机总是会自己创造出一些变量,对于三维数组来说,这些变量就更多了(看看二维数组,唉。。),这样只会是我们的理解更加的不具体,不直观。

其实我们不难发现,无论多高维度的数组,将其输出的格式都是一样的,最终的输出语句一定是在一维数组中的。

五.通过集合说明

普通代码:

import java.util.ArrayList;
import java.util.Collection; public class Demo8 {
public static void main(String[] args) {
Collection cc=new ArrayList();
cc.add("哈哈");
cc.add("嘻嘻");
cc.add("哼哼");
cc.add(1);
for(Object s:cc) {
System.out.println(s);
}
}
}

反编译代码:

import java.util.ArrayList;
import java.util.Iterator; public class Demo8 { public static void main(String[] args) {
ArrayList cc = new ArrayList();
cc.add("鍝堝搱"); //这里的字符串应该只是机器码的缘故,我并没有深究
cc.add("鍢诲樆");
cc.add("鍝煎摷");
cc.add(Integer.valueOf(1));
Iterator var3 = cc.iterator(); while(var3.hasNext()) {
Object s = var3.next();
System.out.println(s);
} }
}

很明显这次我们发现,用增强for遍历集合反编译的格式完全不一样了,并且还用到了迭代器,并且我并没有使用泛型,即没有给出数据类型,这样也更好理解一些。

对于其中的一些关于集合的知识,比如说迭代器的相关方法呀,之类的我就不在本篇说啦,对于集合我还是会总结的。

六.反编译的使用

何为反编译,我的理解就是将那些隐藏句式的全部代码显现出来,对于foreach语句的理解若是没有反编译我是绝对不可能做出来的,最初的时候,我试着用javap进行反汇编但是我发现里面的东西并不是我想看到的,所以我花了一个小时,去找那种我想要的反编译软件,最后发现不是安装太麻烦,就是不适合我。。。。。。。。。

好在偶然发现了一个网站,很好使,完全就是用来进行我所需要的那种反编译的,所以如果看我的文章还是不太理解的话,可以在评论区与我进行讨论,或者通过这个网站形成你自己的理解,网址在这了(http://javare.cn/)。

七.结束

其实之前,我已经总结过该知识点了,并且看的人还挺多的,那时我也是初学,没有思考的太过深入,所以就按照自己所想总结了一下,但是昨天翻看的时候发现总结的那叫一个惨不忍睹,一点逻辑性都没有,这样其实对于那些耐着性子,看我这个菜鸟的博客的人挺不好的,所以我就删掉决定重写,我并不能保证该篇中就没有一点问题,但是这绝对是我深思熟虑的结果。还是老样子,加油,慢慢变强吧。

浅析foreach语句的更多相关文章

  1. Java Iterator, ListIterator 和 foreach语句使用

    Java Iterator, ListIterator 和 foreach语句使用 foreach语句结构: for(part1:part2){part3};  part2 中是一个数组对象,或者是带 ...

  2. 【Java学习笔记】foreach语句(高级for)

    package p2; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java ...

  3. foreach语句

    foreach语句他无非就是for循环的封装,为了提高开发速度才创造出来的.他其实跟for循环一样,只不过写起来比较简便,他是1.5版本才出来的一种封装语法.并没有什么奇特之处他里面的机制就是for循 ...

  4. Java中的可变参数以及foreach语句

    Java中的可变参数的定义格式如下: 返回值类型  方法名称(类型 ... 参数名称){} foreach语句的格式如下: for ( 数据类型  变量名称 :数据名称){ ... } public ...

  5. 可迭代的集合类型使用foreach语句

    在学习算法这本书图论那一部分的时候,接触到了几个类似for(int w:G.adj(v)),的语句,不是很理解,就去百度,发现这是一种叫做foreach的语法,在书的76页有讲到,但是之前没认真看书, ...

  6. 自定义一个可以使用foreach语句进行迭代的类(IEnumerable)

    在c#中,凡是实现了IEnumerable接口的数据类型都可以用foreach语句进行迭代访问.所以,我们要定义一个可以使用foreach进行迭代访问的类,就必须要实现IEnumerable接口. / ...

  7. C#中foreach语句的迭代器实现机制

    C#中的foreach语句可用于循环遍历某个集合中的元素,而所有的只要支持了IEnumerable或IEnumerable<T>泛型接口的类型都是可以 用foreach遍历的.其具体的遍历 ...

  8. C#中的foreach语句与枚举器接口(IEnumerator)及其泛型 相关问题

    这个问题从<C#高级编程>数组一节中的foreach语句(6.7.2)发现的. 因为示例代码与之前的章节连贯,所以我修改了一下,把自定义类型改为了int int[] bs = { 2, 3 ...

  9. 从foreach语句枚举元素看数组

    在foreach语句中使用枚举,可以迭代数组或集合中的元素,且无须知道集合中的元素的个数.如图显示了调用foreach方法的客户端和集合之间的关系.数组或集合实现带GetEnumerator()方法的 ...

随机推荐

  1. C#版 - HDUoj 5391 - Zball in Tina Town(素数) - 题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. HDUoj 5 ...

  2. 从锅炉工到AI专家(5)

    图像识别基本原理 从上一篇开始,我们终于进入到了TensorFlow机器学习的世界.采用第一个分类算法进行手写数字识别得到了一个91%左右的识别率结果,进展可喜,但成绩尚不能令人满意. 结果不满意的原 ...

  3. 如何比较版本号--Python实现

    需求 在写一个程序Django项目的setup程序(初始化环境,比如设置PIP源,安装该项目依赖的各种模块等操作)遇到一个系统当前模块版本和项目所需版本的比较然后给出建议是忽略还是升级.我的要求是不仅 ...

  4. Asp.Net SignalR GlobalHost外部通知

    GlobalHost 外部通知 之前都是在集线器类中进行服务器对客户端的通知操作,但是在开发中往往会有需求监控某个系统 ,比如OA系统  上级领导在上面宣布下午两点要开会 那么就要通知到其他的人.这里 ...

  5. Flink生成Parquet格式文件实战

    1.概述 在流数据应用场景中,往往会通过Flink消费Kafka中的数据,然后将这些数据进行结构化到HDFS上,再通过Hive加载这些文件供后续业务分析.今天笔者为大家分析如何使用Flink消费Kaf ...

  6. PE知识复习之PE的RVA与FOA的转换

    PE知识复习之PE的RVA与FOA的转换 一丶简介PE的两种状态 首先我们知道PE有两种状态.一种是内存展开.一种是在文件中的状态.那么此时我们有一个需求. 我们想改变一个全局变量的初始值.此时应该怎 ...

  7. EF Core新增迁移时无法加载程序集“System.ValueTuple”的错误

    EF Core使用迁移命令时,如: Add-Migration Init 有时会出现如下错误: System.IO.FileLoadException: Could not load file or ...

  8. .Net语言 APP开发平台——Smobiler学习日志:SmoOne新增考勤功能

    大家好!SmoOne这次新增了考勤功能,大家打开SmoOne应用便可体验,无需重新下载更新.如果没有下载SmoOne客户端,可以在apps.smobiler.com进行下载安装. 另外,SmoOne开 ...

  9. [Linux] awk基础编程

    1.awk每次读一行数据,如果设置了-F选项,是在这一行使用分隔符分,$0是全部 2.awk由模式和动作组成 3.条件判断模式{动作} a.txt aaa bbb aaa ccc ddd cat a. ...

  10. 17 , CSS 区块、浮动、定位、溢出、滚动条

    1.CSS 中区块的使用 2.CSS 中浮动的使用 3.CSS 中定位的使用 4.CSS 中溢出的使用 5.CSS 中滚动条的使用 17.1 CSS 中区块的使用 属性名称 属性值 说明 width ...