1.控制循环结构

Java语言没有提供 goto语句来控制程序的跳转,这种做法提高了程序流程控制的可读性,但降低了程序流程控制的灵活性。为了弥补这种不足,Java提供了continue和 break 来控制循环结构。除此之外,return可以结束整个方法,当然也就结束了一次循环。

使用break结束循环

break语句不仅可以结束其所在的循环,还可以直接结束其外层循环。此时需要在 break后紧跟一个标签,这个标签用于标识一个外层循环。

Java中的标签就是一个紧跟着英文冒号(:)的标识符。与其他语言不同的是,Java 中的标签只有放在循环语句之前才有作用。例如下面代码。

程序从外层循环进入内层循环后,当j等于1时,程序遇到一个 break outer;语句,这行代码将会导致结束outer标签指定的循环,不是结束break所在的循环,而是结束break循环的外层循环。所以看到上面的运行结果。
        值得指出的是,break后的标签必须是一个有效的标签,即这个标签必须在 break语句所在的循环之前定义,或者在其所在循环的外层循环之前定义。当然,如果把这个标签放在 break语句所在的循环之前定义,也就失去了标签的意义,因为break 默认就是结束其所在的循环。

使用continue忽略本次循环剩下语句

与break类似的是,continue后也可以紧跟一个标签,用于直接跳过标签所标识循环的当次循环的剩下语句,重新开始下一次循环。例如下面代码。

运行上面程序可以看到,循环变量j的值将无法超过1,因为每当j等于1时,continue outer;语句就结束了外层循环的当次循环,直接开始下一次循环,内层循环没有机会执行完成
        与break 类似的是,continue后的标签也必须是一个有效标签,即这个标签通常应该放在continue所在循环的外层循环之前定义。

使用return结束方法

return关键字并不是专门用于结束循环的,return的功能是结束一个方法。当一个方法执行到一个return 语句时(return关键字后还可以跟变量、常量和表达式,这将在方法介绍中有更详细的解释),这个方法将被结束。

2.数组类型

定义数组:

Java 语言支持两种语法格式来定义数组:

对这两种语法格式而言,通常推荐使用第一种格式。因为第一种格式不仅具有更好的语意,而且具有更好的可读性。对于type[] arrayName;方式,很容易理解这是定义一个变量,其中变量名是 arrayName,而变量类型是type[]。前面已经指出: type[]确实是一种新类型,与 type类型完全不同(例如 int类型是基本类型,但int[]是引用类型)。因此,这种方式既容易理解,也符合定义变量的语法。但第二种格式type arrayName[]的可读性就差了,看起来好像定义了一个类型为type的变量,而变量名是arrayName[],这与真实的含义相去甚远。
        可能有些读者非常喜欢 type arrayName[];这种定义数组的方式,这可能是因为早期某些计算机读物的误导,从现在开始就不要再使用这种糟糕的方式了

注意:

数组是一种引用类型的变量,因此使用它定义一个变量时,仅仅表示定义了一个引用变量(也就是定义了一个指针),这个引用变量还未指向任何有效的内存,因此定义数组时不能指定数组的长度。而且由于定义数组只是定义了一个引用变量,并未指向任何有效的内存空间,所以还没有内存空间来存储数组元素,因此这个数组也不能使用,只有对数组进行初始化后才可以使用。

数组初始化

数组的初始化有如下两种方式。

  • 静态初始化:初始化时由程序员显式指定每个数组元素的初始值,由系统决定数组长度。
  • 动态初始化:初始化时程序员只指定数组长度,由系统为数组元素分配初始值。

静态初始化

因为Java语言是面向对象的编程语言,能很好地支持子类和父类的继承关系:子类实例是一种特殊的父类实例。在上面程序中,String类型是Object类型的子类,即字符串是一种特殊的Object实例。关于继承更详细的介绍,请参考本书第5章。

动态初始化:

使用数组:

如果访问数组元素时指定的索引值小于0,或者大于等于数组的长度,编译程序不会出现任何错误,但运行时出现异常: java.lang.ArrayIndexOutOfBoundsException: N (数组索引越界异常),异常信息后的N就是程序员试图访问的数组索引。

所有的数组都提供了一个length属性,通过这个属性可以访问到数组的长度,一旦获得了数组的长度,就可以通过循环来遍历该数组的每个数组元素。下面代码示范了输出prices数组(动态初始化的int[]数组)的每个数组元素的值(程序清单同上)。

3.foreach循环

从Java 5之后,Java 提供了一种更简单的循环: foreach 循环,这种循环遍历数组和集合(关于集合的介绍请参考本书第8章)更加简洁。使用foreach循环遍历数组和集合元素时,无须获得数组和集合长度,无须根据索引来访问数组元素和集合元素,foreach 循环自动遍历数组和集合的每个元素。

从上面程序可以看出,使用foreach循环遍历数组元素时无须获得数组长度,也无须根据索引来访问数组元素。foreach 循环和普通循环不同的是,它无须循环条件,无须循环迭代语句,这些部分都由系统来完成,foreach 循环自动迭代数组的每个元素,当每个元素都被迭代一次后, foreach 循环自动结束。

4.深入数组

数组是一种引用数据类型,数组引用变量只是一个引用,数组元素数组变量在内存里是分开存放的。下面将深入介绍数组在内存中的运行机制。

内存中的数组

实际的数组对象被存储在堆(heap)内存中;如果引用该数组对象的数组引用变量是一个局部变量,那么它被存储在栈(stack) 内存中。数组在内存中的存储示意图如图4.2所示。

如果需要访问如图4.2所示堆内存中的数组元素,则程序中只能通过p[index]的形式实现。也就是说,数组引用变量是访问堆内存中数组元素的根本方式

只要类型相互兼容,就可以让一个数组变量指向另一个实际的数组,这种操作会让人产生数组的长度可变的错觉。如下代码所示。

运行上面代码后,将可以看到先输出b数组的长度为4,然后依次输出a数组和b数组的每个数组元素,接着会输出b数组的长度为3看起来似乎数组的长度是可变的,但这只是一个假象。必须牢记:

定义并初始化一个数组后,在内存中分配了两个空间,一个用于存放数组的引用变量,另一个用于存放数组本身。下面将结合示意图来说明上面程序的运行过程。

当程序定义并初始化了a、b两个数组后,系统内存中实际上产生了4块内存区,其中栈内存中有两个引用变量: a和b;堆内存中也有两块内存区,分别用于存储a和b引用所指向的数组本身。此时计算机内存的存储示意图如图4.3所示。

当执行上面的粗体字标识代码b=a时,系统将会把a的值赋给b,a和b都是引用类型变量,存储的是地址。因此把a的值赋给b后,就是让b指向a所指向的地址。此时计算机内存的存储示意图如图4.4所示。

从图4.4中可以看出,当执行了b = a;之后,堆内存中的第一个数组具有了两个引用: a变量和b变量都引用了第一个数组。此时第二个数组失去了引用,变成垃圾,只有等待垃圾回收机制来回收它一但它的长度依然不会改变,直到它彻底消失

5.引用类型数组的初始化

从图4.11中可以看出,此时zhang和students[0]指向同一个内存区,而且它们都是引用类型变量,因此通过zhang和students[0]来访问Person实例的实例变量和方法的效果完全一样,不论修改students[0]所指向的Person实例的实例变量,还是修改zhang变量所指向的Person实例的实例变量,所修改的其实是同一个内存区,所以必然互相影响。同理,lee 和students[1]也是引用同一个Person对象,也具有相同的效果。

6.没有多维数组

Java语言里提供了支持多维数组的语法。但本书还是想说,没有多维数组一一如果从数组底层的运行机制上来看。
        Java语言里的数组类型是引用类型,因此数组变量其实是一个引用,这个引用指向真实的数组内存数组元素的类型也可以是引用,如果数组元素的引用再次指向真实的数组内存,这种情形看上去很像多维数组。

接着对这个“二维数组”执行初始化,同样可以把这个数组当成一维数组来初始化,把这个“二维数组”当成一个-维数组,其元素的类型是type[]类型,则可以采用如下语法进行初始化:

从上面程序中可以看出,初始化多维数组时,可以只指定最左边维的大小;当然,也可以一次指定每一维的大小。 例如下面代码(程序清单同上):

还可以使用静态初始化方式来初始化二维数组。使用静态初始化方式来初始化二维数组时,二维数组的每个数组元素都是一维数组,因此必须指定多个一维数组作为二维数组的初始化值。如下代码所示(程序清单同上):

7. Java 8 增强的工具包: Arrays

Java提供的Arrays 类里包含的一些static修饰的方法可以直接操作数组,这个Arrays 类里包含了如下几个static修饰的方法(static修饰的方法可以直接通过类名调用)。

 代码:

除此之外,在System类里也包含了一个static void arraycopy(Object sre, int srcPos, Object dest, int  destPos, int length)方法,该方法可以将sre数组里的元素值赋给dest数组的元素,其中srcPos指定从src数组的第几个元素开始赋值,length参数指定将sre数组的多少个元素值赋给dest数组的元素。
        Java 8增强了Arrays 类的功能,为Arrays类增加了一些工具方法,这些工具方法可以充分利用多CPU并行的能力来提高设值、排序的性能。下 面是Java 8为Arrays类增加的工具方法。

上面方法列表中,所有以parallel开头的方法都表示该方法可利用CPU并行的能力来提高性能。上面方法中的xxx代表不同的数据类型,比如处理int[]型数组时应将xxx换成int,处理long[]型数组时应将xxx换成long。

散称知识点:

  • JDK5提供了一种新的循环: foreach循环,能以更简单的方式来遍历集合、数组的元素。

并且Java7增强了switch 语句的功能,允许switch语句的控制表达式是java.lang.String类型的变量或表达式——只能是java.lang.String类型,不能StringBuffer或StringBuilder这两种字符串类型。

  • 把for循环的初始化语句放在循环之前定义还有一个作用:可以扩大初始化语句中所定义变量的作用域。在 for 循环里定义的变量,其作用域仅在该循环内有效,for 循环终止以后,这些变量将不可被访问。

疯狂Java讲义(四)相关推荐

  1. 疯狂java讲义第四章习题答案

    1.使用循环输出九九乘法表. 疯狂java讲义第四章课后习题第1题答案 2.根据给定的层数,使用循环输出等腰三角形. 疯狂java讲义第四章课后习题第2题答案 3.给定半径输出圆形. 需要注意的是,计 ...

  2. 疯狂Java讲义(六)----第四部分

    1.枚举类 在某些情况下,一个类的对象是有限而且固定的,比如季节类,它只有4个对象;再比如行星类,目前只有8个对象.这种实例有限而且固定的类,在Java里被称为枚举类. 在早期代码中,可能会直接使用简 ...

  3. 疯狂Java讲义:P200接口

    接口 Output package lee; public interface Output {//接口里定义的成员变量只能是常量int MAX_CACHE_LINE=50;//接口里定义的只能是pu ...

  4. 《疯狂Java讲义》读书笔记5

    目录 Java的集合类 Inerator 接口 Set 集合 HashSet 类 LinkedHashSet 类 TreeSet 类 EnumSet 类 List 集合 ArrayList 和 Vec ...

  5. 《疯狂JAVA讲义》学习笔记(一)

    本人之前一直从事iOS开发,最近开始接触Eclipse插件开发,打算先重拾一下扔了很久的Java.看到大家都在网上推荐李刚的<疯狂JAVA讲义>,于是下了一本开始学习.以下为前七章本人记录 ...

  6. 疯狂java讲义第五章课后习题答案

    1.编写一个学生类,提供name.age.gender.phone.address.cmail成员变量,且为每个成员变量提供 seter.geter方法.为学生类提供默认的构造器和带所有成员变量的构造 ...

  7. 学习《疯狂Java讲义第4版》PDF+代码+课件+面试题分析

    学习java选择了<疯狂java讲义>最新的第四版,用了两个多月时间看完,一边阅读,一边敲代码.对Java有了不少新的认识.书中实例清晰明了,讲解也是娓娓道来.Java可以编写图形桌面系统 ...

  8. 《疯狂Java讲义》学习笔记 第六章 面向对象(下续)

    这里## 6.6 Java 9改进的接口 6.6.1 接口的概念 6.6.2 Java 9中接口的定义 6.6.3接口的继承 ==以下代码中纯在自己的很多错误== 6.6.4使用接口 6.6.5接口和 ...

  9. 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条

    http://blog.csdn.net/terryzero/article/details/3797782 疯狂JAVA讲义---第十二章:Swing编程(五)进度条和滑动条 标签: swing编程 ...

  10. java下载pdf6_疯狂java讲义第6版 电子版(pdf格式)

    疯狂java讲义第6版pdf是李刚打造的经典java编程图书的最新版,为了帮助更多的读者能真正掌握Java编程,感受到Java语言的魅力,领会到Java编程的快乐,作者根据多年来的Java授课经验,精 ...

最新文章

  1. 直播回顾 | 最强中文NLP预训练模型艾尼ERNIE官方揭秘
  2. C语言scanf函数详解
  3. 马明哲新年内部讲话透露新战略:全面开启3.0时代
  4. linux设置脚本开机启动centos7,centos7设置开机启动
  5. 【PAT乙级】1068 万绿丛中一点红 (20 分)
  6. 安卓Day16-bug
  7. java编写斐波那契数列,实战案例
  8. leetcode1111. 有效括号的嵌套深度(栈)
  9. 优化算法笔记|粒子群算法理解及Python实现
  10. 创意十足!25个服饰行业的网站设计作品
  11. 基于JAVA+SpringMVC+Mybatis+MYSQL的在线作业管理系统
  12. Flutter高级第5篇:官方推荐的状态管理库 provider 的使用
  13. scala学习笔记三----scala函数式编程风格学习
  14. 取整函数和浮点计算函数,判断奇偶数,mysql序列号
  15. LCD1602的学习与理解
  16. Infinity 插件设置
  17. 【易错】Python中for循环删除元素,有个坑,请勿入坑!!
  18. 有缓震功能的舒缓拖鞋能给运动后带来什么样的减压效果?
  19. wires hark使用
  20. 华为防火墙地址转换技术(NAT)

热门文章

  1. 20140916阿里巴巴面试经历---成都站
  2. 电子音乐爱好者的舞台,电音遇上双12
  3. 手机电子邮箱怎么注册?手机电子邮箱格式怎么写?
  4. ANDROID以流形式上传文件
  5. 微软GitHub账户500G源代码被盗取,黑客声称欲免费公布
  6. 命里有时终须有与我命由我不由天
  7. 短线操作技巧,如何判断次日收阳
  8. tankgame网络版开发
  9. webstorm实用技巧
  10. Python自动化办公:批量识别图片文字并存为Excel