第5章 数组及其常用操作

本章读者可以学到如下实例:

  • 实例031 获取一维数组的最小值
  • 实例032 将二维数组中的行列互换
  • 实例033 利用数组随机抽取幸运观众
  • 实例034 用数组设置JTable表格的列名与列宽
  • 实例035 使用按钮控件数组实现计算器界面
  • 实例036 通过复选框控件数组实现添加多个复选框控件
  • 实例037 使用选择排序法对数组排序
  • 实例038 使用冒泡排序法对数组排序
  • 实例039 使用快速排序法对数组排序
  • 实例040 使用直接插入法对数组排序
  • 实例041 使用Sort()方法对数组排序
  • 实例042 反转数组中元素的顺序

实例031 获取一维数组的最小值

实例说明

一维数组常用于保存线性数据,如数据库中的单行数据就可以使用一维数组保存。本实例将接收用户在文本框中输入的单行数据(其中数据都是整数数字,以不同数量的空格分割),这个数据将被程序分解成一维数组,并从数组中提取最小值显示在界面中。实例的运行效果如图5.1所示。

指点迷津

程序经过特殊判断,数字之间的空格可以使用多个

实现过程

(1)在Eclipse中创建项目031,并在该项目中创建com.Mingrisoft包.
(2)在com.Mingrisoft包中新建JFrame窗体类,名称为ArrayMinValue。在窗体中添加个文本框和一个“计算”按钮以及多个标签控件
(3)编写“计算”按钮的事件处理方法,在该方法中首先获取用户的输入,并通过trim()方法去除左右空格,然后对字符串内容进行检测,排除非法输入,并把字符串转换为整型数组,最后在遍历数组的同时提取最小值并显示到窗体的标签控件中。关键代码如下:

G:\Desktop\书籍\Java\Java 实战\Java经典编程300例\Java经典编程300例\SL\04\030\src\com\mingrisoft\CycFilter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
protected void do_button_actionPerformed(ActionEvent e) {
String arrayStr = textField.getText().trim(); // 去除左右空格
if (arrayStr.equals("")) {
JOptionPane.showMessageDialog(null, "请输入数字内容");
return;
}
for (int i = 0; i < arrayStr.length(); i++) { // 过滤非法输入
char charAt = arrayStr.charAt(i);
if (!Character.isDigit(charAt) && charAt != ' ') {
JOptionPane.showMessageDialog(null, "输入包含非数字内容");
textField.setText("");
return;
}
}
String[] numStrs = arrayStr.split(" {1,}"); // 分割字符串
int[] numArray = new int[numStrs.length]; // 创建整型数组
// 转换输入为整型数组
for (int i = 0; i < numArray.length; i++) {
numArray[i] = Integer.valueOf(numStrs[i]);
}
int min = numArray[0]; // 创建最小数变量
for (int j = 0; j < numArray.length; j++) {
if (min > numArray[j]) { // 提取最小整数
min = numArray[j];
}
}
label.setText("数组中最小的数是:" + min); // 显示最小值到指定的标签中
}
展开/折叠

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package com;

import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class ArrayMinValue extends JFrame
{

/**
*
*/
private static final long serialVersionUID = -2066250832480702511L;
private JPanel contentPane;
private JTextField textField;
private JLabel lblNewLabel_1 = new JLabel("");

/**
* Launch the application.
*/
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable() {
public void run()
{
try
{
ArrayMinValue frame = new ArrayMinValue();
frame.setVisible(true);
} catch (Exception e)
{
e.printStackTrace();
}
}
});
}

/**
* Create the frame.
*/
public ArrayMinValue() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new GridLayout(4, 1, 0, 0));

JLabel lblNewLabel = new JLabel("请在文本框中输入多个整数,以空格为分隔符。例如:3 5 2 562 125");
lblNewLabel.setVerticalAlignment(SwingConstants.TOP);
contentPane.add(lblNewLabel);

textField = new JTextField();
contentPane.add(textField);
textField.setColumns(10);

JPanel panel = new JPanel();
contentPane.add(panel);
panel.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 5));

JButton btnNewButton = new JButton("计算");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
do_button_actionPerformed();
}

private void do_button_actionPerformed()
{
// 获取文本框中的内容
String inputText = textField.getText();
// 检查输入合法性
if (checkInput(inputText))
{
// 解析输入成数组
int[] numbers = parseInputIntoArray(inputText);
// 查找数组中最小值所在的下标
int minIndex = findMinIndex(numbers);
lblNewLabel_1.setText("最小值:" + numbers[minIndex]);
}
}
/**
* 将输入转换成int数组
* @param inputText 文本框中的输入.
* @return int数组
*/
private int[] parseInputIntoArray(String inputText)
{
String[] numberStrs = inputText.trim().split(" ");
int[] numbers = new int[numberStrs.length];
for (int i = 0; i &lt; numbers.length; i++)
{
numbers[i] = Integer.valueOf(numberStrs[i]);
}
return numbers;
}
/**
* 查找数组中最小的元素所在的下标.
* @param numbers 要查找的数组.
* @return 最小值所在的下标.
*/
private int findMinIndex(int[] numbers)
{
int minIndex = 0;
for (int j = 1; j &lt; numbers.length; j++)
{
// 如果后面的比前面的小
if (numbers[j] &lt; numbers[minIndex])
{
// 记录下最小的位置
minIndex = j;
}
}
return minIndex;
}
/**
* 检查输入合法性,不能输入空字符串,也不能输入除了数字和空格之外的其他字符.
* @param inputText 文本框中输入的内容
* @return 如果输入合法,则返回true.
*/
private boolean checkInput(String inputText)
{
if (inputText.equals(""))
{
JOptionPane.showMessageDialog(null, "请输入内容");
return false;
}
for (int i = 0; i &lt; inputText.length(); i++)
{
char ch = inputText.charAt(i);
if (!Character.isDigit(ch) && ch != ' ')
{
JOptionPane.showMessageDialog(null, "请输入数字");
return true;
}
}
return true;
}
});
btnNewButton.setHorizontalAlignment(SwingConstants.LEFT);
panel.add(btnNewButton);
panel.add(lblNewLabel_1);
}
}

多学两招

for语句用于程序的循环流程控制。该语句有3个表达式用于循环变量的控制,其完整语法格式为:

1
2
for(int 1-=0; i<100; i++)(
}

for语句中的3个表达式不是完全必备的,可以根据情况部分省略,甚至完全省略。例如下面代码就以最简单的格式实现了无限循环。

1
2
3
for(;;){

}

技术要点

本实例主要应用String类的split()方法将输入的字符串分割为字符串数组,再将其转换为整型数组,最后通过for循环遍历该数组,并通过if语句提取最小值。其中,split方法可以使字符串按指定的分割字符或字符串进行分割,并将分割后的结果存放在字符串数组中。其语法格式如下

1
String split(String sign);

参数说明:

  • string:为字符串对象
  • sign:为分割字符串的分割符,也可以使用正则表达式。

第4章 流程控制

本章读者可以学到如下实例

  • 实例019 判断某一年是否为闰年
  • 实例020 验证登录信息的合法性
  • 实例021 为新员工分配部门
  • 实例022 用switch语句根据消费金额计算折扣
  • 实例023 判断用户输入月份的季节
  • 实例024 使用while循环语句与自增运算符循环遍历数组
  • 实例025 使用for循环输出杨辉三角形
  • 实例026 使用嵌套循环在控制台上输出九九乘法表
  • 实例027 使用while循环计算1+1/2!+1/3!…1/20!
  • 实例028 使用for循环输出空心的菱形
  • 实例029 终止循环体
  • 实例030 循环体的过滤器

实例019 判断某一年是否为闰年

实例说明

地球绕太阳一圈称之为一年,所用时间是365天5小时48分46秒,取365天为一年,4年将多出23小时15分6秒,将近一天,所以4年设一个闰日(2月29日),这年称为闰年。本实例将要求用户输入年份,并判断输入的年份是否为闰年。实例的运行效果如图4.1所示。

实现过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.mingrisoft;
import java.util.Scanner;

public class Demo {
/**
* @param args
*/
public static void main(String[] args) { //主方法
Scanner scan = new Scanner(System.in);
System.out.println("请输入一个年份:"); //向控制台输出一个提示信息
long year;
try {
year = scan.nextLong();
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) { // 是闰年
System.out.print(year + "是闰年!");
} else { // 不是闰年
System.out.print(year + "不是闰年!");
}
} catch (Exception e) {
System.out.println("您输入的不是有效的年份!");
}
}
}

指点迷津

java.util包的Scanner类是一个用于扫描输入文本的简单文本扫描器,可以用这个类从控制台写入数据。该类的netlOg()方法可以将输入信息扫描为一个long型的数据,如果输入的信息不能被成功转换为long型,将抛出java.Util.InputMismatchException异常。

技术要点

本实例主要的技术就是应用if语句判断闰年。判断一个年份是否为闰年,要满足两个条件个是能被4整除但不能被100整除,另一个是能被400整除。判断闰年的公式用Java语法实现的格式如下:

1
year%4==0&&year%100!=0||year%400==0

实例020 验证登录信息的合法性

大多系统的登录模块都会接收用户通过键盘输入的登录信息,这些登录信息将会被登录模块验证,如果使用的是指定的用户名与密码,则允许用户登录;否则将用户拒之门外。本实例将通过if…else语句进行多条件判断实现登录信息验证。实例的运行效果如图42所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.mingrisoft;

import java.util.Scanner;
public class CheckLogin {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);// 创建扫描器
System.out.println("请输入登录用户名:");
String username = scan.nextLine();// 接收用户输入登录名
System.out.println("请输入登录密码:");
String password = scan.nextLine();// 接收用户输入登录密码
if (!username.equals("mr")) {// 判断用户名合法性
System.out.println("用户名非法。");
} else if (!password.equals("mrsoft")) {// 判断密码合法性
System.out.println("登录密码错误。");
} else {// 通过以上两个条件判断则默认通过登录验证
System.out.println("恭喜您,登录信息通过验证。");
}
}
}

多学两招
字符串属于对象而非基本数据类型,不能使用“==”来判断两个字符串是否相当,所以需要通过equals方法来判断两个宇符串内容是否相同,正如本实例对用户名和密码的判断那样。使用“==”判断的将是两个字符串对象的内存地址,而非字符串内容.

实例022 用switch语句根据消费金额计算折扣

实例说明

俗话说“商场如战场”,各大商家为了笼络有限的顾客,经常会打出各种各样的促销手段。例如,会员折扣制度,即对会员的消费金额进行累加,当超过一定数额时,可以享受相应的折扣。累计消费金额越高,享受的折扣越多。本实例将应用switch语句计算累计消费金额达到一定数额时,享受不同的折扣价格。实例的运行效果如图44所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.mingrisoft;

public class ProductPrice {
public static void main(String[] args) {
float money = 1170; // 金额
String rebate = ""; // 折扣
if (money > 200) {
int grade = (int) money / 200; // 等级
switch (grade) { // 根据等级计算折扣比例
case 1:
rebate = "九五折";
break;
case 2:
rebate = "九折";
break;
case 3:
rebate = "八五折";
break;
case 4:
rebate = "八三折";
break;
case 5:
rebate = "八折";
break;
case 6:
rebate = "七八折";
break;
case 7:
rebate = "七五折";
break;
case 8:
rebate = "七三折";
break;
case 9:
rebate = "七折";
break;
case 10:
rebate = "六五折";
break;
default:
rebate = "六折";
}
}
System.out.println("您的累计消费金额为:" + money);// 输出消费金额
System.out.println("您将享受" + rebate + "优惠!"); // 输出折扣比例
}
}

脚下留神

在程序开发中经常使用的都是正数,负数因为使用得少,常常被忽略,例如“N%2==1”本来是用来计算数字N是否为奇数的,但是开发者没有考虑到负数的情况,从而导致这个算法的失败,因为任何负数应用这个算法都会等于-1。

实例023 判断用户输入月份的季节

实例说明年有四季,每季3个月。其中,

  • 12月、1月和2月为冬季,
  • 3月、4月和5月为春季,
  • 6月、7月和8月为夏季,
  • 9月、10月和11月为秋季。

本实例将根据用户输入的月份来判断季节,这是一个最典型的演示switch语法的例子,通过这个例子,读者可以完全掌握switch语句的用法与技巧。实例的运行效果如图45所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.mingrisoft;

import java.util.Scanner;
public class JudgeMonth {

public static void main(String[] args) {
Scanner scan = new Scanner(System.in); // 创建扫描器
// 提示用户输入月份
System.out.println("请输入一个月份,我能告诉你它属于哪个季节。");
int month = scan.nextInt(); // 接收用户输入
switch (month) { // 判断月份属于哪个季节
case 12:
case 1:
case 2:
System.out.print("您输入的月份属于冬季。");
break;
case 3:
case 4:
case 5:
System.out.print("您输入的月份属于春季");
break;
case 6:
case 7:
case 8:
System.out.print("您输入的月份属于夏季");
break;
case 9:
case 10:
case 11:
System.out.print("您输入的月份属于秋季");
break;
default:
System.out.print("你那有" + month + "月份吗?");
}
}
}

脚下留神

switch语句的每个case关键字都用于判断一个常量并做出相应的业务处理,熟练掌握switch语句之后可以组合多个case来完成多条件的处理,就是多个常量结果执行相同的业务处理,如本实例中应用的格式。

实例024 使用while循环语句与自增运算符循环遍历数组

实例说明在多数情况下,遍历数组都是使用for循环语句实现。其实应用while循环语句和自增运算符也可实现遍历数组。本实例将利用自增运算符结合while循环语句实现数组的遍历,并将遍历结果输出到控制台。实例的运行效果如图46所示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.mingrisoft;

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++]);// 自增索引值
}
}
}

指点迷津
自增自减运算符分前置和后置两种。其中,前置运算如“++index”,会先将index的值递增,然后再使用递增后的值;而后置运算如“index++”,会首先使用该变量的值,然后再把变量值递增.

实例025 使用for循环输出杨辉三角形

实例说明
杨辉三角形由数字排列,可以把它看作一个数字表,其基本特性是两侧数值均为1,其他位置的数值是其正上方的数值与左上角数值之和。本实例将使用for循环输出包括10行内容的杨辉三角形。实例的运行效果如下所示:

1       
1       1
1       2       1
1       3       3       1
1       4       6       4       1
1       5       10      10      5       1
1       6       15      20      15      6       1
1       7       21      35      35      21      7       1
1       8       28      56      70      56      28      8       1
1       9       36      84      126     126     84      36      9       1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.mingrisoft;

public class YanghuiTriangle {
public static void main(String[] args) {
int triangle[][]=new int[10][];// 创建二维数组
// 遍历二维数组的第一层
for (int i = 0; i < triangle.length; i++) {
triangle[i]=new int[i+1];// 初始化第二层数组的大小
// 遍历第二层数组
for(int j=0;j<=i;j++){
// 将两侧的数组元素赋值为1
if(i==0||j==0||j==i){
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(); //换行
}
}
}

指点迷津

在创建二维数组时,其第一维的长度即是要输出杨辉三角形的行数。例如,在本实例中要输出10行的杨辉三角形就可以将其第一维的长度设置为10.

指点迷津

Java语言中的二维数组其实是每个元素都是一个一维数组的一维数组,所以第二维的长度可以任意,就像本实例中那样。这比其他语言的数组更灵活,而且多维数组也是如此。

技术要点

本实例应用的主要技术是应用for循环语句根据杨辉三角形的公式遍历二维数组。杨辉三角形的公式包括两部分,一部分是两侧数值都是1,也就是说二维数组的triangle[0][0]triangle[i][0]或者triangle[i][i]的元素值为1,另一部分是其他位置的数值是其正上方的数值与左上角数值之和,也就是triangle[i][j]=triangle[i-1][j]+triangle[i-1][j-1].

指点迷津

在二维数组中,第1个下标值代表的是行数,第2个下标值代表的是列数,即triangle[o代表的是第i行第0列的元素.

实例026 使用嵌套循环在控制台上输出九九乘法表

实例说明

对于九九乘法表读者都不会陌生,几乎每个人都能倒背如流。那么如何通过嵌套循环,在控制台上输出九九乘法表呢?这个内容在掌握了for循环的嵌套后,就不难实现。本实例将应用嵌套的for循环实现在控制台上输出九九乘法表。实例的运行效果如图4.8所示。

1*1=1
1*2=2   2*2=4
1*3=3   2*3=6   3*3=9
1*4=4   2*4=8   3*4=12  4*4=16
1*5=5   2*5=10  3*5=15  4*5=20  5*5=25
1*6=6   2*6=12  3*6=18  4*6=24  5*6=30  6*6=36
1*7=7   2*7=14  3*7=21  4*7=28  5*7=35  6*7=42  7*7=49
1*8=8   2*8=16  3*8=24  4*8=32  5*8=40  6*8=48  7*8=56  8*8=64
1*9=9   2*9=18  3*9=27  4*9=36  5*9=45  6*9=54  7*9=63  8*9=72  9*9=81

脚下留神:
在上面的代码中,在内层循环输出计算结果时,应用的是System.out对象的print()方法输出,应用该方法不换行,在内层循环结来后,再应用System.out对象的println()方法换行。
指点迷津:
循环语句可用于完成复杂的运算,也可以用于控制程序的递归流程,而多层循环可以实现更加复杂的业务逻辑,是学习编程必须掌握的一种应用。在处理有规则的大量数据时,应该考虑使用多层循环来优化程序代码,但是建议添加详细的代码注释,便于以后的维护与修改工作。
技术要点
要在控制台上输出九九乘法表,可以通过嵌套的for循环来实现,即创建双层的for循环。

  • 第一层for循环,也称外循环,用于控制表格的行;
  • 第二层for循环,也称内循环,用于控制表格的列。

其中,

  • 第一层for循环的控制变量的最大值是9,
  • 第二层for循环的控制变量的最大值要等于行数的最大值。
    • 然后输出内层与外层循环控制变量的乘积,即可实现九九乘法表。

实例027 使用while循环计算1+1/2!+1/3!…1/20!

实例说明

本实例在计算阶乘的算法之上应用while循环语句计算1+1/2!+1/3!…1/20!的和。如果使用基本数据类型double是无法精确地显示运算结果的,所以本实例使用了BigDecimal类的实例来完成这个运算。实例的运行效果如图49所示。

1+1/2!+1/3!···1/20!的计算结果等于:
1.71828182845904522367258882524732563634867246268558104448130832136101139366719986414383110243797108748822820657493330665752903534700022508204525385549479876951292493516361991885142411580915233808389198581342610980977425822951724476374113374431295345516733481291917383751991568557019209000617394017755970330759280319424925748716392429788018461622511631047241914024775263254452027548084334842631749679270930789639542724477953673333791555400257219557963341089085618184152725912383836106812569589258574113531875910271222819280308083619226237539764181652472718046378704910462924352995976893461209516866339555490458432187283021232937484781081946952237499593023333299830547132009915333667625253213008545235615683712431845561218831886238965727822680526029924244310460181428675093053813137695411922636380686046919663567678071558475494384765625
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package com.mingrisoft;

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); // 输出计算结果
}
}

公式推导

1/3!=1/(3*2*1)=(1/3)*(1/2)*(1/1)=(1/1)*(1/2)*(1/3)

脚下留神:

对于高精度要求或者运算数较大的计算,应该使用BigDecimal类实现,否则Java基本类型的数据无法保证浮点数的精度,也无法对超出其表示范围的数字进行运算

技术要点

本实例主要应用了while循环和BigDecimal类的实例对象的相关方法实现计算1+1/2!+1/3!+…+1/20!的和。
BigDecimal类型的数字可以用来做超大的浮点数的运算,如加、减、乘、除等。使用BigDecimal对象的add()方法可以实现加法运算,使用multiply()方法可以实现乘法运算。

实例028 使用for循环输出空心的菱形

实例说明本实例在输出菱形的基础上加大难度,输出空心的菱形图案,这在等级考试与公司面试时也出现过类似题目,实例目的在于要求熟练掌握for循环的嵌套使用。实例的运行效果如图4.10所示

1
2
3
4
5
6
7
      *
* *
* *
* *
* *
* *
*

实现过程

(2)在com.Mingrisoft包中创建类文件,名称为Diamond,并在该类的主方法中调用printHollowRhombus方法完成7行的空心菱形输出。其中printHollowRhombus方法是实例中自定义的,该方法使用两个双层for循环分别输出菱形的上半部分与下半部分。关键代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.mingrisoft;

public class Diamond {
public static void main(String[] args) {
printHollowRhombus(6);
}

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(""); // 换行
}
}
}

脚下留神

for循环中有3个表达式,这3个表达式都是可选的,也就是说for循环可以没有表达式.例如for(;;)这样的for循环将是一个无限循环,读者在使用for循环时应注意避免无限循for循环中有3个表达式,这3个表达式都是可选的,也就是说for循环可以没有表达式.

技术要点

本实例应用的主要技术是for循环语句的嵌套和ifelse语句。其中,ifelse语句用于控制菱形中心位置不输出*号,即输出空心菱形。

实例029 终止循环体

实例说明

循环用于复杂的业务处理,可以提高程序的性能和代码的可读性,但是循环中也有特殊情况,例如由于某些原因需要立刻中断循环去执行下面的业务逻辑,这时就可以使用break语句实现。本实例将实现应用break语句中断单层循环中断双层for循环。实例的运行效果如图4.l1所示。

实现过程

(1)在eclipse中创建项目029,并在该项目中创建com.mingrisoft包。
(2)在com.mingrisoft包中创建类文件,名称为BreakCyc。在该类的主方法中,首先创建一个字符串数组,然后在使用for循环遍历时判断如果发现数组中包含字符串“老鹰”则立刻中断循环。最后再创建一个整数类型的二维数组,并使用双层for循环遍历,当发现第一个小于60的数组元素时,立刻中断整个双层循环,而不是内层循环。关键代码如下:

指点迷津

充分利用循环可以提高程序的开发与执行效率,但是如果不注重循环中的算法很容易导致程序的死循环,所以在循环体中要对可能出现的特殊情况使用break语句中断循环,

技术要点

本实例应用的主要技术是break语句。break语句用于强行退出循环。使用带标签的break语句,可以强行退出多层循环。例如,要退出双层的for循环,可以使用下面的语法:

1
2
3
4
5
6
7
8
9
lable:
for(元素变量x:遍历对象obj){
for(元素变量x1:遍历对象obj1){
// 引用了x的Java语句;
if(条件表达式){
break lable;

}
}

在上面的语法中,如果执行到break,正常情况下应该结束内层循环去执行外层循环,但是由于break后带有标签,所以程序将结束标签处的外层循环。

实例030 循环体的过滤器

实例说明

循环体中可以通过break语句中断整个循环,这增加了循环的控制能力,但是对于特殊情况还是不够,例如某些条件下需要放弃部分循环处理,而不是整个循环体。Java提供了continue语句来实现这一功能,continue语句可以放弃本次循环体的剩余代码,不执行它们而开始下轮的循环。本实例利用continue语句实现了循环体过滤器,可以过滤“老鹰”字符串,并做相应的处理,但是放弃continue语句之后的所有代码。实例的运行效果如图412所示

实现过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.mingrisoft;

public class CycFilter {
public static void main(String[] args) {
// 创建数组
String[] array = new String[] { "白鹭", "丹顶鹤", "黄鹂", "鹦鹉", "乌鸦", "喜鹊", "老鹰", "布谷鸟", "老鹰", "灰纹鸟", "老鹰", "百灵鸟" };
System.out.println("在我的花园里有很多鸟类,但是最近来了几只老鹰,请帮我把它们抓走。");
int eagleCount = 0;
// foreach遍历数组
for (String string : array) {
// 如果遇到老鹰
if (string.equals("老鹰")) {
System.out.println("发现一只老鹰,已经抓到笼子里。");
eagleCount++;
continue;// 中断循环
}
// 否则输出数组元素
System.out.println("搜索鸟类,发现了:" + string);
}
System.out.println("一共捉到了:" + eagleCount + "只老鹰。");
}
}

多学两招

break语句和continue语句都是对循环体的控制语句,它们不仅应用于for循环,在任何循环体中都可以使用这些语句,灵活使用可以让循环实现更加复杂的运算和业务处理。

技术要点

本实例应用的主要技术是continue语句。continue语句只能应用在forwhiledowhile循环语句中,用于让程序直接跳过其后面的语句,进行下一次循环。continue语句的语法比较简单,只需要在循环体中使用关键字continue加分号即可.

Java经典编程300例 前言

会站在巨人的肩膀上!
开发的终极目标是满足用户需求,一个软件往往包含复杂的功名程序员需要很的时间内实现对新手,显然并不容易有开发经验的程序员编程效率非常高?答案就是他们做过类似的程序,通过适当的修改以前的代码就可以满足现在的要求。因此速加强编程经验的积累就成了新手的当务之急。显然,单单依靠项目来积累速度是非常慢
本书图文并茂、难易并举,汇集开发中广泛使用的实例,内容涵盖Java EE编程的实例分成实例说明、实现过程和技术要点3部分进行讲解。通过对本的学但能快速掌握相关知识点,还能逐步提升编程能.

本书内容

本书以基础知识结构为框架,给出了每邹分知识中可能遇到的疑难问题或者是开发扌本书共17章,主要包a语言概述、Eclipse开发工具、Java语言基础、流程控制、数组其常用操对象对象进阶、字符串与包装类集合类框架数具类、错误处理、输入输岀、枚举类型与泛型、Swing多线程、网络通信和数据库.
为了更清晰地阐述问题和给出问题的解决方案,本书设置了以下栏目:

  • 实例说明:详细描述本
  • 用途,并给出实例的运行效果截图
  • 过程:逐步讲解如何解决本实例的问题,并给出关键代码、注意事项等
  • 技术要点:对本实例使用的关键技术进行总结,方便日后使用

本书特色

  • 贴近应用。本书精选的实例都是真正来自开发一线。以实例的形式来进行讲解,使其易被读者接
  • 横向链接。本书知识框架a开发入门及项目实战》一书相以在使用《Java发入门及项目实进行基础学用本书丰富并提高技能
  • 解析透彻。本书对每个问题的相关知识进行细致地讲解,并进行知识拓展,使读者仅知其然,而且知其所以然。
  • 授人以渔。本书在讲解技术的同时,还注重对读者能力的培养,使读者掌握分析问题,解决问题的能力。

本书配套资源

提供了内容丰富的配套讠包括源程序、素材模块库、案例库、题库、素材库等多项辅助内容,读者朋友可以通过如下方式获取

第1种方式

  • 登录http://www.tup.com.cn/,在网页 右上角的搜索文本框中输书名:Java经典编程300例(注意写和留出空格),或者输入本书关键字,或者输入本书号(注意去掉ISBN号间隔线“单击“搜索”按钮
  • 找到本书后单击超链接,在该书的网页下侧单击“网络资源”超链接,即可
1
2
3
4
5
6
7
8
9
10
11
12
尊敬的教师/读者您好:

本书属于零售店销书,因书自身已配有完整教学光盘(视频教学、素材、源代码、课件等)故不提供其他资源。
为了更好地服务您们,我们特将该书的光盘资源拷贝到了我们社的百度云网盘存储以备您们下载使用。

本书光盘资源下载地址:(请关注我们的百度云网盘,点击该书资源下载链接即可下载。)

http://pan.baidu.com/s/1gefFcLd

客服QQ:2150049669

如有问题,请直拨客服:010-62799916-223 叶老师

第2种方式

访问本书的新浪微博Javamrbook,找到配套资源的链接地址进行下载。

读者人群

本书非常适合以下人员阅读:

  • 从事Java语言编程行业的开发人员
  • 有一定语言基础,想进一步提高技能的人员
  • 大中专院校的老师和学生
  • 即将走向工作岗位的大学毕业生
  • 相关培训机构的老师和学员
  • Java语言编程爱好者

1.4 数据库分析与设计

1.4.1 数据库分析

在开发企业日常事务管理系统时,考虑到中小型企业的需求,项目开发成本以及维护成本。本系统将采用MySQL5.0作为后台数据库,数据库名为db_Affairmanage。数据库中一共包含4张表,用来储存不同的信息,详细信息如图1-13所示

1.4.2 数据库概念设计

本系统一共设计规划出4个实体,分别是员工信息实体消息信息实体消息回复实体以及消息批复实体.
只有企业内部员工才能使用该系统,因此需要在数据库中建立一个员工信息表,用来储存员工的相关信息。员工信息实体ER图如图1-14所示。

公司每个员工都可以发表消息,这时就需要有一个表来储存这些消息信息。消息信息实体ER图如图1-15所示。

公司每个员工可以对已经发布的消息进行回复,这时就需要一个表来储存这些消息回复消息回复实体E-R图如图1-16所示。

公司的管理层领导可以对已经发布的消息进行批复,这时就需要一个表来储存这些消息批复。消息批复实体ER图如图1-17所示。

1.4.3 数据库逻辑结构设计

根据设计好的各实体E-R图创建数据库的逻辑结构,数据库各表的结构如下。

员工信息表

(1)员工信息表用来储存员工的基本信息,如员工编号、员工姓名、员工性别、出生日期以及办公室电话等信息,该表的逻辑结构如表1-1所示。

字段名 数据类型 是否主键 描述
employeeID 整数(int) 员工编号
employeeName 文本(varchar) 员工姓名
employeeSex 位(bit) 员工性别
employeeBirth 日期(date) 出生日期
employeePhone 文本(varchar) 办公室电话
employeePlace 文本(varchar) 住址
joinTime 日期date) 录入时间
password 文本(varchar) 系统口令
isLead 位(bit) 是否为管理层领导

消息信息表

(2)消息信息表用来储存发布消息的信息,如消息ID、消息标题、消息内容、发布人以及发布时间,该表的逻辑结构如表1-2所示

字段名 数据类型 是否主键 描述
messageID 整数(int) 是(自动递增) 消息ID
messageTitle 文本(varchar) 消息标题
messageContent 文本(Text) 消息内容
employeeID 整数(int) 否(外键) 发布人
publishTime 日期时间(datetime) 发布时间

消息回复表

(3)消息回复表用来储存消息的回复信息,如消息回复ID、回复内容、回复人、回复时间以及消息ID,该表的逻辑结构如表1-3所示

字段名 数据类型 是否主键 描述
replyID 整数(int) 是(自动递增) 消息回复ID
replyContent 文本(Text 回复内容
employeeID 整数(int) 否(外键) 回复人
replyTime 日期时间(datetime) 回复时间
messageID 整数(int) 否(外键) 消息ID

消息批复表

(4)消息批复表用来储存消息的批复信息,如消息批复⑩D、批复内容、批复人、批复时间以及消息ID,该表的逻辑结构如表1-4所示。

字段名 数据类型 是否主键 描述
criticismID 整数(int) 是(自动递增) 消息批复ID
criticismContent 文本(Tex) 批复内容
employeeID 整数(int) 否(外键) 批复人
criticismTime 日期时间(datetime) 批复时间
messageID 整数(int) 否(外键) 消息ID

1.4.4 绘制表之间关系ER图

根据各表关系绘制关系ER图如图1-18所示。