1、使用while与自增运算符循环遍历数组
1.1 实例说明
本实例利用自增运算符结合while循环获取每个数组元素的值,然后把它们输出到控制台中。其中自增运算符控制索引变量的递增。程序运行结果如图1所示。
图1 实例运行结果
1.2 实现过程
创建ErgodicArray类,在该类的主方法中创建一个鸟类数组,然后创建一个索引变量,这个变量用于指定数组下标,随着该索引的递增,while循环会逐步获取每个数组的元素并输出到控制台中。关键代码如下:
public class ErgodicArray {
public static void main(String[] args) {
// 创建鸟类数组
String[] aves = new String[] { "白鹭", "丹顶鹤", "黄鹂", "鹦鹉", "乌鸦", "喜鹊",
"布谷鸟", "灰纹鸟", "百灵鸟" };
int index = 0;// 创建索引变量
System.out.println("我的花园里有很多鸟,种类大约包括:");
while (index < aves.length) {// 遍历数组
System.out.println(aves[index++]);// 自增索引值
}
}
}
1.3 秘笈心法
1.3.1 前置与后置的自增运算
自增自减运算符分前置与后置两种,其中前置运算例如“++index”会先将index的值递增,然后在使用递增后的值,而后置运算例如“index++”会首先使用该变量的值,然后在把变量值递增。
2、使用for循环输出杨辉三角
2.1 实例说明
杨辉三角形由数字排列,可以把它看做一个数字表,其基本特性是两侧数值均为1,其他位置的数值是其正上方的数值与左上角数值之和。本实例通过数组来实现这个杨辉三角形,其运行结果如图1所示。
图1 杨辉三角形
2.2 实现过程
创建YanghuiTriangle类,在该类的主方法中创建一个二维数组,并指定二维数组的第一维长度,这个数组用于存放杨辉三角形的数值表,通过双层for循环来实现第二维数组的长度,然后计算整个数组的每个元素的值。程序关键代码如下:
public class YanghuiTriangle {
public static void main(String[] args) {
int triangle[][]=new int[8][];// 创建二维数组
// 遍历二维数组的第一层
for (int i = 0; i < triangle.length; i++) {
triangle[i]=new int[i+1];// 初始化第二层数组的大小
// 遍历第二层数组
for(int j=0;j<=triangle[i].length-1;j++){
// 将两侧的数组元素赋值为1
if(i==0||j==0||j==triangle[i].length-1){
triangle[i][j]=1;
}else{// 其它数值通过公式计算
triangle[i][j]=triangle[i-1][j]+triangle[i-1][j-1];
}
// 输出数组元素
System.out.print(triangle[i][j]+"\t");
}
System.out.println();
}
}
}
2.3 秘笈心法
2.3.1 Java二维数组可以不等长
Java语言中的二维数组其实是一维数组的每个元素都是另一个一维数组,所以第二维数组的长度可以任意,就像本实例中那样。这比其他语言的数组更灵活,而且多维数组也是如此。
3、使用嵌套循环在控制台上输出九九乘法表
3.1 实例说明
Java基本语法中的for循环非常灵活并且可以嵌套使用,其中双层for循环是程序开发中使用最频繁的,常用于操作表格数据,对于行数与列数相同的表格操作代码比较简单,但是类似九九乘法表就不好控制了,因为它的列数要与行数对应,可以说这个表格是个三角形,本实例通过双层循环输出了这个九九乘法表,效果如图1所示。在面试与等级考试中也常出现这类题目。
图1 九九乘法表
3.2 实现过程
创建MultiplicationTable类在该类的主方法中创建双层for循环,第一层for循环也称为外层循环,它用于控制表格的行,第二层循环也称为内层循环,它用于控制表格的列,这里第二层循环的控制变量非常重要,它的条件判断是列数要等于行数的最大值,然后输出内层与外层循环控制变量的乘积,这样就实现了九九乘法表。程序关键代码如下:
public class MultiplicationTable {
public static void main(String[] args) {
for(int i=1;i<=9;i++){// 循环控制变量从1遍历到9
for(int j=1;j<=i;j++){// 第二层循环控制变量与第一层最大索引相等
// 输出计算结果但不换行
System.out.print(j+"*"+i+"="+i*j+"\t");
}
System.out.println();// 在外层循环中换行
}
}
}
3.3 秘笈心法
3.3.1 灵活使用嵌套循环
循环语句可以完成复杂的运算,也可以用于控制程序的递归流程,而多层循环可以实现更加复杂的业务逻辑,是学习编程必须掌握的一种应用。在处理有规则的大量数据时,应该考虑使用多层循环来优化程序代码,但是建议添加详细的代码注释,便于以后的维护与修改工作。
4、用while循环计算1+1/2!+1/3!…1/20!
4.1 实例说明
本实例在计算阶阶乘的算法之上应用while循环语句计算1+1/2!+1/3!…1/20!的和。如果使用基本数据类型double是无法精确的显示运算结果的,所以本实例使用了BigDecimal类的实例来完成这个运算,实例运行结果如图1所示。
图1 实例运行结果
说明:由于本实例的运行结果精度非常高,小数位数过长,所以特殊设置了控制台折行,读者的运行结果可能是单行的数字。
4.2 实现过程
创建Example类,在该类的主方法中创建保存总和的sum变量和计算阶乘的factorial变量,为保证计算结果的精度,这两个变量都是BigDecimal类的实例对象。然后通过while实现20次循环,并完成计算,程序代码如下:
import java.math.BigDecimal;
public class Example {
public static void main(String args[]) {
BigDecimal sum = new BigDecimal(0.0); // 和
BigDecimal factorial = new BigDecimal(1.0); // 阶乘项的计算结果
int i = 1; // 循环增量
while (i <= 20) {
sum = sum.add(factorial); // 累加各项阶乘的和
++i; // i加1
factorial = factorial.multiply(new BigDecimal(1.0 / i)); // 计算阶乘项
}
System.out.println("1+1/2!+1/3!¡¤¡¤¡¤1/20!的计算结果等于:\n" + sum);// 输出计算结果
}
}
4.3 秘笈心法
4.3.1 使用BigDecimal类完成大数字与高精度运算
对于高精度要求或者运算数较大的计算,应该使用BigDecimal类实现,否则Java基本类型的数据无法保证浮点数的精度也无法对超出其表示范围的数字进行运算。
5、for循环输出空心的菱形
5.1 实例说明
本实例在输出菱形基础上加大难度,输出空心的菱形图案,这在等级考试与公司面试时也出现过类似题目,实例目的在于熟练掌握for循环的嵌套使用。实例运行结果如图1所示。
图1 实例输出结果
5.2 实现过程
public class Diamond {
public static void main(String[] args) {
printHollowRhombus(10);
}
public static void printHollowRhombus(int size) {
if (size % 2 == 0) {
size++;// 计算菱形大小
}
for (int i = 0; i < size / 2 + 1; i++) {
for (int j = size / 2 + 1; j > i + 1; j--) {
System.out.print(" ");// 输出左上角位置的空白
}
for (int j = 0; j < 2 * i + 1; j++) {
if (j == 0 || j == 2 * i) {
System.out.print("*");// 输出菱形上半部边缘
} else {
System.out.print(" ");// 输出菱形上半部空心
}
}
System.out.println("");
}
for (int i = size / 2 + 1; i < size; i++) {
for (int j = 0; j < i - size / 2; j++) {
System.out.print(" ");// 输出菱形左下角空白
}
for (int j = 0; j < 2 * size - 1 - 2 * i; j++) {
if (j == 0 || j == 2 * (size - i - 1)) {
System.out.print("*");// 输出菱形下半部边缘
} else {
System.out.print(" ");// 输出菱形下半部空心
}
}
System.out.println("");
}
}
}
5.3 秘笈心法
5.3.1 没有表达式的for循环
for循环中有3个表达式,这3个表达式都是可选的,也就是说for循环可以没有表达式,例如for(;;)这样的for循环将是一个无限循环,读者在使用for循环时应注意避免无限循环。
6、foreach循环优于for循环
6.1 实例说明
JDK1.8为Java添加了新的for循环foreach。它是原有for循环遍历数据的一种简写格式,使用的关键字依然是for但是参数格式不同。本实例使用foreach循环分别遍历集合对象与数组,并把元素值输出到控制台,实例运行结果如图1所示。
图1 实例运行结果
6.2 关键技术
foreach循环是for循环的一种简写格式,只用于遍历数据集合或数组,其语法格式如下:
for ( Type e : collections ) {
// 对变量e的使用
}
参数说明:
e:其类型Type是集合或数组中元素值的类型,该参数是集合或数组collections中的一个元素。
collections:要遍历的集合或数组,也可以是迭代器。
说明:
在循环体中使用参数e,该参数是foreach从集合或数组以及迭代器中取得的元素值,元素值是从头到尾进行遍历的。
6.3 实现过程
创建UseForeach类在该类的主方法中创建List集合对象,并为该对象添加内容,然后使用foreach循环遍历该集合输出所有内容,再从List集合中提取一个字符串数组,然后使用foreach循环遍历该数组,所有数组元素输出到控制台。程序关键代码如下:
import java.util.ArrayList;
import java.util.List;
public class UseForeach {
public static void main(String[] args) {
List<String> list=new ArrayList<String>();// 创建list集合
list.add("abc");// 初始化list集合
list.add("def");
list.add("hij");
list.add("klm");
list.add("nop");
list.add("qrs");
System.out.print("foreach遍历集合:\n\t");
for (String string : list) {// 遍历list集合
System.out.print(string);// 输出集合的元素值
}
System.out.println();
String[] strs=new String[list.size()];
list.toArray(strs);// 创建数组
System.out.print("foreach遍历数组:\n\t");
for (String string : strs) {// 遍历数组
System.out.print(string);// 输出数组元素值
}
}
}
6.4 秘笈心法
6.4.1 使用foreach遍历数据
在JDK1.5之前使用for循环对集合、数值和迭代器进行遍历,这需要创建索引变量、条件表达式,这写会使代码造成混乱,并增加出错的几率,并且每次循环中索引变量或迭代器都会出现三次,有两次出错的机会。而且会有一些性能损失,其性能稍微落后于foreach循环。所以对于数据集合的遍历,建议使用foreach循环完成。
7、终止循环体
7.1 实例说明
循环用于复杂的业务处理可以提高程序的性能和代码的可读性,但是循环中也有特殊情况,例如由于某些原因需要立刻中断循环去执行下面的业务逻辑。实例运行如图1所示。
图1 实例运行结果
7.2 实现过程
在Eclipse中创建一个Java项目,在项目中创建BreakCyc类,在该类的主方法中创建一个字符串数组,在使用foreach遍历的时候判断如果发现数组中包含字符串“老鹰”则立刻中断循环。在创建一个整数类型二维数组,使用双层foreach循环遍历,当发现第一个小于60的数组元素,则立刻中断整个双层循环,而不是内层循环。程序关键代码如下:
public class BreakCyc {
public static void main(String[] args) {
System.out.println("\n-------------中断单层循环的例子。-------------");
// 创建数组
String[] array = new String[] { "白鹭", "丹顶鹤", "黄鹂", "鹦鹉", "乌鸦", "喜鹊",
"老鹰", "布谷鸟", "老鹰", "灰纹鸟", "老鹰", "百灵鸟" };
System.out.println("在你发现第一只老鹰之前,告诉我都有什么鸟。");
for (String string : array) {// foreach遍历数组
if (string.equals("老鹰"))// 如果遇到老鹰
break;// 中断循环
System.out.print("有:" + string+" ");// 否则输出数组元素
}
System.out.println("\n\n-------------中断双层循环的例子。-------------");
// 创建成绩数组
int[][] myScores = new int[][] { { 67, 78, 63, 22, 66 },
{ 55, 68, 78, 95, 44 }, { 95, 97, 92, 93, 81 } };
System.out.println("宝宝这次考试成绩:\n数学\t语文\t英语\t美术\t历史");
No1: for (int[] is : myScores) {// 遍历成绩表格
for (int i : is) {
System.out.print(i + "\t");// 输出成绩
if (i < 60) {// 如果中途遇到不及格的,立刻中断所有输出
System.out.println("\n等等," + i + "分的是什么?这个为什么不及格?");
break No1;
}
}
System.out.println();
}
}
}
7.3 秘笈心法
7.3.1 用break避免死循环
充分利用循环可以提高程序的开发与执行效率,但是如果不注重循环中的算法很容易导致程序的死循环,那将是程序的死穴。所以在循环体中要对可能出现的特殊情况使用break语句中断循环。
8、循环体的过滤器
8.1 实例说明
循环体中可以通过break语句中断整个循环,这增加了循环的控制能力,但是对于特殊情况还是不够,例如某些条件下需要放弃部分循环处理,而不是整个循环体。Java提供了continue语句来实现这一功能,continue可以放弃本次循环体的剩余代码,不执行它们而开始下一轮的循环,本实例利用continue语句实现了循环体过滤器,可以过滤“老鹰”字符串,并做相应的处理,但是放弃continue语句之后的所有代码。程序运行结果如图1所示。
图1 实例运行结果
8.2 实现过程
在Eclipse项目中创建CycFilter类,在该类的主方法中创建鸟类名称的字符串数组,其中包含多个“老鹰”字符串,然后通过foreach循环遍历该数组,在循环过程中如果遍历的数组元素是“老鹰”字符串,则输出发现老鹰的信息并过滤循环体之后的需哦有代码。关键代码如下:
public class CycFilter {
public static void main(String[] args) {
// 创建数组
String[] array = new String[] { "白鹭", "丹顶鹤", "黄鹂", "鹦鹉", "乌鸦", "喜鹊",
"老鹰", "布谷鸟", "老鹰", "灰纹鸟", "老鹰", "百灵鸟" };
System.out.println("在我的花园里有很多鸟类,但是最近来了几只老鹰,请帮我把它们抓走。");
int eagleCount = 0;
for (String string : array) {// foreach遍历数组
if (string.equals("老鹰")) {// 如果遇到老鹰
System.out.println("发现一只老鹰,已经抓到笼子里。");
eagleCount++;
continue;// 中断循环
}
System.out.println("搜索鸟类,发现了:" + string);// 否则输出数组元素
}
System.out.println("一共捉到了:" + eagleCount + "只老鹰。");
}
}
8.3 秘笈心法
8.3.1 让循环多一些控制
break语句和continue语句都是对循环体的控制语句,它们不仅应用于for循环,在任何循环体中都可以使用这些语句,灵活使用可以让循环实现更加复杂的运算和业务处理。
9、循环的极限
9.1 实例说明
循环是常用的开发模式,它可以简化业务处理,提高代码编写与程序运行效率,但是循环中的控制算法要掌握好,否则容易造成死循环导致程序崩溃。本实例将向读者介绍一个Java语言中很难发现的导致程序死循环的实例,实例将测试使用int整数类型作为循环索引变量,也是循环控制变量,用它来控制循环的次数,但是当这个程序的条件是索引小于等于变量类型的最大值时会发生什么。
9.2 实现过程
public class CycUtmost {
public static void main(String[] args) {
int end=Integer.MAX_VALUE;// 定义循环终止数
int start=end-50;// 定义循环起始数
int count=0;// 定义循环计数器
for (int i = start; i <= end; i++) {// 执行循环
count++;// 循环计数
}
// 输出循环计数器
System.out.println("本次循环次数为:"+count);
}
}
技巧:
你会认为这个程序会循环至少50次,然后把计数器的值输出,但实际上这个程序的运行结果会导致死循环,因为控制条件是索引小于等于整数类型的最大值,当整数类型达到其最大值再累加1的时候会的到整数类型的最小值,所以它永远不可能大于end变量,这样就导致了程序的死循环,所以在程序开发时注意控制变量的取值范围。
9.3 秘笈心法
9.3.1 了解变量的取值范围
Java基本数据类型都有其取值范围,熟悉二进制原理的读者应该能够裂解,当超出取值范围时,数值会被截取。例如本实例中的循环控制变量超出整数类型的最大取值范围时,就会绕回整数类型的最小值。所以在进行条件判断涉及取值边界时,要考虑这个因素。
************关于作者************
学习过程中有任何问题不懂得都可以进行咨询,欢迎来撩!