本文介绍的编程基础知识非常Java适合初学者。
要学习编程,你需要了解编程语言的语法和功能。
你要不断的练习、练习和实践来处理你遇到的各种问题。
1. 马上开始 - 编写你的第1个Java程序
检查在开发环境中是否安装了 Java Development Kit (JDK)。
让我们来编写第1个Java程序,在控制台上输出“Hello,world!”,
Hello,World!
步骤1:编写代码
选择一个文本编辑器,Windows:TextPad、NotePad++;Mac OS X:jEdit、gedit;Ubuntu:gedit。
在编辑器内输入以下代码,输入完毕后保存为“Hello.Java"文件,扩展名“.java",文件名需要与类名一致区分大小写。
public class Hello {
public static void main(String[] args){
System.out.println("Hello,World!");
}
}
步骤2:编译源码
运行命令“javac”编译源文件"Hello.java",编译成功后会生成二进制文件“hello.class”。在终端中运行下面命令:
// 进入Hello.java所在目录
javac Hello.java
在IDEs(例如Eclispe、NetBeans)中不需要显示编译文件,因为他们支持即时编译。
步骤3:运行程序
运行"java"命令,
java Hello
Hello,World!
需要注意的是“java Hello”并没有包含“.class"扩展名。
在IDEs中,源文件右键 =》运行... =》Java Application会起到同样的作用。
编程的简要说明
/* ...... */
// ... 一直到行末尾
这都是注释的方式,注释会被编译器忽略不会被执行,但是注释方便读者更好的阅读和理解程序,有两种注释的方式:
- 多行注释:以/*开头,以*/结尾,可以跨越多行。
- 单行注释:以//开头,直到行尾。
public class Hello { ...... }
这个单元就是类的声明方式,类用关键字“class”进行定义,{ ..... }里面是类的主题内容,关键字"public”稍后会说明。
在Java中,源文件名需要和类名保持一致,同时以“.java"为文件扩展名。
public static void main(String[] args) { ...... }
这个单元是main()方法的定义,{ ...... }方法的主体中包含了编程语句。
System.out.println("Hello, world!");
字符串是由双引号和引号之间的文本组成,上面语句运行后,会在控制台输出Hello, world!,不包括两端的引号。
2. Java术语和语法
语句: 表示着一段程序的执行以;为结尾。
块: 一个块是由一组大括号和里面的语句组成,通常被视为一个单独的单元。我们的程序有两个块组成,一个块包含着Hello类的主体,另一个块包含着main()方法的主体,不需要在结束括号添加分号。
注释:多行注释以/*卡头,以*/结尾,单行注释以//开头直到行尾,注释会被变编译器忽略不会被执行,但是注释提供了解释、使用的文档说明,所以请自由的使用注释。
空白:空格,制表符和换行符统称为空白。一个空格标记分割,其余的空白会被忽略,但是他们会帮助你和你的读者更好的理解你的程序,所以请自由的使用空格。
区分大小写:Java是大小写敏感的,ROSE、Rose、rose是不同的变量,还有文件名也是区分大小写的。
3. Java程序模板
编程中你可以使用下面的模板,在你的程序中选择一个有意义的"Classname",在main方法体中写入编程语句,不用担心其他的项和关键字,我会在适当的时候加以解释。
public class Classname { // 选择一个有意义的类名
public static void main(String[] args){
// 这里是你的编程语句
}
}
4. 使用System.out.println()和System.out.print()输出
你可以使用 System.out.println()和System.out.print()将文本输出到控制台上:
- System.out.println(aString) 输出字符串,折行,光标位于折行开头的位置。
- System.out.print(aString)输出字符串,光标位于输出文本的后面。
运行下面的代码,并解释生成的输出:
public class PrintTest {
public static void main(String[] args) {
System.out.println("Hello, world!");
System.out.println();
System.out.print("Hello, world!");
System.out.println("Hello,");
System.out.print(" ");
System.out.print("world!");
System.out.println("Hello, world!");
}
}
Hello, world!
Hello, world!Hello,
world!Hello, world!
练习
1. 用System.out.println()打印下面的输出语句。
* * * * * * * * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * *
* * * * * * * * * * *
(a) (b) (c)
5. 编写一个加法的程序
public classFiveNumberSum {
public static void main(String[] args) {
int number1 = 11; // 声明5个int变量来存储5个数值
int number2 = 22;
int number3 = 33;
int number4 = 44;
int number5 = 55;
int sum; // 声明1个sum变量来存储相加之和
sum = number1 + number2 + number3 + number4 + number5;
System.out.print("The sum is ");
System.out.println(sum); // 输出相加之和
}
}
The sum is 165
int number1 = 11;
int number2 = 22;
int number3 = 33;
int number4 = 44;
int number5 = 55;
声明了5个int型变量number1、number2、number3、number4和number5,将11、22、33、44和55利用操作符"="赋给变量,你可以在一条语句中声明多个变量,用逗号分割,例如:
int number1 = 11, number2 = 22, number3 = 33, number4 = 44, number5 = 55;
int sum;
声明一个没有初始化的int型变量。
sum = number1 + number2 + number3 + number4 + number5;
sum存储number1到number5相加之和,操作符"+"表示加法,和数学上的一样。
System.out.print("The sum is ");
System.out.println(sum);
打印输出变量sum值,sum不加双引号,否则会直接输出"sum"。
练习
- 用操作符"*"修改上面的程序,并计算相乘的结果.
6. 程序是什么
程序是顺序执行的指令序列,参考下面的流程图。
例子
根据圆的半径计算周长和面积并输出。
public class CircleComputation {
public static void main(String[] args) {
// 声明变量
double radius, area, circumference;
final double PI = 3.14159265;
// 初始化圆半径
radius = 1.2;
// 计算面和周长
area = radius * radius * PI;
circumference = 2.0 * radius * PI;
// 打印输出结果
System.out.print("The radius is ");
System.out.println(radius);
System.out.print("The area is ");
System.out.println(area);
System.out.print("The circumference is ");
System.out.println(circumference);
}
}
The radius is 1.2
The area is 4.523893416
The circumference is 7.5398223600000005
double radius, area, circumference;
声明了3个double变量radius、area和circumference,double变量存储实数。
final double PI = 3.14159265;
声明一个double型变量PI并设置了初值,PI被声明为final,意味着它的值不能被改变。
radius = 1.2;
将1.2赋值给radius。
area = radius * radius * PI;
circumference = 2.0 * radius * PI;
根据圆的半径计算面积和周长。
System.out.print("The radius is ");
System.out.println(radius);
System.out.print("The area is ");
System.out.println(area);
System.out.print("The circumference is ");
System.out.println(circumference);
打印计算结果。值得注意的是main()方法体中顺序执行的语句。
练习
- 参考上面的例子,编写程序:根据长度和宽度打印输出矩形的周长和面积。
- 参考上面的例子,编写程序:根据半径和高度打印输出圆柱体的表面积和体积。
7. 什么是变量
计算机操纵数据,变量存储数据,之所以叫变量因为它的值可以被改变。
变量就是一块地址,存储特定类型的值,换句话说,一个变量有一个名称,数据类型和存储该类型的值。
- 变量有名称,例如半径,面积,年龄,高度,变量的名称是唯一的,我们可以获取(radius*radius*3.1416)和设置(adius=1.2)变量存储的值。
- int:整数例如123和-456。
- double:浮点数或者实数,例如:3.1416、-55.66、7.8e9和-1.2e3.4, 有一个可选的小数点和小数部分,也可以用科学计数法表示。
- String:文本例如"Hello","Good Moring!"。文本字符串包含在双引号里面。
- 变量存储特定类型的值。值得注意的是,大多数编程语言中变量都关联着类型以及该类型的值。int变量可以存储整数例如123,但不能存储实数例如12.34,也不能存储文本例如"你好"。早期的编程语言引入类型的概念来简化数据的理解。
下图说明了3种数据类型:int,double和String,int变量存储整数,double存储实数,字符串存储文本内容。
变量使用前需要被声明,你可以使用下面的声明方式:
varType varName; // 声明变量的类型
varType varName1, varName2,...; // 声明多个同一类型的变量
varType varName = initialValue; // 声明变量的类型并赋值
varType varName1 = initialValue1, varName2 = initialValue2,... ; // 声明多个变量并分别赋值
请注意:
- 声明语句以分号(;)为结尾。
- 声明多个变量,变量间以逗号(,)分隔。
- 操作符=,用来给变量赋值。
举例:
int sum; // 声明1个int型变量sum。
int number1, number2; // 声明2个int型变量number1,number2以分号相隔。
double average; // 声明1个double型变量average。
int height = 20; // 声明1个int型变量并初始化。
变量声明后,你可以利用操作符"="给变量赋值或重新赋值,例如:
int number; // 声明1个int型变量number。
number = 99; // 给变量"number"分配了一个整数99。
number = 88; // 给变量"number"重新分配了一个整数88。
number = number + 1; // 计算"number + 1", 将结果赋值给"number"。
int sum = 0; // 声明1个"int"变量"sum"并设置初值0。
sum = sum + number; // 计算"sum + number",将结果复制给"sum"。
int num1 = 5, num2 = 6; // 一条语句中声明了两个变量并设置初值, 用逗号分隔。
double radius = 1.5; // 声明1个"double"变量"radius"并设置初值1.5。
int number; // 错误: 变量"number"已经声明。
sum = 55.66; // 错误: "sum"是"int"型变量不能存储实数。
sum = "Hello"; // 错误: "sum"是"int"型变量不能存储字符串。
请注意:
- 每个变量只能声明一次。(没有两套房子对应着一个地址吧。)
- 你可以在程序内的任意位置声明。
- 一旦声明了某个类型的变量,它只能存储该类型的值,例如一个int型变量职能存储整数例如123,不能存储浮点类型例如-2.17或者文本“Hello"。
- 变量声明后类型不能改变。
在上面的列子中我已经展示了两种类型:int类型存储整数,double类型存储浮点数,编程时混合使用int和double时,需要特别的小心稍后我会解释。
x=x+1?
对于赋值操作符(=)在编程和数学中我们要区别对待,数学中"x=x+1"等式是不成立的,但在编程中意为着x+1后的值重新赋值给x。
x+y=1
数学中是有效,编程中无效。在编程中等式右侧是计算值;等式的左侧是变量,也就是说优先计算等式右侧,之后赋值给等式左侧。有一些编程语言使用 :=为赋值操作符,避免与等号混淆。
8. 基本的算数运算
基本的算数运算符是:
运算符 | 含义 | 例子 |
---|---|---|
+ | 加法 | x + y |
- | 减法 | x - y |
* | 乘法 | x * y |
/ | 除法 | x / y |
% | 取模(求余) | x % y |
++ | 递增(一元) | ++x or x++ |
-- | 递减(一元) | --x or x-- |
加法、减法、乘法、除法和取模是两个操作数二元运算,而自增和自减是一个操作数一元运算。
例子
下面的程序说明了这些运算:
/**
* 算数运算符测试
*/
public classArithmeticTest {
public static void main(String[] args) {
int number1 = 98; // 声明了一个int型变量number1设置初值98
int number2 = 5; // 声明了一个int型变量number2设置初值5
int sum, difference, product, quotient, remainder; // 声明5个变量来存储计算结果
// 执行算数运算
sum = number1 + number2;
difference = number1 - number2;
product = number1 * number2;
quotient = number1 / number2;
remainder = number1 % number2;
// 打印输出结果
System.out.print(number1);
System.out.print("和");
System.out.print(number2);
System.out.print("的相加, 相减, 相乘, 相除和取模的结果分别为");
System.out.print(sum);
System.out.print(", ");
System.out.print(difference);
System.out.print(", ");
System.out.print(product);
System.out.print(", ");
System.out.print(quotient);
System.out.print(", 和");
System.out.println(remainder);
++number1; // number1自增1, 相当于"number1=number1 + 1"
--number2; // number2自减2, 相当于"number2=number2 - 1"
System.out.println("number1递增后的结果为" + number1);
System.out.println("number2递增后的结果为" + number2);
quotient = number1 / number2;
System.out.println(number1 + " 和" + number2 + "新的商为" + quotient);
}
}
98和5的相加, 相减, 相乘, 相除和取模的结果分别为103, 93, 490, 19, 和3
number1递增后的结果为99
number2递增后的结果为4
99和4新的商为24
程序剖析
int number1 = 98;
int number2 = 5;
int sum, difference, product, quotient, remainder;
为了程序的需要声明了全都是int型的变量number1、number2、 sum、difference、product、quotient和remainder。
sum = number1 + number2;
difference = number1 - number2;
product = number1 * number2;
quotient = number1 / number2;
remainder = number1 % number2;
开始执行number1和number2的运算,注意下整数相除后产生的截断整数,例如98/5 → 19, 99/4 → 24和1/2 → 0。
System.out.print(number1); // 输出变量值
System.out.print("和");
System.out.print(number2);
System.out.print("的相加, 相减, 相乘, 相除和取模的结果分别为");
......
打印运算结果并适当的加以描述,输出普通文本需要加双引号,变量不需要。
System.out.println("sum"); // 输出"sum"
System.out.println(sum); // 输出变量sum存储的值例如98
++number1;
--number2;
举例说明了自增和自减操作, "++"和"--"只有一个操作数(一元运符)而不像"+"、"-"、"*"、"/"和"%"有两个操作数(二元运算符),++放在操作数之前称作预增,放在操作数之后称作后增,预增和后增的最终结果都是使操作数自增1,但是两者有所区别,我会在后面说明。
System.out.println("number1递增后的结果为" + number1);
System.out.println("number2递增后的结果为" + number2);
打印自增/自减后的结果。这里我们将文本字符串和变量通过"+"操作符联合输出,在这种情况下"+"不执行加法操作,而是字符串连接符。
练习
- 使用"+"操作符使用一条println()语句打印所有的输出结果。
- 增加一个新int型变量number3,设置初始值为77,计算和打印三个数之和。
- 编程中我们使用*来表示乘法,试着计算并打印输出结果:1的31倍加上2的17倍加上3的87倍的和。
9. 累加1000个数?使用循环
假设你想计算从1~1000累加和,按照上面的例子你要在程序中写1000行代码!不过有个更简单的方式就是使用循环,要知道计算机最擅长的就是重复性的计算。
例子
来试试下面的程序:使用循环来计算从1累加到1000的和
/*
* 使用循环计算从最小值到最大值的累加和
*/
public class RunningNumberSum {
public static void main(String[] args) {
int lowerbound = 1; // 存储最小值
int upperbound = 1000; // 存储最大值
int sum = 0; // 声明sum变量来存储中间的累加和
int number = lowerbound;
while (number <= upperbound) {
sum = sum + number; // 将number累加到sum中
++number; // 开始累加下个数
}
// 打印输出结果
System.out.println("从" + lowerbound + "到" + upperbound + "的累加之和为" + sum);
}
}
从1到1000的累加之和为500500
程序剖析
int lowerbound = 1;
int upperbound = 1000;
定义两个变量分别存储最小值和最大值。
int sum = 0;
定义一个变量来存储累加之和。
int number = lowerbound;
while (number <= upperbound) {
sum = sum + number;
++number;
}
这个我们称之为循环,一个while循环的语法如下:
initialization-statement;
while (test) {
loop-body;
}
next-statement;
从上面的流程图我们可以看出,首先执行初始化语句,校验test,如果为真执行方法体,每执行一次方法体后都会重新校验test,为真继续执行,直到test为假的时候退出循环。
程序循环的总次数:upperbound-lowerbound+1,循环结束后打印输出结果。
System.out.println("从" + lowerbound + "到" + upperbound + "的累加之和为" + sum);
练习
- 修改上面的程序计算从9到888累加和。
- 修改上面的程序计算从1到1000的奇数累加和。
- 修改上面的程序计算从1到1000每个数都被7除的累加和。
- 修改上面的程序计算从1到100每个数平方的累加和。
- 修改上面的程序计算从1到10的乘积。
10. 条件(判断)
如果你想计算从1到1000的奇数之和,有很多种方法,你可以声明两个变量:sumOdd和sumEven,使用条件语句判断奇数和偶数,之后累加到相应的变量,程序如下:
/*
* 分别计算从最小值到最大值的奇数和偶数和
*/
public class OddEvenSum {
public static void main(String[] args) {
int lowerbound = 1, upperbound = 1000; // 最小值, 最大值
int sumOdd = 0; // 奇数累加和, 初始化为0
int sumEven = 0; // 偶数累加和, 初始化为0
int number = lowerbound;
while (number <= upperbound) {
if (number % 2 == 0) { // 偶数
sumEven += number; // 等价于sumEven = sumEven + number
} else { // 奇数
sumOdd += number; // 等价于sumOdd = sumOdd + number
}
++number; // 下个数值
// 打印输出结果
System.out.println("奇数和从" + lowerbound + "到" + upperbound + "为" + sumOdd);
System.out.println("偶数和从" + lowerbound + "到" + upperbound + "为" + sumEven);
System.out.println("两者之差为" + (sumOdd - sumEven));
}
}
}
奇数和从1到1000为250000
偶数和从1到1000为250500
两者之差为-500
程序剖析
int lowerbound = 1, upperbound = 1000;
声明用于循环的最小值和最大值。
int sumOdd = 0;
int sumEven = 0;
声明两个变量分别来存储累加奇数和累加偶数。
if (number % 2 == 0) {
sumEven = sumEven + number;
} else {
sumOdd = sumOdd + number;
}
这是一个条件语句。可以使用这一种条件语句:if-then活if-then-else。
// if-then
if ( test ) {
true-body;
}
// if-then-else
if ( test ) {
true-body;
} else {
false-body;
}
if-then条件语句,test为真执行true-body。if-then-else语句,test为真执行true-body,test为假执行false-body。在我们的程序中,我们使用求余操作符(%)取2的余数来校验奇偶。
比较运算符
有6比较运算符:
操作符 | 含义 | 举例 |
---|---|---|
== | 等于 | x == y |
!= | 不等于 | x != y |
> | 大于 | x > y |
>= | 大于等于 | x >= y |
< | 小于 | x < y |
<= | 小于等于 | x <= y |
值得注意的是双等号(==)是用来比较相等;一个等号(=)是赋值操作。
并列条件
验某个数值是否在1~100之间:1<=x<=100,这里面有条件(x>=1) 与 (x<=100),编程中你需要用( x >= 1 ) && ( x <= 100 ) 来表示, "&&"操作符表示"与"操作,同样校验某个数值是否可以被2或3整除,你可以使用 ( x % 2 ==0 ) || ( x % 3 == 0 ) ,"||"操作符表示"或"操作。
有三个逻辑运算符
操作符 | 含义 | 举例 |
---|---|---|
&& | 逻辑与 | (x >= 1) && (x <= 100) |
|| | 逻辑或 | (x < 1) || (x > 100) |
! | 逻辑非 | !(x == 8) |
举例:
(x >= 0) && (x <= 100) // 验证x是否大于等于0小于等于100,错误的用法:0 <= x <= 100
(x < 0) || (x > 100) // 验证x是否小于0或者大于100
!((x >= 0) && (x <= 100)) // 条件非
// 验证闰年:闰年要被4整除但不能被100整除,或者直接被400整除
((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)
练习
- 编程校验1~1000之间被13或者15或者17整除,但是不能被30整除的数都有哪些。
- 编程计算从公元1年到公元2010年所有的闰年。
11. 浮点类型
回想一下,在Java中变量有名称、类型和存储该类型的值。我们之前已经使用过int类型,int型变量只能存储整型,例如123和-456;它不能存储一个实数,例如12.34。编程中,真正的实数例如3.1416和-55.66称之为浮点数,它们属于类型double,你可以使用浮点数(例如1.23,-4.5)或者科学计数法(例如1.2e3,-4E5.6)其中e或E表示10的指数。
例子
/*
* 摄氏温度和华氏温度之间的转换
*/
public class h {
public static void main(String[] args) {
double celsius, fahrenheit;
celsius = 37.5;
fahrenheit = celsius * 9.0 / 5.0 + 32.0;
System.out.println(celsius + " degree C is " + fahrenheit + " degree F.");
fahrenheit = 100.0;
celsius = (fahrenheit - 32.0) * 5.0 / 9.0;
System.out.println(fahrenheit + " degree F is " + celsius + " degree C.");
}
}
37.5 degree C is 99.5 degree F.
100.0 degree F is 37.77777777777778 degree C.
12. 混合使用int、double和类型转换
虽然你可以使用double存储整数(例如:double count=5.0),但是强烈建议你使用int来存储,因为int比double更高效(运行时间、存储等)。
你的程序有时会同时使用int和double,例如用int来存储1~1000累加之和,用double来存储平均值,混合使用类型的场景你要格外的小心。
值得注意的是:
- 对于算数运算('+', '-', '*', '/'),两个int会产生一个int;同样的两个double会产生一个double,例如1/2 → 0,1.0/2.0 → 0.5。
- 一个int和一个double会产生一个double,例如1.0/2 → 0.5,1/2.0 → 0.5。
你可以将int赋值给double变量,int类型会自动转换为double类型:3 → 3.0,举例:
int i = 3;
double d;
d = i; // 3 → 3.0, d = 3.0
d = 88; // 88 → 88.0, d = 88.0
double nought = 0; // 0 → 0.0; int 0和double 0.0有些细微的差别
但是不能直接将double赋值给int变量,因为小数部分可能会丢失,编译器也会发出错误的警告,举例:
double d = 5.5;
int i;
i = d; // 错误: 丢失精度
i = 6.6; // 错误: 丢失精度
类型转换操作符
将一个double赋值给int变量,你需要显示的调用类型转换操作符来截断小数,如下:
(new-type)expression;
举例:
double d = 5.5;
int i;
i = (int) d; // 强制的将double转换为int,d变量值不受影响
i = (int) 3.1416; // i = 3
值得注意的是强制类型转换是以(int)或(double)的形式,适用于一个操作数的运算符(一元运算符)。
类型转换是一个操作,就像自增、自减,强制转换一个特定类型的数值。(int)3.1416返回3,(double)5返回5.0。
例子
运行下面的代码并解释输出的原因
/*
* 计算从最小值到最大值的累加之和, 同时计算平均值
*/
public class TypeCastingTest {
public static void main(String[] args) {
int lowerbound = 1, upperbound = 1000;
int sum = 0; // sum为"int"
double average; // average为"double"
// 计算和(使用"int")
int number = lowerbound;
while (number <= upperbound) {
sum = sum + number;
++number;
}
System.out.println("The sum from " + lowerbound + " to " + upperbound + " is " + sum);
// 计算平均值(使用"double")
average = sum / (upperbound - lowerbound + 1);
System.out.println("平均值1为" + average);
average = (double)sum / (upperbound - lowerbound + 1);
System.out.println("平均值2为" + average);
average = sum / 1000;
System.out.println("平均值3为" + average);
average = sum / 1000.0;
System.out.println("平均值4为" + average);
average = (double)(sum / 1000);
System.out.println("平均值5为" + average);
}
}
从1到1000累加和为500500
平均值1为500.0
平均值2为500.5
平均值3为500.0
平均值4为500.5
平均值5为500.0
平均值1不正确,因为int/int生成int(500),最后被转换成double(500.0)。
对于平均值2,sum首先被转换成double,随后,double/int产生一个double。
对于平局值5,int/int产生int(500),之后被强制转换成double。
练习
- 创建一个类HarmonicSeriesSum来计算谐波系列1 + 1/2 + 1/3 + 1/4 + .... + 1/n的总和,其中n=1000,sum为double类型,特别注意1/2输出0,1.0/2输出0.5。试着改变的n的值1000,5000,10000,50000,100000重新计算。
- 修改上面类为GeometricSeriesSum来计算几何级数1 + 1/2 + 1/4 + 1/8 + ....的总和,其中n=1000。
13. 总结
本文介绍的编程基础知识非常Java适合初学者。
要学习编程,你需要了解编程语言的语法和功能。
你要不断的练习、练习和实践来处理你遇到的各种问题。