Java 数学学习手册(一)
一、介绍
市场上有很多好的 Java 编程书籍,但是对于一个刚接触 Java 并且只有很少编程知识的初学者来说,找到一本合适的并不容易。
这本书将帮助初学者学习如何有效地用 Java 编程。我的意图是简化 Java 更复杂的方面,并指导学习者探索“幕后”的东西我希望这本书里面的说明足够直观,读者可以通过实践来理解。
有编程经验的人都明白,数学知识在程序设计中起着至关重要的作用。所以拥有良好的数学功底在学习编程的时候无疑是超级有帮助的。这本书提供了一个在编程环境中练习数学问题解决的好机会。带着这个动机,我加入了一些适用于编程相关概念的数学练习题。
通过有意识的练习来学习可以在更深的层次上增强你对新概念的理解。积极参与动手项目是学习过程中的一个重要部分。更多的练习会更快产生效果。我希望这对你来说是一次愉快的学习经历。
编程工作包括使用某种计算机语言设计和编写代码。正确执行的代码将执行重复的任务并完成预期的目标。如今,随着高科技产品融入我们的日常生活,计算机编程技能几乎在任何地方都变得不可或缺。许多日常计算工作已经被编程设备所取代——除了当地超市的自助结账队伍或不断增加的网上购物数量,你不需要看得太远。重复发生的事件越来越多地由自动化系统控制,如建筑安全系统、安装在你房子里墙上的恒温器,以及许多其他例子。
另一个例子是游戏软件,它有如此丰富的用户界面,以至于我们许多人——从青少年到成年人——都已经沉迷其中。所有这些产品和服务本质上都是由计算机编程构建的。
随着人工智能之美的出现,我们已经比以往任何时候都更能看到和感受到计算机技术应用的力量。如果你看过好莱坞电影,比如《抵达》或【乘客】(均于 2016 年上映),我相信你会被电影中描绘的智能机器人迷住。如果你对计算机如何精确识别任何图片中的活动对象感到好奇,我建议你听一听一个激动人心的 TED 演讲,题为“我们如何教计算机理解图片”。所有这些令人惊讶的事情都是由软件实现的,软件是用编程语言编写的。
要成为一名优秀的程序员,你需要了解逻辑控制和基本的计数方法。如果你想开发一个系统来控制对象的活动,这将需要更复杂的数学知识。
数学史上有相当多著名但尚未解决的问题。随着计算机技术的进步,我们可以利用计算机的才能来解决这些问题。
例如,Collatz 猜想指出,如果你随机挑选一个正整数 N,如果它是偶数,除以 2;如果是奇数,就乘以 3 再加 1。如果你重复这个过程足够长的时间,最终 N 的最终结果总是 1。
数学家和数据研究人员尝试了数百万个数字。没有发现例外,但是没有人找到证明所有整数都遵循这个规律的方法。
利用简单的 Java 编程,我们可以证明任意正整数到 n 的 Collatz 猜想,在下面的短程序中,我将用每一个整数来检验这个猜想,找出它的序列长度,也就是它达到结果“1”的运算次数。
public class ProveIt {
public static void main(String[] args) {
// representation of a million
final long N = 1000 * 1000;
for(long i = 1; i <= N; i++) {
System.out.println("i=" + i + " - " +
GetCollatzSequenceCount(i));
}
System.out.println("DONE!");
}
private static long GetCollatzSequenceCount(long n) {
if (n <= 0) return 0;
long count = 0;
while(true) {
if (n == 1) return count;
if (n % 2 == 0) {
n /= 2;
} else {
n = n * 3 + 1;
}
count++;
}
}
}
你猜怎么着?为了测试多达 1,000,000 个整数,它在普通工作笔记本电脑上几秒钟内完成执行并报告结果。现在不要担心理解或运行这段代码;要知道,这个短程序可以在几秒钟内完成 100 万次迭代。
输出的最后一部分是:
i=999991 - 165
i=999992 - 113
i=999993 - 165
i=999994 - 113
i=999995 - 258
i=999996 - 113
i=999997 - 113
i=999998 - 258
i=999999 - 258
i=1000000 - 152
DONE!
关于本书中的符号还有最后一件事要提:
-
数学 :描述一个具体的数学概念。
-
问题 :提供后续练习列表。可以找到一些问题的提示。
-
提示 :为参考解决问题建议思路。
-
最后,鼓励学生尝试 实验室工作后学习 答案例题*** 。*
*## 问题
-
列举一个你观察到的同时满足以下(a)和(b)的例子。
-
现在没有与之相关的编程功能。
-
如果有一个内置程序,它的运行效率会高得多。
-
-
我们如何在两个杯子之间交换不同类型的水?
不允许你掺水。
- 我在考虑 1 到 100 之间的一个整数。你可以问我一些问题来确定这个整数,但是你不能问类似“这个整数是什么?”
为了算出数字,你问最少数量问题的策略是什么?
-
有 27 个乒乓球。它们看起来都一样,重量也一样,除了其中一个更轻。使用天平,您如何快速找到与其他产品不同的产品?
-
如何使用以下四个数字和基本运算符(“+”、“-”、“x”和“/”)来创建一个等于 24 的数学公式?每个数字只能使用一次,但可以使用括号。
*
二、数字基础
什么是数制?
存在许多不同的数字系统,因为有特定的用途,其中某个数字系统使用起来更方便,并且比其他数字系统更有优势。例如:
-
重量:1 磅= 16 盎司
-
长度:1 码= 3 英尺,1 英尺= 12 英寸
-
巴比伦数字:基数 60
(来自维基百科)
- 在中国古代:阴阳——二进制,八卦——八卦图
(来自维基百科)
-
十进制计数
- 十个符号:0–9
-
二进制计数
- 两个符号:0 和 1
-
时间测量
一天= 24 小时
一小时= 60 分钟= 3600 秒
为什么人用十进制数,而计算机用二进制数?
一个简单的答案是,人类有十个手指和十个脚趾,而计算机只有两种状态。
开玩笑地说,计算机是由许多连接和组件(部件)组成的,用于传输和存储数据,以及与其他组件通信。大多数存储、传输和通信事件都发生在数字电子设备中。数字电子设备使用二进制系统(开或关)。具有一系列开/关脉冲的信号等于一个二进制数。
如何在不同的数字系统之间转换数字
【数学】十进制和二进制之间的转换:
-
将十进制数转换成二进制数
[示例]
将基数为 10 的 350 转换为二进制数(基数为 2)
[回答]
以 10 为基数,我们可以用这个等式写出 350:
350 = 3 * 102+5 * 101+0 * 100
请注意,每个系数(即 3、5 和 0)都小于 10,并且没有 10 3 或以上的系数。
现在我们想把它改成这样:
350 = a * 28+b * 27+c * 26+d * 25+e * 24+f * 23+g * 22+h * 21+I * 20
注意没有 2 9 或以上,因为我们知道 350 < 512=2 9
350–1 * 256(即 28)= 94<128 = 27
a = 1,b = 0;
94–1 * 64(即 26)= 30<32 = 25
c = 1,d = 0;
30–1 * 16(即 24)= 14
e = 1;
14–1 * 8(即 23)= 6
f = 1;
6–1 * 4(即 22)= 2
g = 1;
2–1 * 2(即 2 1 ) = 0
h = 1,I = 0;
所以 350 = 1 * 28+0 * 27+1 * 26+0 * 25+1 * 24+1 * 23+1 * 22+1 * 21+0 * 20
也就是说(350)10=(101011110)2
下标数字(10 和 2)表示它的基数。
-
将二进制数转换成十进制数
[示例]
将二进制数 11001001 转换为十进制数
【回答】
我们重写了二进制数的表达式,如下所示。
(11001001) 2
= 1 * 27+1 * 26+0 * 25+0 * 24+1 * 23+0 * 22+0 * 21+1 * 20
= 128 + 64 + 8 + 1
= (201) 10
要练习十进制和二进制的转换,我推荐这个网游:
games . pen JEE . com/binary-numbers-game/
【数学】十进制和二进制的分数
-
将十进制数(基数为 10)转换为二进制数
我们需要了解如何识别小数点后的每一位数字。例如,4.3256
去掉整数部分“4”,我们得到 0.3256。
0.3256 x 10 = 3.256
3 是小数点后的第一位数字
删除整数部分“3”,所以我们现在有 0.256
0.256 x 10 = 2.56
2 是小数点后的第二位数字
去掉整数部分“2”,所以我们现在有 0.56
0.56 x 10 = 5.6
5 是小数点后的第三位数字
去掉整数部分“5”,所以我们现在有 0.6
0.6 x 10 = 6
6 是小数点后的第四位数字
去掉整数部分“6”,我们就完成了。
当我们把一个分数从十进制转换成二进制时,同样的过程也适用。
“4.3256”的整数部分是“4”,在二进制中是 100。
从现在开始,我们只看小数部分。
0.3256 x 2 = 0.6512
0 是小数点后的第一位数字
0.6512 x 2 = 1.3024
1 是第二位数字
0.3024 x 2 = 0.6048
0 是第三位数字
0.6048 x 2 = 1.2096
1 是第 4 位数字
0.2096 x 2 = 0.4192
0 是第 5 位数字
0.4192 x 2 = 0.8392
0 是第 6 位数字
0.8392 x 2 = 1.6784
1 是第 7 位数字
……
重复,直到我们最终得到 0,或者我们看到一个重复的模式。
(100.0101001…) 2 为最终答案。
【数学】二进制算术:加、减、乘、除、平方根
二进制加法和减法运算遵循如下规则:
0 + 0 = 0
0 - 0 = 0
0 + 1 = 1
1 - 0 = 1
1 + 0 = 1
1 + 1 = 0(进位 1)= 10
10-1 = 1
注意
与我们熟悉的十进制数字系统(也称为以 10 为基数的数字)相反,二进制数字以 2 为基数,每一位只有 0 或 1 来表示。在加法运算中,当任何一个数字达到 2 时,它的左边数字就变成“进位 1”。然而,在减法运算中,一个数字 0 需要从它的左边数字借 2 来减去 1。然而,这是与“进位”相反的操作方向
二进制乘法和除法运算遵循如下规则:
-
0 x 0 = 0
-
0 x 1 = 0
-
1 x 0 = 0
-
1 x 1 = 1
这是二进制数除法的一个例子。
-
11__
-
- 1011
-
−11_
-
101
-
−11
-
10
余数(r)
二进制和其他数字系统之间的转换:
- 十六进制-以 16 为基数的数字系统
十进制和十六进制之间的映射:
|十六进制:
|
Zero
|
one
|
Two
|
three
|
four
|
five
|
six
|
seven
|
eight
|
nine
|
A
|
B
|
C
|
D
|
E
|
F
| | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | | 十进制: | Zero | one | Two | three | four | five | six | seven | eight | nine | Ten | Eleven | Twelve | Thirteen | Fourteen | Fifteen |
由于二进制中的每四个数字构成一个十六进制数字,为了将二进制数转换为十六进制数,我们从右开始对二进制中的每四个数字进行分组。
比如二进制的 100 等于十六进制的 4,二进制的 1011 等于十六进制的 8 + 2 + 1 = B。所以二进制的 1001011,十六进制就是 4B。
- 八进制-以 8 为基数的数字系统
二进制中的每三个数字组成一个八进制数字。我们可以将二进制中的每三个数字从最右边开始分组,并将其转换为八进制形式。
例如,
要将二进制的 10111011 转换为八进制的结果:
第一步——从右起每三位数分组:(10)2(111)2(011)2;
第二步——将每组最多三位数(0 到 1)转换为一个八进制数(0 到 7):(2)8(7)8(3)8;
步骤 3 -转换后的八进制结果是 273 8 。
相反,要将八进制的 273 转换为二进制格式,我们将每个八进制数字转换为三位二进制数字:
- 2738=(2)8(7)8(3)8=(010)2(111)2(011)2= 0101110112
什么是比特、字节、KB、MB、GB、TB、PB?
位表示二进制数字,0 或 1。它是数据的最小单位。
字节是八位的序列。
1 字节(= 8 位)、KB、MB、GB、TB、PB
| 1024 字节= 1 KB | KB:千字节 | | 1024 kb = 1mb | 兆字节 | | 1,024 MB = 1 GB | GB:千兆字节 | | 1.024 GB = 1 TB | TB:TB:TB | | 1,024 TB = 1 PB | PB:PB |什么是按位?
在计算机中,一个整数在内存中被表示为一个比特序列。我们通常通过计算机的图形用户界面与显示器上的十进制数字进行交互。然而,它的二进制形式在计算机内部执行实际的计算。按位只是涉及处理单个位的一级运算。
按位运算符包含三种基本运算符:
& 还有
-
0 & 0 = 0 & 1 = 1 & 0 = 0
-
1 & 1 = 1
-
如果第一位为 1,第二位为 1,则每个位对的逻辑与(&)结果为 1。否则,结果为零。
-
示例:
-
01 & 00 = 00
-
11111111 & 01100101 = 01100101
| 或者
-
否则,结果为零。
-
示例:
-
0101 | 0011 = 0111
-
0010 | 1000 = 1010
-
如果第一位是 1 或者第二位是 1。
-
或者,如果第一位和第二位都是 1。
-
0 | 0 = 0
-
0 | 1 = 1 | 0 = 1 | 1 = 1
-
每个位对的逻辑或(|)导致 1,
^ 没有
-
一元运算对每个位执行逻辑否定。
-
换句话说,在这个操作之后,1 位被翻转为 0 位,0 位被翻转为 1 位。
-
示例:
-
^ 0011 = 1100
-
^ 01010110 = 10101001
问题
-
为什么计算机使用二进制数?
-
十六进制、八进制和按位是什么意思?
三、Java 基础
今天,计算机使用如此多不同种类的编程语言。它们中的每一个都在解决特定类型的问题的某个领域中起着重要的作用。Java 是 Sun Microsystems 在 90 年代初发明开发的;经过 20 年的发展,Java 现在已经成为世界上最流行的编程语言之一。
Java 是一种典型的面向对象编程语言,也称为面向对象编程语言,它处理一堆“对象”这些对象包含数据和操作。操作是关于可以对对象中的数据做什么。
在 Java 世界中,有一种开源开发工具叫做 Eclipse。它有丰富的功能,并且可以免费使用。Eclipse 也是一个适合初学者的工具。我们将使用 Eclipse 开始探索 Java 世界。
Java 有什么特点?
面向对象
对象是具有某些属性的“东西”(也称为特性)。该对象执行一组操作(也称为方法)。这些操作定义了对象的行为。
基于类
一个类仅仅是一种对象的代表。它是描述对象细节的模板。一个类由三个元素组成:名称、属性和操作。
Java 位元组码
Java 字节码是 Java 虚拟机(JVM)的机器语言。当 Java 字节码在机器上运行时,它将被 JVM 翻译成特定于机器的本机代码。因此,在 Windows 计算机上,JVM 字节码被翻译成特定于 Windows 的本机代码;在 Linux 计算机上,它被翻译成特定于 Linux 的本机代码。这被称为一次写入,随处运行(如图 3-1 所示)。
图 3-1
一次编写,随处运行
当 JVM 加载一个类文件时,它为类中的每个方法获得一个字节码流。当一个方法在程序执行期间被调用时,该方法的字节码被执行。
尽管这对初学者来说可能有些难以理解,但我们还是想介绍一些内置于 Java 语言及其运行时引擎中的其他强大特性。
-
多线程
Java 语言支持多线程功能,这使得多个任务可以同时运行。这个特性增强了 Java 代码的计算能力,并使 Java 应用程序具有很高的响应能力。
-
安全代码
Java 不像其他语言(如 C 或 C++)那样使用指针。这避免了传统的安全漏洞。除了运行时检查,Java 还在编译期间使用严格的规则进行静态类型检查。Java 有它的异常处理来捕捉意外的错误。当用户通过网络等获取代码时,Java 提供了一种加密安全机制。这些安全功能使 Java 成为比其他语言更安全的编程语言。
-
碎片帐集
Java 有自己独特设计的内存管理机制。与 C/C++语言不同,Java 不要求开发人员根据何时注册或释放内存来管理内存。它会自动收集并释放未使用的内存。这使得开发工作变得更加容易。
最后要提到的但并非最不重要的强大特性是 Java 极其丰富的开源库。这是 Java 越来越受开发人员欢迎的一个重要原因。而且,因为 Java 的开发者社区正在变得越来越强大,随着时间的推移,Java 将会发展成为一种更加强大的编程语言。
四、开始玩 Java 吧
下载并安装一个 Java 运行时环境(根据你电脑的操作系统选择合适的版本): https://www.java.com/en/download/manual.jsp
下载安装 Eclipse(寻找最近的稳定版本): http://www.eclipse.org/downloads/
安装后,您应该会在桌面上看到一个图标,如图所示——“Neon”版本。
一旦您启动 Eclipse,您将需要指定工作空间(图 4-1 )。
图 4-1
指定工作空间
JRE 和 JDK 有什么区别?
JRE 是“Java 运行时环境”。它是你的 Java 程序运行的地方。JDK 是“Java 开发工具包”,它是 Java 的全功能软件开发工具包,包括 JRE、编译器和用于创建和编译程序的工具(例如 JavaDoc、Java 调试器)。
当您只想在浏览器或计算机上运行 Java 程序时,您将安装 JRE。但是如果你想做一些 Java 编程,你还需要安装 JDK。
图 4-2 显示了 JRE 和 JDK 之间的清晰关系,以及它们的基本特征区域。
图 4-2
JDK 和 JRE 比较
什么是工作空间、源代码和包?
“工作区”用于将一组相关的项目组合在一起。通常这些项目会组成一个应用程序。
“源代码”是指源代码,即 Java 程序和相关代码。
“包”表示文件的集合。
什么是编辑、编译和执行?
“编辑”用 Java 语言编写代码。
“编译”将 Java 源代码转换成 Java 字节码。
“执行”运行程序。
-
编辑
创建
*.java文件 -
编译
生成
*.class文件
创建您的第一个程序
让我们开始吧:
-
Once Eclipse is launched, left-click on “File” in the top menu bar and left-click on “New” in the drop-down menu. Then select “Java Project” from another drop-down menu as shown in Figure 4-3.
图 4-3
在我们创建 Java 项目或 Java 类之前
-
Now create a Java project named
MyFirstProgram, as shown in Figure 4-4. Click “Finish.”图 4-4
创建 Java 项目
-
Select File ➤ New ➤ Class to create a Java class (name: “
Welcome”), as shown in Figure 4-5. Make sure you select “public static void main(String[] args).” Click on “Finish.”图 4-5
创建 Java 类
-
自动创建
Welcome类和public static void main(String[] args)方法,如图 4-6 所示。然后手动添加以下输出行: -
Click on “Run” from the top menu bar, and then click on “Run” from its drop-down menu, we will see output text in the Console window as shown in Figure 4-6.
图 4-6
运行应用程序
System.out.println("Hello, friend, you are welcome!");
探索类和 main()
正如你在第三章中看到的,“类”是一个模板,它描述了一个对象应该显示的行为。您可以从类中创建单个对象。这被称为“类实例化”一个类有局部变量、实例变量、类变量和许多方法。
main()是一个方法名。当您的 Java 程序被执行时,运行时通过首先调用它的main()方法来启动您的程序。main()方法是 Java 程序的一个入口点。
为什么是“public static void main(String[]args)”。
这是由 Java 语言和 JVM 设计的一个约定(如果其中一些没有意义,请不要担心,我们将在本书的后面回到它)。
-
main是方法的名称; -
String[] args是将main()方法输入的参数作为字符串数组的数据类型;传递给main()方法的字符串值称为参数;它们可以作为可选值,在程序启动时发送给程序; -
void表示main()方法调用没有返回数据; -
public表示main()方法可供 JVM 调用,以启动整个程序的执行; -
static表示不能用对象实例调用main()方法;换句话说,JVM 可以直接调用它,而不必创建额外的结构来调用它。
如果您将public更改为private,您将在运行时看到以下错误。
Error: Main method not found in class <your class name>, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
问题
-
Something.java档和Something.class档有什么区别?-
一个
.java文件是一个大得多的二进制文件,而一个.class文件是一个较小的压缩版本。 -
.class文件用于面向对象编程,而.java文件用于过程编程。 -
一个
.java文件包含用 Java 语言编写的代码,一个.class文件包含用 C++语言编写的代码。 -
程序员先写
.class文件,后面自动生成.java文件。 -
Something.java是程序员打出的源代码文件,Something.class是编译好的可执行类文件,由计算机运行。
-
-
下面哪个方法头是正确的?
-
public static foo void[] -
public static void foo() -
public void static foo{} -
public void static foo() -
public static foo()
-
五、变量
一个变量是:
-
存储的位置
-
存储某种信息供以后使用的容器
-
可通过引用描述所述信息的名称来检索
有不同类型的变量:
-
局部变量
它们是仅在局部范围内有效的变量,例如在方法内部或代码块内部。
-
类变量和实例变量
我们将在后面的章节中学习基本的类概念时看到例子。类变量定义类字段和属性的数据类型。当从一个类创建一个对象时,该对象的类变量成为实例变量。类变量和实例变量都在类中声明,但是它们不属于该类的任何方法。
-
方法参数
参数也是变量,用于将值从方法外部传递到方法中。
定义变量名
变量名:
-
不能以数字或某些特殊符号开头,如引号(
")或类似于)的括号等。,但可以以下划线(_)或美元符号($)开头。 -
不能是该语言中已经使用的任何关键字,也称为保留字,例如,
if、else等。
例子
以下哪一项可以在 Java 程序中用作标识符?答案不止一个。
-
ABC -
B4 -
24isThesolution -
"hello" -
AnnualSalary -
_average -
for -
sum_of_data -
first-name -
println
答案:1、2、5、6、8 和 10
您可以键入如图 5-1 所示的简单代码来检查哪些字符串不适合变量名,因为在 Eclipse 的 Java 代码编辑器中,所有语法错误都用红色下划线标出。
图 5-1
突出显示错误
Java 中不同类型的变量
变量的类型将定义数据的类型以及它们存储在变量中时的大小。Java 提供了八种基本的数据类型。Java 还支持非原始数据类型的引用或对象数据类型。
原始类型:
-
int -
long -
short -
float -
double -
char -
byte -
boolean
参考类型:
-
String -
对象、数组等等
当我们在程序中声明一个变量时,我们实际上是在计算机的内存中为操作预留了空间。有必要了解常见的数据类型及其占用的内存空间。此表显示了数据类型、它们的位(和字节)大小以及它们所代表的值类型的列表。
|类型
|
位数
|
价值
| | --- | --- | --- | | (同 Internationalorganizations)国际组织 | 32 位元(= 4 位元组) | 整数 | | 短的 | 16 位(= 2 字节) | 整数 | | 长的 | 64 位元(= 8 位元组) | 整数 | | 字节 | 8 位(= 1 字节) | 整数 | | 漂浮物 | 32 位元(= 4 位元组) | 浮点 | | 两倍 | 64 位元(= 8 位元组) | 浮点 | | 茶 | 16 位(= 2 字节) | unicode 字符 | | 布尔 | 见下文 | 对/错 |
对于布尔数据类型,只有两个不同的值,true或false。一个小小的空间似乎正合适。事实上,Java 实际上为布尔数据类型准备了至少一个字节的空间,尽管它只使用了一位的空间。确切地说,它没有明确定义,因为它将依赖于平台的虚拟机。
给变量赋值
以下是如何将值或内容分配给特定类型的变量:
int number1 = 3;
int number2 = 7;
int total = number1 + number2;
boolean flag = true;
String a = "welcome";
String b = "my friend";
String c = a + b;
然后,您可以使用下面的方法来显示和验证变量的当前值。例如,这一行将显示字符串变量c的当前值:
System.out.println(c);
实验室工作
参照我们创建的第一个程序,按照描述使用System.out.println()语句;编译并运行它;然后在控制台窗口中,验证每个操作后每个变量的结果值。
基本数学运算:
int number = 9 / 8;
double number = 9 / 8;
有序的数学运算:
int number = 6 + 8 * 5;
int number = (6 – 8) * (5 + 3);
六、第一个算法
今天有许多不同类型的算法在计算机上运行。算法定义了计算机需要遵循来解决特定问题的一组指令。智能和高性能的算法导致精确和高效的工作结果。
接下来是一个使用真实对象创建算法的示例。在这里,我们将看看如何在两个相同大小的容器之间交换不同种类的水(淡水和海水)。根据常识,我们知道使用第三个同样大小的空容器。以下是完成这项工作需要采取的一系列行动:
-
将容器 A 中的淡水倒入容器 C(空的);
-
将海水从容器 B 倒入容器 A;
-
将 C 容器中的淡水倒入 b 容器,任务完成。
从这张表中你可以看到每个容器中的水在每一步之后是如何变化的。
| |操作
|
容器
|
容器
|
容器
|
| --- | --- | --- | --- | --- |
| 开始 | 介绍 | 淡水 | 海水 | 空的 |
| 在步骤 1 之后 | A C | 淡水->空的 | 海水 | 空->淡水 |
| 在步骤 2 之后 | B
A | 空->海水 | 海水->空的 | 淡水 |
| 在步骤 3 之后 | C
B | 海水 | 空->淡水 | 淡水->空的 |
在许多程序中,我们经常会遇到需要将一个变量的值设置为另一个变量的值的情况。让我们应用从上一个例子中学到的相同逻辑来交换两个变量之间的值。换句话说,我们将实现我们之前定义的算法。
在变量之间交换值
假设两个整数,a = 5和b = 4。我们想改变他们的价值观,使其成为a = 4和b = 5。按照下表中列出的操作顺序,变量a和b中的值将被切换。
步骤
|
操作
|
a
|
b
|
c
|
| --- | --- | --- | --- | --- |
| 0 | int a = 5; int b = 4; | five | four | |
| 1 | int c = a; | five | four | five |
| 2 | a = b; | four | four | five |
| 3 | b = c; | four | five | five |
其他方法
您可以使用其他方法在两个整数之间交换值,而不使用临时变量。一种方法是利用+和–运算符来交换值:
-
a = a + b;现在
a = 9, b = 4 -
b = a – b;现在
a = 9, b = 5 -
a = a – b;现在
a = 4, b = 5
成功完成!
七、输入和输出
在计算机程序的运行期间,程序可以要求用户输入数据,读取用户的输入,然后向用户显示输出结果。Scanner是我们用来在控制台窗口上实现用户交互功能的工具。
导入 java.util.Scanner
在一个包中预定义了Scanner实用程序类及其方法。我们使用import语句将Scanner类与我们正在创建的程序集成在一起。
-
方法 1。在 Java 代码的顶部添加第
import java.util.Scanner;行,然后在main()类中添加以下内容: -
方法 2。直接在 Java 代码中键入代码
Scanner input = new Scanner(System.in);,然后使用 Eclipse 的智能感知来选择正确的修复。换句话说,Eclipse 将建议您添加import语句,因为它发现您可能需要它。因此,
import java.util.Scanner;将被添加到类的顶部。
Scanner input = new Scanner(System.in);
获取输入
从程序中读取用户输入数据有几种方法:
-
nextLine():读取一个字符串输入
-
next():读取一个字符串输入
-
nextInt():读取整数输入
-
nextFloat():读取浮点数输入
nextLine()和next()有什么区别?
-
next()只读取输入,直到空格。
它不能阅读由空格分开的两个单词。在读取输入流后,它将光标放在同一行,这意味着它不会改变行。
-
nextLine()读取输入直到行尾('
\n')。它会在返回当前行后自动向下移动扫描仪。
生产产量
System.out.println是在控制台窗口中显示文本的常用方式。开发人员通常使用它来读取用户的输入,向用户提供一般信息,并在运行时记录信息(到控制台),以便找出关键变量的情况。
我们经常使用以下特殊字符(即转义字符)来控制输出格式:
-
+:连接两个字符串; -
\n:换行符; -
\t:在制表符宽度对齐文本的制表符; -
\\:反斜杠字符; -
\r:回车符; -
\"和\":双引号字符。
这里有一个例子:
System.out.println("This demonstrates " + "\"how to display a table format\".\n");
System.out.println("123\t45\t6789\nab\tcde\tf");
这将生成以下输出:
This demonstrates "how to display a table format".
123 45 6789
ab cde f
实验室工作
练习使用语句System.out.println()来:
-
使用
+显示两个子字符串“我是”和“一名开发人员”之间的字符串连接 -
显示新行
-
使用
\"和\"显示报价
例子
以下哪一项是输出消息的正确语法?
-
System.out.println("Hello, world!"); -
System.println.out('Hello, world!'); -
System.println("Hello, world!"); -
System.println(Hello, world!); -
Out.system.println"(Hello, world!)";
答案:1
例子
下列语句的输出是什么?
System.out.println("\"Quotes\"");
System.out.println("Forward slashes \\//");
System.out.println("How '\"profound' \"\\\" it is!");
回答:
"Quotes"
Forward slashes \//
How '"profound' "\" it is!
实验室工作
以下程序的输出是什么?如果我们把next()换成nextLine()会怎么样?
public class TestScanner {
public static void main(String arg[]) {
Scanner sc=new Scanner(System.in);
System.out.println("enter string for c");
String c=sc.next();
System.out.println("c is "+c);
System.out.println("enter string for d");
String d=sc.next();
System.out.println("d is "+d);
}
}
问题
-
以下语句的输出是什么?
System.out.println("name\tage\theight"); System.out.println("Anthony\t17\t5'9\""); System.out.println("Belly\t17\t5'6\""); System.out.println("Bighead\t16\t6'"); -
以下语句的输出是什么?
System.out.println("\ta\tb\tc"); System.out.println("\\\\"); System.out.println("'"); System.out.println("\"\"\""); -
用 Java 写一个程序打印以下内容:
\/ \\// \\\///
八、循环结构——for循环
简单来说,循环结构重复做一些事情,直到状态改变(见图 8-1 )。
图 8-1
for 循环结构
例子
这里有一个例子:
for (int i = 0; i < 100; i++) {
<do something>
}
for陈述中有三个关键要素:
-
int i = 0:声明一个计数器变量,并给它赋一个初始值; -
i < 100:定义继续for循环的条件;只要这个条件为真,循环就会运行,当它不为真时,我们停止并退出for循环; -
i++:递增计数器值;i++和i = i + 1.是一回事
那么,“”在上面的代码中会重复多少次呢?
实验室工作
-
使用
for循环输出“Hello!”10 次。 -
使用
for循环打印出从 1 到 25 的所有整数,包括 1 和 25。 -
打印出从 1 到 25 的所有整数。
-
输出从 3 到 99 的所有偶数。
for 循环公式
for循环背后的数学模型实际上是一个算术序列:
for (int counter=firstTerm;
counter <= lastTerm;
counter=counter + difference) {
......
}
counter系列中的第 n 项等于:
- 第一项+差值×(n–1)
求算术数列的“for 循环”公式
例如,下面是一个数字列表:
-
-4, 5, 14, 23, 32, 41, 50, 59, 68, 77, 86.
-
它遵循一个算术序列。
-
firstItem = -4
-
lastItem = 86
-
差值= 5-(-4)= 9
-
将此转化为一个
for循环:
for(int i=-4; i <= 86; i=i+9) { ...... }
它将遍历列表中的每一个数字。
数学:战略计数
你可以用手指数,但是当你的数列中有非常多的数字时,那就没用了。正确的做法是通过重组来准备这些数字。目的是找到一个好的模式,以便我们可以系统地计数。
在这里寻找一个模式就是找出一个代表数列中每个数字的基本公式。
看看这个例子:3,4,5,6,....,100,所以我们知道数字的总数是:
- 100 – 3 + 1 = 98.
一种常见的方法是将数列转换成更简单的形式。如果我们从数列的每个数字中减去 2,我们得到 1,2,3,4,......, 98.我们现在知道总数是 98。并且,表示每个数的公式将是 x(i) = i + 2,(i=1,2,......,98).
那 5,8,11,14 呢,......, 101?怎么用“for循环”把它打印出来?
它看起来比上一个更复杂,但您可以尝试相同的方法。
-
每个数字减 5;它变成了 0,3,6,9,......, 96
-
除以 3,它就变成 0,1,2,3,......, 32
-
从 0 开始,一个一个数,一直数到 32,并不难。总数是 33。
-
数列中第 I 个数的通称将是 x(i) = 3 * i + 5,(i=0,1,2,......, 32).
现在,回到for循环结构,很明显答案应该是这样的:
for (i=0; i <= 32; i++) {
System.out.println(3 * i + 5);
}
实验室工作
-
编写一个
for循环,生成以下数字列表:1 4 9 16 25 36 49 64 81 100
(提示:寻找一个共同的模式。)
例子
以下循环序列的输出是什么?
它打印出以下内容:
****!****!****!
****!****!****!
外部for循环(标记为“1”)有两次迭代,因此输出将有两行,由println()。
中间的for循环(标记为“2”)有三次迭代,所以它将打印出 2 x 3 = 6“!”总计通过print()。
内部的for循环(标记为“3”)有四次迭代,所以print()总共会打印出 2×3×4 = 24 个*。
实验室工作
- 写一个方法
exp()来计算一个指数结果,给定一个基数和一个幂(也叫指数)。例如,exp(3, 4)返回 81。限制是基数和指数不能为负。
问题
-
以下循环序列的输出是什么?
for (int i = 1; i <= 2; i++) { for (int j = 1; j <= 3; j++) { System.out.print(i + ""*"" + j + ""= "" + i * j + ""; "); } System.out.println(); } -
编写一个
for循环,生成以下数字列表:5 10 17 26 37 50
-
编写一个
for循环,生成以下数字列表:1 8 27 64 125
-
编写一个
for循环,生成以下数字列表:-1 0 7 26 63 124
-
使用
for循环产生以下输出:***** ***** ***** ***** -
编写
for循环代码,输出以下内容:one
Twenty-two
Three hundred and thirty-three
Four thousand four hundred and forty-four
九、循环结构——while循环
这是循环结构的另一种方式(图 9-1 )。
图 9-1
while 循环
while(i == 0) {
<do something>; //the variable "i" may be updated in this code block.
}
可以在“做某事”过程中更新状态。
问:如果状态永远不变,会发生什么?
答:这将是一个“无限循环”,意味着程序将永远运行,直到它崩溃或被用户终止。
注意
你可能注意到了<do something>线旁边的//。这标识了开发人员留下的注释。你应该使用注释来注释你的代码,以便将来的读者更容易理解(他们可能是你,所以善待你未来的自己)。编译 Java 程序时,编译器会忽略所有注释。
例子
循环会执行它的主体多少次?
int x = 1;
while (x < 100) {
System.out.print(x + " ");
x += 10;
}
答案:十次(当 x = 1,11,21,31,41,51,61,71,81,91 时)
例子
循环会执行它的主体多少次?
int max = 10;
while (max < 10) {
System.out.println("count down: " + max);
max--;
}
答案:零。
for循环和while循环都是完成重复工作的循环结构(即<做某事>)。for循环提供了一种简单的方法来分配初始计数器值,并定义计数器值如何在同一行代码中递增(或递减),而while循环要求用户在单独的行中定义它们。以下两个示例具有相同的功能。
for(int i = 0; i < 10; i++) {
<do something>
}
int i = 0;
while(i < 10) {
<do something>
i++;
}
除了for循环之外,我们需要while循环选项还有一个很好的理由。这个例子显示了我们更喜欢while循环而不是for循环的许多情况之一。
boolean flag = true;
while(flag) {
< commit planned operations
, during which time the flag may be updated upon a certain codition change, e.g. the operation is completed, or failed for some reason.>
}
do-while 循环
Java 还提供了一个do - while循环结构:
do {
<do something>
} while (expression);
do - while和while的区别在于do - while在循环的底部而不是顶部对其布尔表达式求值。因此,do块(又名)中的语句总是至少执行一次。您可以尝试以下程序来观看演示。
class DoWhileDemo {
public static void main(String[] args){
int count = 1;
do {
System.out.println("Count is: " + count);
count++;
} while (count < 1);
}
}
实验室工作
-
使用
while循环输出“Hello!”10 次。 -
使用
while循环打印出从 1 到 25 的所有整数,包括 1 和 25。 -
解释下面的代码片段试图做什么。
int n = 5; while (n == 5) { n = n + 1; System.out.println(n); n--; }
问题
-
循环会执行它的主体多少次?
int x = 250; while (x % 3 != 0) { System.out.println(x); } -
循环会执行它的主体多少次?
int x = 2; while (x < 200) { System.out.print(x + " "); x *= x; } -
循环会执行它的主体多少次?
String word = "a"; while (word.length() < 10) { word = "b" + word + "b"; } System.out.println(word); -
循环会执行它的主体多少次?
int x = 100; while (x > 1) { System.out.println(x / 10); x = x / 2; } -
给定静态方法
runWhileLoop(),当x = 10时它的输出是什么?您可能希望将该方法复制到您的测试类中进行尝试。public static void runWhileLoop(int x) { int y = 1; int z = 0; while (2 * y <= x) { y = y * 2; z++; } System.out.println(y + " " + z); }
十、逻辑控制结构
与我们在进行逻辑对话时口头描述的方式非常相似,编程语言中的if和if / else是进行条件决策和选择相应执行路径的常见结构(图 10-1 )。
图 10-1
if 结构
if (a == 3) {
<do something>
}
这类似于但不完全相同,因为:
if (a == 3) {
<do something>
} else {
<do something else>
}
图 10-2 是if / else逻辑控制结构的整个工作流程。
图 10-2
if/else 结构
条件运算符
下表中列出的条件运算符常用于条件语句中。比如我们用a == 3来评价“是否a等于3?”在条件语句中。Java 使用六种不同的条件运算符来表达两个操作数之间的关系。表达式的结果为真或假,这是一个布尔值,它决定了“是”或“否”的执行路径。
条件运算符
|
描述
| | --- | --- | | == | 等于 | | > | 大于 | | >= | 大于或等于 | | < | 小于 | | <= | 小于或等于 | | != | 不等于 |
例子
以下哪个if语句头使用了正确的语法?
-
如果 x = 10,则
-
如果(x 等于 42) {
-
if (x => y) {
-
如果[x == 10] {
-
if (x == y) {
回答
e
例子
给定下面的方法,whatIsIt(9, 4)的输出是什么?
public static void whatIsIt(int x, int y) {
int z = 4;
if (z <= x) {
z = x + 1;
} else {
z = z + 9;
}
if (z <= y) {
y++;
}
System.out.println(z + " " + y);
}
回答
10 4
实验室工作
-
定义一个整数变量,并将值“3”赋给它。
-
当整数变量被赋值为数字 3 时,使用
if语句输出“Hello”。 -
当整数变量被赋值为 3 以外的任何数字时,使用
if/else语句输出“Goodbye”。 -
下面的代码有什么问题吗?
int n = 4; if (n >= 3) { System.out.println("Hello!"); } if (n == 4) { System.out.println("Hello again!"); } -
使用
if/else语句实现以下要求:-
当数字小于 3 时,输出“小于 3”
-
当数字为 3 时,输出“等于 3”
-
当数字大于 3 时,输出“大于 3”
-
-
输入一个整数,然后,
-
当输入的数字大于 6 时,输出“数字大于 6”
-
当输入的数字小于 6 时,输出“数字小于 6”
-
-
解释下面的代码片段试图做什么:
Scanner scan = new Scanner(System.in); int n = scan.nextInt(); if (n > 6) { if (n > 8) { System.out.println("n is greater than 8"); } else { System.out.println("n is greater than 6, but n is smaller than 9"); } }
有时,您可能需要使用多个“真或假”条件的逻辑组合。让我们在这里引入另一个概念,即“逻辑运算符”
逻辑运算符
数学:逻辑运算符
逻辑运算符和逻辑运算:
-
&&
与关系
-
||
或关系
-
!
没有关系
-
A && B
表示只有当 A 和 B 都为真时,结果才为真。比如在(x>3&x<5)中,A 是“x > 3”,B 是“x < 5”。
-
A || B
表示当 A 或 B 为真时,结果为真。
-
!A
表示当 A 为真时,结果为假;当 A 为假时,结果为真。“的例子中(x > 0)”,A 是“x > 0”。
在所有这些例子中,A 和 B 是表达式或布尔变量。
| (甲和乙) | a =真 | a =假 | | b =真 | 真实的 | 错误的 | | b =假 | 错误的 | 错误的 |Summary -只有当 A 和 B 都为真时,结果才为真。否则,结果为假。
| (甲||乙) | a =真 | a =假 | | b =真 | 真实的 | 真实的 | | b =假 | 真实的 | 错误的 |只有当 A 和 B 都为假时,Summary - Result 才为假。否则,结果为真。
这些运算符的一些属性的最后一个示例:
-
(x< 0 || x >0)
T2【x!= 0)
-
!(x == 0 || y == 0)等价于(x!= 0 && y!= 0)
-
!(x > 3 && x < 5) is equivalent to (x > = 5 || x <=3)
使用文氏图将有助于我们分析某些类型的逻辑问题。
数学:分析逻辑问题
维恩图是揭示数据集之间逻辑关系的可视化方法。
在图 10-3 中,圆 A 和圆 C 的重叠区域在区域 b。
如果我们定义 A = { x,y | x = 0 },C = { x,y | y = 0 },那么 B = { x = 0;y=0 }。
图 10-3
维恩图
实验室工作
-
算出下面程序的输出。
public class LogicalOperation { public static void main(String args[]) { boolean a = true; boolean b = false; System.out.println("a && b = " + (a&&b)); System.out.println("a || b = " + (a||b) ); System.out.println("!(a && b) = " + !(a && b)); } } -
编写一个名为
quadrant的静态方法,该方法将一对表示笛卡尔坐标系上的(x,y)点的整数作为参数。它返回该点的象限号(即 0,1,2,3,4,见图)。
下面是对该方法的示例调用。
|打电话
|
返回值
|
| --- | --- |
| quadrant(12, 17) | 1 |
| quadrant(-2, 3) | 2 |
| quadrant(-15, -3) | 3 |
| quadrant(4, -42) | 4 |
| quadrant(0, 3) | 0 |
问题
-
将下列英语语句翻译成逻辑表达式:
-
z 是奇数。
-
x 是偶数
-
y 为正。
-
x 或者 y 是偶数。
-
y 是 z 的倍数。
-
z 不为零。
-
y 是一个正数,y 在数量级上大于 z。
-
x 和 z 是相反的符号。
-
y 是一个非负的一位数。
-
z 是非负的。
-
-
给定以下变量声明:
int x = 4; int y = -3; int z = 4;下列表达式的结果是什么(对或错)?
x == 4 x == yx == z y == zx + y > 0 x - z != 0y * y <= z y / y == 1x * (y + 2) > y - (y + z) * 2
十一、错误和提示
以下是初学者容易犯的常见编码错误列表。如果你留意这些错误模式,它将帮助你克服最初的编码障碍。
-
缺少半个花括号
{}。(它应该总是有一对。)
-
缺少括号
()的一半。(它也应该总是有一双。)
-
每行结尾缺少分号
;。 -
在条件检查中使用一个
=符号。(正确的做法是
==。) -
给未定义的变量赋值。
(正确的做法是,只有在变量被定义后,才给变量赋值。)
-
多次定义同一个变量。
int i; ...... int i = 3; ...... -
忘记在循环结构中递增/递减计数器。
-
main函数的签名不正确。应该是
public static void main(String[] args,所以注意public static void main,还有String[] args。 -
控制台窗口无输出–缺少输出行,例如
System.out.println()。 -
变量名和字符串的区别:
- 变量名
a是一个字符串。
- 变量名
-
变量名
a是一个值为“a”的字符串。
string a;
-
Mistakenly resetting value in an aggregator:
for (int i=1; i<n; i++) { int sum = 0; sum += i; }这个程序对从 1 到 n 的所有数字求和。为了纠正这个错误,需要将行
int sum = 0移出循环结构,就在行for之前。
string a = "a";
编程技巧
-
如何在文本编辑器上增大/减小字体大小:
使用 Ctrl +或 Ctrl -。
在 macOS 上是⌘+和⌘-
设置:首选项= >常规= >键
-
如何在 Eclipse 中注释掉一段代码:
选择代码块
按 CTRL 和“/”(同时)
在 macOS 上,它是命令+“/”
-
如何在代码块中添加注释:
You may use the Java Comments feature to briefly explain what a specific line of code or a code block in your program is doing so that other people can understand your implementation ideas. There are basically two ways you can write Java Comments among lines of code.
-
使用“//”作为前缀在一行中编写语句,例如:
// count 是跟踪点击总数的变量
int count = 0;
-
使用“/∫”和“∫/”来写多行注释,例如:
/* *
这段代码试图从指定的一组产品中找出最高价格值(以美元为单位):
*/
-
-
编码时注意“彩色下划线”:
红线–错误信息:语法等。
橙色线-警告信息
处理异常
到目前为止,在这一章中,我们已经解释了如何避免犯编译错误检测过程会发现的错误。运行时的那些错误呢?在 Java 中,我们使用下面的结构来捕获它们,并分别处理这些条件。这被称为异常处理。
try {
<main instruction code to execute>
......
} catch(IllegalArgumentException ex) {
<exception handling steps>
}
运行时可能导致错误的代码放在try块中,运行时响应错误的代码放在catch块中。这里的catch块只响应抛出IllegalArgumentException的错误。您可以指定多个catch块来响应运行时抛出的不同类型的异常,因为您可能希望对不同类型的运行时错误做出不同的响应。最后,如果您的代码在运行时检测到一些问题,您可以故意抛出一个错误。你将在第十七章中看到如何做到这一点。
问题
-
下面的程序包含三个错误。纠正错误并提交程序的工作版本。
public MyProgram { public static void main(String[] args) { System.out.println("This is a test of the") System.out.Println("alarming system."); System.out.printLn("Thank you for your attention!") } } -
下面的程序包含四个错误。纠正错误并提交程序的工作版本。
public class FriendMessage { public static main(string[] args) { System.out.println("Speaking plum"); System.out.println("and eat); } -
下面的程序包含至少 10 个错误。纠正错误并提交程序的工作版本。
public class Many Errors { public static main(String args) { System.println(Hello, buddy!); message() } public static void message { System.out println("This program cannot "; System.out.println("have any "errors" in it"); }
十二、Java 基础概要
在这一章中,我们将总结到目前为止我们在 Java 基础领域所学的知识,并指出一些常见的错误。
通则
如何定义变量名
变量名字符串
-
大小写敏感的
-
可以包含数字 0 到 9
-
可以有下划线
_或美元符号$
变量名字符串:
-
不能以数字开头
-
不能使用保留字,如
for、class、void、if、else等。
如何在控制台中输出
-
System.out.print(<string + value>); -
System.out.println(<string + value>);
如何在控制台中收听输入
Scanner input = new Scanner(System.in);
input.nextLine();
input.next();
input.nextInt();
input.nextFloat();
如何重复手术
for(<initial state>; <condition check>; <increment/decrement count>) {
<do something>;
}
while(<condition check>) {
<do something>
}
或者,
do {
<do something>
}
while(<condition check>)
如何控制条件操作
if (<condition check>) {
<do something>;
}
if (<condition check>) {
<do something>;
} else {
<do something else>;
}
if (<condition check>) {
<do something>;
}
else {
<do something else with the nested if/else statement(s)>;
}
基本编码结构
public class MyClass {
public static void main(...) {
myMethod();
}
private static void myMethod(...) {
for (... ; ... ; ...) {
......;
}
if (...) {
......;
}
else {
......;
}
}
}
花括号
-
总是带着一对花括号:“
{......}” -
总是以“{”开头,然后是“}”
-
常见模式(以两对开/关为例)
-
{ { } }
开,开,关,关
-
{ } { }
开,关,开,关
-
{ } } {
错了!
-
} { } {
错了!
-
-
这些模式的基本规则是什么?
-
开始时,以“{”开头
-
最后,以“}”结尾
-
“}”不会多于“{”
-
实验室工作
-
以下程序的输出是什么?
public class StoryOfMethods { public static void main(String[] args) { method1(); method2(); System.out.println("Done with main."); } public static void method1() { System.out.println("This is from method1."); } public static void method2() { System.out.println("This is from method2."); method1(); System.out.println("Done with method2."); } } -
以下程序的输出是什么?
public class OrderOfFunctions { public static void main(String[] args) { second(); first(); second(); third(); } public static void first() { System.out.println("Inside the first function."); } public static void second() { System.out.println("Inside the second function."); first(); } public static void third() { System.out.println("Inside the third function."); first(); second(); } }