0. 前言
导师开了一个专栏——Java教程,之前也没有学过Java,所以跟着老师的教程走一遍!
俗话说得好,“工欲善其事必先利其器”。学任何一门编程语言之前,都需要装好合适的 IDE。所以这一节主要就是安装 Eclipse,把环境搭好。
1. day 1
1.1 安装JDK
安装 Eclipse 之前,需要先下载安装 java 的运行环境 jdk。由于以前装过jdk,故此处贴一个其他博主的具体的 jdk 安装步骤以及环境变量的配置过程:https://blog.csdn.net/qq_39135287/article/details/82108080
JDK 安装好并配置好环境之后,可以通过如下命令检测是否安装成功。
命令:javac
命令:java -version
查看版本
1.2 安装 Eclipse
- 下载地址:http://www.eclipse.org/downloads/
选择对应自己电脑的版本
之后,会跳转到如下页面,点击下载即可。
- 下载完成后,解压下载刚刚下载的安装包
解压后,打开如下文件夹
双击eclipse.exe 即可
- 选择工作目录
1.3 JDK、JRE、JVM
JDK(Java Development Kit Java 开发工具包)
- JDK 是提供给开发人员使用的,其中包含了 java 的开发工具,也包括了JRE。
其中的开发工具:编译工具 javac.exe、打包工具 jar.exe 等
JRE(Java Runtime Environment Java 运行环境)
- 包括 java 虚拟机(JVM — Java Virtual Machine)和 java 程序所需的核心类库等
因此,安装了 JDK ,就无需单独安装 JRE 了。若只想运行已经开发好的java程序,只需安装 JRE 即可。
可以用下面的图来说明 JDK、JRE、JVM 的关系。
1.4 第一个 java 程序
package basic;
class HelloWorld{
public static void main(String[] args){
System.out.println("Hello, World!");
}//Of main
}//Of class HelloWorld
1.5 基本语法
一、变量按数据类型分:
- 基本数据类型
- 整型:byte short int long
- 浮点型:float double
- 字符型:char
- 布尔型:boolean
- 引用数据类型
- 类 class
- 接口 interface
- 数组 array
二、变量按在类中的声明位置分:
成员变量、局部变量(后续补充…)
基本数据类型
- 整型
类型 | 存储空间 | 数值范围 |
---|---|---|
byte | 1字节(8bit位) | − 2 7 -2^7 −27~ 2 7 − 1 2^7-1 27−1 (-128~127) |
short | 2字节 | − 2 15 -2^{15} −215~ 2 15 − 1 2^{15}-1 215−1 |
int | 4字节 | − 2 31 -2^{31} −231~ 2 31 − 1 2^{31}-1 231−1 |
long | 8字节 | − 2 63 -2^{63} −263~ 2 63 − 1 2^{63}-1 263−1 |
注:声明 long 型变量必须以"l"或"L"结尾;整型变量通常使用 int.
整型常量默认为 int 型
- 浮点型
类型 | 存储空间 | 数值范围 |
---|---|---|
float | 4字节 | -3.403E38~3.403E38 |
double | 8字节 | -1.798E308~1.798E308 |
注:float 表示的数值范围比 long 大;声明 float 型变量必须以"f"或"F"结尾;浮点型变量通常使用 double.
浮点型常量默认为 double 型
- 字符型
char:1字符 = 2字节
定义char型变量,通常使用 ‘’,内部是一个字符
char a = '\n';//换行符
char b = '\t';//制表符
- 布尔型
值只能为 true 或 false
基本数据类型之间的运算
此处讨论前面7种基本数据类型变量间的运算,不包括 boolean 类型。
- 自动类型提升
表示数值范围小的数据类型与数值范围大的数据类型的变量做运算时,结果自动提升为表示数值范围更大的数据类型。
byte、char、short → \rightarrow → int → \rightarrow → long → \rightarrow → float → \rightarrow → double
class VariableTest{
public static void main(String[] args){
byte byteVar = 2;
int intVar1 = 129;
int intVar2 = byteVar + intVar1;
System.out.println(intVar2);
}
}
- 强制类型转换
需要使用强转符:()
强制转换可能导致精度损失
class VariableTest{
public static void main(String[] args){
double doubleVar = 17.9;
int intVar1 = (int)doubleVar;//截断操作,精度损失
System.out.println(intVar1);//17
long longVar = 179;
short shortVar = (short)longVar;//没有精度损失
int intVar2 = 128;
byte byteVar = (byte)intVar2;//精度损失
System.out.println(byteVar);//-128
}
}
关于 int 强转成 byte 型,由128变成-128看似不能理解,实际转换过程涉及到进制转换的知识。此处,对此进行扩展说明。
首先,需要明确一点的是,在计算机中数值是以补码的形式存储的。正数的原码、反码、补码都相同,负数的补码是反码+1.
以十进制数-13(byte:8位)为例:首位为符号位,0表示整数,1表示负数
- -13 原码: 10001101
- -13 反码:11110010
在原码的基础上,符号位不变,其余位取反 - -13 补码:11110011
在反码的基础上,+1
即在计算机中 -13 是以 11110011 的形式存储的。
由此,对 int 型128 强转为 byte 型进行解释
- 128 (32位) 二进制表示为:0000 0000 0000 0000 0000 0000 1000 0000
- 转成 byte 型,取低的8位,因此转换后结果为:1000 0000
- 1000 0000是某个数的补码,最高位为符号位,所以是个负数,再倒推回去得到,这个数的十进制是 -128。所以,最终转换后输出的结果是-128.
字符串类型:String
首先,需要注意一点,String 不是基本数据类型,是引用数据类型。
- 声明 String 类型变量时,使用 “”;
- String 可以和8种基本数据类型做运算,但只能做连接运算(+)且运算结果为 String 类型。
class StringTest{
public static void main(String[] args){
String s = "Hello, Jerry!";
System.out.println(s);
int age = 21;
String ageStr = "年龄:";
String info = ageStr + age;// +:连接运算
System.out.println(info);
boolean t = true;
String info2 = info + t;// +:连接运算
System.out.println(info2);
}
}
1.6 小结
- 一个 java 源文件中可以同时声明多个类 class,但是最多只能有一个类声明为 public,并且声明为 public 的类名必须与源文件名相同。如下所示:
public class test01{
public static void main(String[] args){
System.out.println("Hello, World!");
}//Of main
}//Of class HelloWorld
class Person{
}
class Animal{
}
- 程序的入口是
main()
方法,格式是固定的 - 输出语句
System.out.println(); //先输出后换行
System.out.print(); //只输出不换行
-
不同于 Python,java 语句要以 “;” 结束
-
合法标识符定义规则
- 由26个英文字母(大小写)、0-9、_或$组成;
- 不能以数字开头;
- 不能使用关键字和保留字;
- 严格区分大小写;
- 不能包含空格
-
名称命名规范
- 包名:多个单词构成全部小写,如:mystudent;
- 类名、接口名:多个单词构成,每个单词首字母大写(大驼峰),如:MyStudent;
- 变量名、方法名:多个单词构成,第一个单词小写,后面的单词首字母大写(小驼峰),如:myStudent;
- 常量名:多个单词构成时,由下划线连接,全部大写,如:PI
2. day 2 算术运算
照着我导师的代码写了一遍。对 Int 型和 Double 型的变量,对其进行加减乘除以及取余运算,并将结果进行打印。
package com.stujava.arithmeticoperation02;
public class TeacherBasicOperations {
public static void main(String[] args) {
int tempFirstInt, tempSecondInt, tempResultInt;
double tempFirstDouble, tempSecondDouble, tempResultDouble;
tempFirstInt = 15;
tempSecondInt = 4;
tempFirstDouble = 1.2;
tempSecondDouble = 3.5;
//Addition
tempResultInt = tempFirstInt + tempSecondInt;
tempResultDouble = tempFirstDouble + tempSecondDouble;
System.out.println("" + tempFirstInt + " + " + tempSecondInt + " = " + tempResultInt);
System.out.println("" + tempFirstInt + " + " + tempSecondInt + " = " + tempResultInt);
System.out.println("" + tempFirstDouble + " + " + tempSecondDouble + " = " + tempResultDouble);
//Subtraction
tempResultInt = tempFirstInt - tempSecondInt;
tempResultDouble = tempFirstDouble - tempSecondDouble;
System.out.println("" + tempFirstInt + " - " + tempSecondInt + " = " + tempResultInt);
System.out.println("" + tempFirstDouble + " - " + tempSecondDouble + " = " + tempResultDouble);
//Multiplication
tempResultInt = tempFirstInt * tempSecondInt;
tempResultDouble = tempFirstDouble * tempSecondDouble;
System.out.println("" + tempFirstInt + " * " + tempSecondInt + " = " + tempResultInt);
System.out.println("" + tempFirstDouble + " * " + tempSecondDouble + " = " + tempResultDouble);
//Division
tempResultInt = tempFirstInt / tempSecondInt;
tempResultDouble = tempFirstDouble / tempSecondDouble;
System.out.println("" + tempFirstInt + " / " + tempSecondInt + " = " + tempResultInt);
System.out.println("" + tempFirstDouble + " / " + tempSecondDouble + " = " + tempResultDouble);
//Modulus
tempResultInt = tempFirstInt % tempSecondInt;
System.out.println("" + tempFirstInt + " % " + tempSecondInt + " = " + tempResultInt);
}// Of main
}//Of class TeacherBasicOperations
需要注意的是,输出时,"+" 是连接符。
3. day 3 if 语句
if-else 是一种分支结构,常用作条件判断。
/*
分支结构之 if-else
第一种:
if(条件表达式){
...
}
第二种:
if(条件表达式){
...
}else{
...
}
第三种:
if(条件表达式){
...
}else if(条件表达式){
...
}else if(条件表达式){
...
}
...
else{
...
}
*/
先写一遍老师的代码:
public class IfStatement {
/**
*********************
* The entrance of the program.
*
* @param args Not used now.
*********************
*/
public static void main(String args[]) {
int tempNumber1, tempNumber2;
// Try a positive value
tempNumber1 = 5;
if (tempNumber1 >= 0) {
tempNumber2 = tempNumber1;
} else {
tempNumber2 = -tempNumber1;
} // Of if
System.out.println("The absolute value of " + tempNumber1 + " is " + tempNumber2);
// Try a negative value
tempNumber1 = -3;
if (tempNumber1 >= 0) {
tempNumber2 = tempNumber1;
} else {
tempNumber2 = -tempNumber1;
} // Of if
System.out.println("The absolute value of " + tempNumber1 + " is " + tempNumber2);
// Now we use a method/function for this purpose.
tempNumber1 = 6;
System.out.println("The absolute value of " + tempNumber1 + " is " + abs(tempNumber1));
tempNumber1 = -8;
System.out.println("The absolute value of " + tempNumber1 + " is " + abs(tempNumber1));
}// Of main
/**
*********************
* The absolute value of the given parameter.
*
* @param paraValue The given value.
*********************
*/
public static int abs(int paraValue) {
if (paraValue >= 0) {
return paraValue;
} else {
return -paraValue;
} // Of if
}// Of abs
}// Of class IfStatement
运行结果:
The absolute value of 5 is 5
The absolute value of -3 is 3
The absolute value of 6 is 6
The absolute value of -8 is 8
以上代码实际上就是确定一个数的绝对值是多少。正数的绝对值是本身,负数的绝对值还要取个负号,此处就涉及到判断了,需要先判断这个数是 >=0 还是 <0。前两个都是直接进行判断,后面两个数据,是将取绝对值的方法写成一个函数,也可以叫方法,其返回值为某数的绝对值。
4. day 4 闰年计算
首先,看看闰年的判定方法。
有这么一种说法:“四年一闰,百年不闰,四百年再闰”
1、普通闰年:公历年份是4的倍数的,一般是闰年。(如2004年就是闰年);
2、世纪闰年:公历年份是整百数的,必须是400的倍数才是闰年(如1900年不是世纪闰年,2000年是世纪闰年)。
即能被4整除且不能被100整除是闰年;能被400整除的是闰年。
用数学式子来描述就是:(year % 4 = 0 and year % 100 ≠ \neq = 0) or year % 400 = 0
package com.teachercode;
public class LeapYear {
/**
*********************
* The entrance of the program.
*
* @param args not used now.
*********************
*/
public static void main(String[] args) {
// Test isLeapYear
int tempYear = 2021; // 平年
System.out.print("" + tempYear + " is ");
if (!isLeapYear(tempYear)) {
System.out.print("NOT "); // 当 !isLeapYear(tempYear)=true,即 isLeapYear(tempYear)=false表明不是闰年
}// Of if
System.out.println("a leap year.");
tempYear = 2000; // 闰年
System.out.print("" + tempYear + " is ");
if (!isLeapYear(tempYear)) {
System.out.print("NOT "); // 当 !isLeapYear(tempYear)=true,即 isLeapYear(tempYear)=false表明不是闰年
}// Of if
System.out.println("a leap year.");
tempYear = 2100; // 平年
System.out.print("" + tempYear + " is ");
if (!isLeapYear(tempYear)) {
System.out.print("NOT "); // 当 !isLeapYear(tempYear)=true,即 isLeapYear(tempYear)=false表明不是闰年
}// Of if
System.out.println("a leap year.");
tempYear = 2004; // 闰年
System.out.print("" + tempYear + " is ");
if (!isLeapYear(tempYear)) {
System.out.print("NOT "); // 当 !isLeapYear(tempYear)=true,即 isLeapYear(tempYear)=false表明不是闰年
}// Of if
System.out.println("a leap year.");
// Test isLeapYearV2
System.out.println("Now use the second vertion.");
tempYear = 2021;
System.out.print("" + tempYear + " is ");
if (!isLeapYearV2(tempYear)) {
System.out.print("NOT ");
}// Of if
System.out.println("a leap year.");
tempYear = 2000;
System.out.print("" + tempYear + " is ");
if (!isLeapYearV2(tempYear)) {
System.out.print("NOT ");
}// Of if
System.out.println("a leap year.");
tempYear = 2100;
System.out.print("" + tempYear + " is ");
if (!isLeapYearV2(tempYear)) {
System.out.print("NOT ");
}// Of if
System.out.println("a leap year.");
tempYear = 2004;
System.out.print("" + tempYear + " is ");
if (!isLeapYearV2(tempYear)) {
System.out.println("NOT ");
}// Of if
System.out.println("a leap year.");
}// Of main
/**
*********************
* Is the given year leap ?
*
* @param paraYear The given year.
*********************
*/
public static boolean isLeapYear(int paraYear) {
/*
* 此判定方法就是将逻辑判断写在一起,通过一个 if-else 就能够实现闰年的判定
* (year % 4 = 0 and year % 100 != 0) or year % 400 = 0
* */
if ((paraYear % 4 ==0 && paraYear % 100 != 0) || (paraYear % 400 == 0)) {
return true;
}else {
return false;
} //Of if
} // Of isLeapYear
/**
*********************
* Is the given year leap? Replace the complex condition with a number of if.
*
* @param paraYear The given year.
*********************
*/
public static boolean isLeapYearV2(int paraYear) {
/*
* 此判定方法就是将逻辑判断分开来写,通过 if-else if-else 来实现
* */
if (paraYear % 4 != 0) {
return false;
}else if (paraYear % 400 == 0) {
return true;
}else if (paraYear % 100 == 0) {
return false;
}else {
return true;
} //Of if
} //Of isLeapYearV2
} //Of class LeapYear
5. day 5 基本 switch 语句
switch-case 也是一种分支结构,其结构如下:
switch (表达式) {
case 常量1:
语句1;
break;
case 常量2:
语句2;
//break;
......
case 常量n:
语句n;
break;
default:
语句;
break;
}
public class SwitchStatement {
/**
*********************
* The entrance of the program.
*
* @param args Not used now.
*********************
*/
public static void main(String[] args) {
scoreToLevelTest();
}// Of main
/**
*********************
* Score to level.
*
* @param paraScore from 0 to 100.
* @return The level from A to F.
*********************
*/
public static char scoreToLevel(int paraScore) {
// E stands for error, and F stands for fail.
char resultLevel = 'E';
// Divide by 10, the result ranges from 0 to 10.
int tempDigitalLevel = paraScore / 10;
switch (tempDigitalLevel) {
/*
根据switch表达式中的值,依次匹配各个case中的常量,若匹配,则调用相关执行语句;
语句执行后,仍向下继续执行其他case中的语句,直至break或switch-case末尾结束.
*/
case 10:
case 9:
resultLevel = 'A';
break;
case 8:
resultLevel = 'B';
break;
case 7:
resultLevel = 'C';
break;
case 6:
resultLevel = 'D';
break;
//switch-case中的多个case的执行语句相同,可以合并
case 5:
case 4:
case 3:
case 2:
case 1:
case 0:
resultLevel = 'F';
break;
default:
resultLevel = 'E';
}// Of switch
return resultLevel;
}// Of scoreToLevel
/**
*********************
* Method unit test.
*********************
*/
public static void scoreToLevelTest() {
int tempScore = 100;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 91;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 82;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 75;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 66;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 52;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 8;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
tempScore = 120;
System.out.println("Score " + tempScore + " to level is: " + scoreToLevel(tempScore));
}// Of scoreToLevelTest
}// Of class SwitchStatement
至此,分支结构就已经了解完了,if-else 以及 switch-case. switch-case 语句都能写成 if-else 的形式,反之,则不行(由于 switch 的表达式类型的限制)。实际情况中,更加常用的是 if-else,但在特定的情况下 switch-case 又更能避免冗余。
比如,比较常见的一道题目,输入某年某月某日,判断这是该年的第几天。
首先,需要判断某一年是否是闰年;其次,若完全使用 if-else,会显得冗余。由此,通过 switch-case 来实现月份的一个累加,判断闰年的时候就是用 if-else,二者结合来实现这个过程。具体实现如下:
import java.util.Scanner;
/*
* 从键盘输入year、month 和 day,输出当年的第几天
* */
/*
* 1 3 5 7 8 10 12: 31
* 2: 28 or 29
* 4 6 9 11: 30
* */
public class SwitchCaseTest2 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("请输入year:");
int year = scan.nextInt();
System.out.println("请输入month:");
int month = scan.nextInt();
System.out.println("请输入day:");
int day = scan.nextInt();
int sumDay = whichDay(year, month, day);
System.out.println("2019年" + month + "月" + day + "日是该年的第" + sumDay +"天");
}// Of main
public static int whichDay(int year, int month, int day) {
int sumDay = 0; // 该变量用来累计天数
switch(month) {
//该结构中没有break,所以倒着匹配月份;假如是10月份,匹配至10时,会累加9月的天数,没有break就不会跳出switch结构,继续执行后面的语句,就不断累加前边的天数。
case 12:
sumDay += 30;
case 11:
sumDay += 31;
case 10:
sumDay += 30;
case 9:
sumDay += 31;
case 8:
sumDay += 31;
case 7:
sumDay += 30;
case 6:
sumDay += 31;
case 5:
sumDay += 30;
case 4:
sumDay += 31;
case 3:
//需要判断平年还是闰年
if ((year % 4 == 0 && year % 100 != 0) || year % 400 ==0) {
sumDay += 29;
}else {
sumDay += 28;
}
case 2:
sumDay += 31;
case 1:
sumDay += day;
}// Of switch
return sumDay;
}// Of whichDay
}// Of class SwitchCaseTest