03Java基础语法

关键字、标识符、注释、常量

关键字

  1. 被Java语言赋予特定含义的单词

  2. 特点:组成关键字单词的字母全部小写。

  3. 注意:

    A. goto和const是保留字

    B. 类似于 Notepad++、EditPlus 这样的高级文本编辑器,针对关键字都有特殊的颜色标记。

标识符

  1. 给类,接口,方法,变量等起名字的字符序列

  2. 组成规则:

    A. 英文大小写字母

    B. 数字

    C. $和_

  3. 注意事项:

    A. 不能以数字开头

    B. 不能是java中的关键字

    C. 区分大小写

  4. 常见的命名规则(见名知意)

    A. 包  全部小写

        单级包:小写

          举例:liuyi、com

        多级包:小写,并用 ‘.’ 隔开

          举例:cn.itcast、com.baidu

    B. 类或者接口

        一个单词:首字母大写

          举例:Student,Demo

        多个单词:每个单词首字母大写

          举例:HelloWorld,StudentName

    C. 方法或者变量

        一个单词:首字母小写

          举例:name,main

        多个单词:从第二个单词开始,每个单词首字母大写

          举例:studentAge,showAllNames()

    D. 常量  全部大写

        一个单词:大写

          举例:PI

        多个单词:大写,并用 ‘_’ 隔开

          举例:STUDENT_MAX_AGE

注释

  1. 单行注释 //

  2. 多行注释 /**/

  3. 文档注释 /** */

常量

  1. 在程序执行的过程中,其值不发生改变的量

  2. 分类:

    A. 字面值常量

    B. 自定义常量(后面讲)

  3. 字面值常量

    A. 字符串常量 “hello”

    B. 整数常量 12、23

    C. 小数常量 12.345

    D. 字符常量 ‘a’、’A’、’0’

    E. 布尔常量 true,false

    F. 空常量 null

  4. 在Java中针对整数常量提供了四种表现形式

    A. 二进制 由0,1组成。以0b开头。

    B. 八进制 由0,1,…7组成。以0开头。

    C. 十进制 由0,1,…9组成。整数默认是十进制。

    D. 十六进制 由0,1,…9,a,b,c,d,e,f(大小写均可)组成。以0x开头。

    System.out.println(100); //十进制

    System.out.println(0b100); //二进制

    System.out.println(0100); //八进制

    System.out.println(0x100); //十六进制

数据类型

Java是一种强类型语言,针对每种数据都提供了对应的数据类型。

JAVA只有两种数据类型:基本数据类型,引用数据类型

基本数据类型:8种

注意:Java基本类型长度固定,和系统位宽无关

整数

JAVA中没有无符号的整数。JAVA中整数可以表示十进制,二进制(以0b开头),八进制(以0开头),十六进制(以0X或0x开头)。

byte

​ 1个字节,-27—27-1

                    8位带符号数

1
2
3
4
5
6
byte b1 = 127;
byte b2 = (byte)128; //-128
byte b3 = (byte)129; //-127
byte b4 = (byte)130; //-126

byte的范围:-128 ~ 127

short

​ 2个字节,-215—215-1

                    16位带符号数

int

​ 4个字节,-231—231-1,JAVA中的整数默认为int类型

                    32位带符号数

long

​ 8个字节,-263—263-1,在整数的后面加L或l表示long类型的整数。

                    64位带符号数

浮点数

浮点数的运算会产生误差

float

​ 4个字节,在浮点数后面加F或f.

                    32位,标准IEEE 754

double

​ 8个字节,JAVA中浮点数默认为double类型

                    64位,标准IEEE 754

字符类型

char

​ 2个字节,值必须放在一对单引号中,并且单引号中只能有一个字符。

​ 值必须放在一对单引号中,并且单引号中只能有一个字符

​ JAVA使用Unicode编码集,所有的字符均为2个字节,所以 Java 语言中的字符 char 可以存储一个中文汉字

  ASCII码

    ‘a’ 97

    ‘A’ 65

    ‘0’ 48

布尔类型

boolean

​ 1个字节,只有两个值:true、false。JAVA中boolean类型不能转换为其它类型。占用1个字节。

Demo

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
class DataTypeDemo {
public static void main(String[] args) {
// 定义变量的格式:
// 数据类型 变量名 = 初始化值;

// 定义一个字节变量
byte b = 10;
System.out.println(10);
System.out.println(b);

// 定义一个短整型变量
short s = 100;
System.out.println(s);

// 定义一个整型变量
int i = 1000;
System.out.println(i);

// 超过了int的范围
// int j = 1000000000000;
long j = 1000000000000L;
// long j = 100L;
System.out.println(j);

// 定义浮点数据变量
float f = 12.345F;
System.out.println(f);
double d = 12.345;
System.out.println(d);

// 定义字符变量
char ch = 'a';
System.out.println(ch);

// 定义布尔变量
boolean flag = true;
System.out.println(flag);
}
}

引用数据类型

接口

数组

枚举

注解

字符串

字符串转义陷阱

1
2
System.out.println("\045678"); // 输出 %678
System.out.println("\u045678"); // 输出 i78

声明

变量

  a) 格式:数据类型 变量名[=值];

  b) JAVA是强类型的语言。

  c) 当变量没有赋值时不能使用,否则编译失败。

  d) 在同一个范围内不能出现同名的变量。

  e) 标识符(类名,变量名,方法名,包名等)的命名规则

    i. 标识符由字母,数字,下划线,美元符组成。

    ii. 不能使用数字开头。

    iii. 不能使用关键字(JAVA中关键字均为小写)。

  f) Java命名规范:变量名均为小写。如果变量名由多个单词组成,从第二个单词开始,每个单词首字母大小,其它均为小写(如:userName,userAge,password)

常量(最终变量)

  a) 使用final关键字。

    final datatype CONSTANTNAME = VALUE;

    final double PI = 3.14159;

  b) 从不改变的永久数据(即常量只能赋值一次)

类型转换

基本数据类型的类型转换

基本类型比较大小

​ 先比较精度,精度大的类型大。如果精度相同,比较字节数,字节数大的类型大。

自动转换

​ JVM会自动将小类型转换为大的类型。

1
2
3
4
5
6
byte b1 = 127;
byte b2 = (byte)128; //-128
byte b3 = (byte)129; //-127
byte b4 = (byte)130; //-126

byte的范围:-128 ~ 127

从小到大byte,short,char—int—long—float—double

float 比 long类型大?

​ long:8个字节 -263 ~ 263-1

​ float:4个字节 -3.4028235E+38~3.4028235E+38

3.4*1038 > 2*1038 > 2*838 = 2*(23)38 = 2*2114 > 263-1

​ 它们的底层存储结构不同,float表示的数据范围比long的范围要大。

手动转换(强制转换)

​ 使用:将大类型转换为小类型。精度损失问题

​ 格式:目标数据类型 变量名 = (目标数据类型) (被转换的数据);

注意: boolean类型不能转换为其他的数据类型

​ 默认转换(从小到大的转换)

​ A:byte,short,char—int—long—float—double

​ B:byte,short,char相互之间不转换,他们参与运算首先转换为int类型

Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 定义一个byte类型,一个int类型,做加法
byte a = 3;
int b = 4;

byte c = a + b; // 这个是有问题的

int c = a + b; // 可能损失精度

byte c = (byte) (a + b); // 用强制类型转换改进

System.out.println((int) 1.7); // 结果为1,当double型值被转换为int型值时,小数部分被截去

System.out.println((double) 1 / 2); // 结果为0.5,因为1首先被转换为1.0,然后用2除1.0

System.out.println(1 / 2); // 结果为0,因为1和2都是整数,那么对他们做除法的结果也必须是整数

double d = 4.5;

int i = (int) d; // 类型转换不改变被转换的变量,d在类型转换之后值不变。

思考题

一:哪句是编译失败的呢?为什么呢?

  byte b1=3,b2=4,b;

  b=b1+b2; //有问题的,是类型提升。先将b1和b2转换为int型后参与运算。

  b=3+4; //只要整形直接量是在目标变量允许的范围内,那么将整形直接量赋给short型或byte型变量时,就不需要显示的类型转换。

二:分析

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
  byte a = 130; // 有问题,因为byte的范围是:-128到127。

  byte b = (byte) 130;
  System.out.println(b); // -126

  byte c = (byte) 300;
  System.out.println(c); // 44

/*
分析过程:
我们要想知道结果是什么,就应该知道是如何进行计算的。
而我们又知道计算机中数据的运算都是补码进行的,要得到补码,首先要计算出数据的二进制。
byte,short,char相互之间不转换,他们参与运算首先转换为int类型。

A:获取130这个数据的二进制。
00000000 00000000 00000000 10000010
这是130的原码,也是反码,还是补码。
B:做截取操作,截成byte类型的了。
10000010
这个结果是补码。
C:已知补码求原码。
符号位 数值位
补码: 1 0000010
反码: 1 0000001
原码: 1 1111110
- 2+4+8+16+32+64=126
*/

三:找问题

1
2
3
4
5
  double d = 12.345;

  float f = d; // 编译错误

  float f = (float) d; // 编译成功。把double赋值给float,加了强制类型转换

四:下面两个定义有没有区别?

1
2
3
  float f1 = (float) 12.345; // f1其实是通过一个double类型转换过来的。

  float f2 = 12.345f; // f2本身就是一个float类型。

字符型与数值型的转换

char型 转 数值型

char型数据可以转换成任意一种数值类型

  char型数据转换成数值型,字符的统一码就被转换成某个特定的数值。

1
2
3
int i = (int)'A';;

System.out.println(i); //65

数值型 转 char型

​ 整数转换成char类型,只用到该数据的低十六位,其余部分都被忽略。例如:

1
2
3
char ch = (char)0XAB0041;

System.out.println(ch); //A

​ 浮点型转换成char型,首先将浮点值转换成int型,然后将int型转换为char型。

1
2
3
char ch = (char)65.25;

System.out.println(ch); //A

提示

转换结果适用于目标变量,就可以使用隐士转换方式;否则,必须使用显示转换方式:

1
2
3
byte b = 'a'; // 隐士转换

int i = 'a'; // 隐士转换

因为统一码 \uFFF4 不适用于一个字节范围内,下面的转换就是不正确的:

1
byte b = '\uFFF4';

为了强制赋值,就必须使用显示转换方式:

1
byte b = (byte) '\uFFF4';

总结

  所有数值运算符都可以用在char型操作数上。

  如果另一个操作数是一个数字或字符,那么char型操作数就会被自动转换成一个数字。

  如果另一个操作数是一个字符串,字符就会与该字符串相连。

字符参与运算

    是查找ASCII里面的值

      ‘a’ 97

      ‘A’ 65

      ‘0’ 48

    System.out.println(‘a’);

    System.out.println(‘a’ + 1);

字符串参与运算

    这里其实是字符串的连接

    System.out.println(“hello”+’a’+1); // helloa1;字符串数据和其他数据做+,结果是字符串类型。这里的+不是加法运算,而是字符串连接符。

    System.out.println(‘a’+1+”hello”); //结果为:98hello ‘a’是字符不是字符串

    System.out.println(“5+5=”+5+5); //5+5=55

    System.out.println(5+5+”=5+5”); //10=5+5

运算符

显示当前时间

  a). 调用System.currentTimeMillis()方法获取存放在变量totalMilliseconds中从1970年1月1日午夜到现在的毫秒数(例如:1203183086328毫秒)。

  b). 通过将总毫秒数totalMilliseconds除以1000得到总秒数totalSeconds(例如:1203183086328毫秒/1000 = 1203183086秒)。

  c). 通过totalSeconds%60得到当前的秒数(例如:1203183086秒%60 = 26,这个值就是当前秒数)。

  d). 通过将totalSeconds除以60得到总的分钟数totalMinutes(例如:1203183086秒/60 = 20053051分钟)。

  e). 通过totalMinutes%60得到当前分钟数(例如:20053051分钟%60 = 31,这个值就是当前分钟数)。

  f). 通过将总分钟数totalMinutes除以60获得总的小时数totalHours(例如:20053051分钟/60 = 334217小时)。

  g). 通过totalHours%24得到当前的小时数(例如:334217小时%24 = 17,该值就是当前小时数)。

算术运算符

+,-,*,/,%,++,–

a). +的用法

​ 1:加法

​ 2:正号

​ 3:字符串连接符

    System.out.println(“hello”+’a’+1); helloa1

    System.out.println(‘a’+1+”hello”); 98hello

b). /和%的区别

数据做除法操作的时候,/取得是商,%取得是余数

1
2
3
4
5
6
7
8
int x = 3, y = 4;

System.out.println(x + y); // 7
System.out.println(x - y); // -1
System.out.println(x * y); // 12
System.out.println(x / y); // 0
System.out.println(x * 1.0 / y); // 0.75
System.out.println(x % y); // 3

c). 算术运算结果的类型

​ 1. 当参与运算的元素类型相同时,结果的类型一定与运算元素的类型一致。

​ 2. 当参与运算的元素类型不同时,结果的类型一定与运算中类型大的元素类型一致。

1
2
3
4
5
short s = 1;      //值在类型的取值范围内时,JVM会自动将值转换为需要的类型

s = s + 1; //错误,结果的类型为int类型,不能直接赋给short.

s += 1; //正确,+=会自动转换结果的类型

d). ++ 和 –

​ ++/–可以出现在变量的前面/后面。无论出现在前面/后面,代码执行后变量一定加1/减1

​ ++/–出现在前面:先参与计算,再取值。

​ ++/–出现在后面:先取值,再参与计算。

    int y = (x++)+(++x)+(x*10); //4+6+60

1
2
3
4
 //交换两个变量的值(不通过第三个变量实现)
 x = x + y;
 y = x - y;
 x = x - y;

比较运算符

>,>=,<,<=,==,!=

a). 比较运算的结果一定为boolean类型

b). JAVA中不是所有的类型都可以使用比较运算符进行比较。如:boolean与其它类型。基本数据类型不能与引用数据类型进行比较。

逻辑运算符

&,|,!,&&,||,^

a). 逻辑与(&),逻辑或(|)

img

b). 短路与

​ &&,当第一个表达式为false时,不执行第二个表达式,直接返回false

c). 短路或

​ ||,当第一个表达式为true时,不执行第二个表达式,直接返回true

d). 逻辑非

​ !,取反

e). 异或^

​ 相同则false,不同则true。

扩展运算符

+=,-=,*=,/=,%=,扩展运算符会自动转换结果的类型

1
2
3
  short s = 1;
  s += 1; //正确,+=会自动转换结果的类型
  //不是等价于 s = s + 1; 而是等价于 s = (s的数据类型)(s + 1);

位运算符

&,|,^,~,<<,>>,>>>

a). 与、或、异或、取反

注意

​ 要做位运算,首先要把数据转换为二进制

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
// &,|,^,~
int a = 3;
int b = 4;
System.out.println(3 & 4);
System.out.println(3 | 4);
System.out.println(3 ^ 4);
System.out.println(~3);
/*
分析:因为是位运算,所以我们必须先把数据换算成二进制。
3的二进制:11
00000000 00000000 00000000 00000011
4的二进制:100
00000000 00000000 00000000 00000100

&位与运算:有0则0。
00000000 00000000 00000000 00000011
&00000000 00000000 00000000 00000100
-----------------------------------
00000000 00000000 00000000 00000000
结果是:0

|位或运算:有1则1。
00000000 00000000 00000000 00000011
|00000000 00000000 00000000 00000100
-----------------------------------
00000000 00000000 00000000 00000111
结果是:7

^位异或运算:相同则0,不同则1。
00000000 00000000 00000000 00000011
^00000000 00000000 00000000 00000100
-----------------------------------
00000000 00000000 00000000 00000111
结果是:7

~按位取反运算符:0变1,1变0
00000000 00000000 00000000 00000011
~11111111 11111111 11111111 11111100 (补码)
补码:11111111 11111111 11111111 11111100
反码:11111111 11111111 11111111 11111011
原码:10000000 00000000 00000000 00000100
结果是:-4
*/

​ 一个数据针对另一个数据位异或两次,该数不变

1
2
3
4
5
int a = 10;
int b = 20;

System.out.println(a ^ b ^ b); //10
System.out.println(a ^ b ^ a); //20

b). 左移、右移、无符号右移

​ 左移(<<)     左边最高位丢弃,右边补齐0

​ 右移(>>)     右边数值位丢弃,最高位是0,左边补齐0;最高为是1,左边补齐1

​ 无符号右移(>>>) 右边数值位丢弃,无论最高位是0还是1,左边补齐0

思考题

一:请用最有效率的方式计算出2乘以8的结果

      2<<3

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
// <<,把<<左边的数据乘以2的移动次幂
System.out.println(3 << 2); // 3*2^2 = 3*4 = 12;

// >>,把>>左边的数据除以2的移动次幂
System.out.println(24 >> 2); // 24/2^2 = 24/4 = 6
System.out.println(24 >>> 2); // 6

System.out.println(-24 >> 2); // -6
System.out.println(-24 >>> 2); // 1073741818
System.out.println(0b00111111111111111111111111111010); // 1073741818

/*
计算出3的二进制:11
00000000 00000000 00000000 00000011
(00)000000 00000000 00000000 0000001100

----------------------------------------------
计算出-24的二进制
原码:10000000 00000000 00000000 00011000

>> 2的移动:
原码:10000000 00000000 00000000 00011000
反码:11111111 11111111 11111111 11100111
补码:11111111 11111111 11111111 11101000

11111111 11111111 11111111 11101000
1111111111 11111111 11111111 111010(00) 补码
补码:1111111111 11111111 11111111 111010
反码:1111111111 11111111 11111111 111001
原码:1000000000 00000000 00000000 000110
结果:-6

>>> 2的移动:
原码:10000000 00000000 00000000 00011000
反码:11111111 11111111 11111111 11100111
补码:11111111 11111111 11111111 11101000

11111111 11111111 11111111 11101000
0011111111 11111111 11111111 111010(00)
结果:1073741818
----------------------------------------------
*/

二:请实现两个变量的交换

​ int a = 10;

​ int b = 20;

方式1:采用第三方变量

1
2
3
4
int c = a;
a = b;
b = c;
System.out.println("a:"+a+",b:"+b);

方式2:用位异或运算符(面试用)

1
2
3
4
5
6
// 左边a,b,a
// 右边a^b
a = a ^ b;
b = a ^ b; // a ^ b ^ b = a
a = a ^ b; // a ^ b ^ a = b
System.out.println("a:"+a+",b:"+b);

方式3:用变量相加的做法

1
2
3
4
a = a + b; //a=30
b = a - b; //b=10
a = a - b; //a=20
System.out.println("a:"+a+",b:"+b);

方式4:一句话搞定

1
2
b = (a+b) - (a=b); //b=30-20=10,a=20
System.out.println("a:"+a+",b:"+b);

三元运算符(三目运算符)

​ x ? y : z ;x是一个boolean类型。当x为true时,返回y的值。当x为false时,返回z的值。

    int z = ((x = y)? x : y); // 报错,这是赋值符号。

​ 获取三个整数中的最大值

    int a = 10,b = 30,c = 20;

    int max2 = (a > b)?((a > c)? a: c):((b > c)? b: c);

    int max2 = a > b?a > c? a: c:b > c? b: c; // 这种做法不推荐。

    int i,j,k; i=j=k=1; // 该语句正确

键盘录入

1
2
3
4
5
6
import java.util.Scanner;

Scanner input = new Scanner(System.in); //创建键盘录入对象
int a= input.nextInt(); //通过对象获取数据
input.next(); //读取一个字符串,该字符串在一个空白符之前结束
input.nextLine(); //读取一行文本(即以按下回车键为结束标志)

格式化输出

a) System.out.print(): //打印不换行。必须有参数。

b) System.out.println(): //将光标移到下一行(打印换行)。可以没有参数。

c) System.out.printf(“%f”,a); //格式化输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 定义一些变量,用来格式化输出。
double d = 345.678;
String s = "你好!";
int i = 1234;

// "%"表示进行格式化输出,"%"之后的内容为格式的定义。
System.out.printf("%f", d); // "f"表示格式化输出浮点数。
System.out.printf("%9.2f", d); // "9.2"中的9表示输出的长度,2表示小数点后的位数。
System.out.printf("%+9.2f", d); // "+"表示输出的数带正负号。
System.out.printf("%-9.4f", d); // "-"表示输出的数左对齐(默认为右对齐)。
System.out.printf("%+-9.3f", d); // "+-"表示输出的数带正负号且左对齐。
System.out.printf("%d", i); // "d"表示输出十进制整数。
System.out.printf("%o", i); // "o"表示输出八进制整数。
System.out.printf("%x", i); // "d"表示输出十六进制整数。
System.out.printf("%#x", i); // "d"表示输出带有十六进制标志的整数。
System.out.printf("%s", s); // "d"表示输出字符串。
System.out.printf("输出一个浮点数:%f,一个整数:%d,一个字符串:%s", d, i, s); // 可以输出多个变量,注意顺序。
System.out.printf("字符串:%2$s,%1$d的十六进制数:%1$#x", i, s); // "X$"表示第几个变量。

流程控制

顺序结构

​ 从上往下,依次执行

选择结构

​ 按照不同的选择,执行不同的代码

if 语句

​ 格式(三种)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
if(布尔表达式){
代码;
}

if(条件){
代码;
}else{
代码;
}

if(条件){
代码;
}else if(条件){
代码;
} else if(条件){
代码;
}
……
else{
代码;
}

​ 注意事项

​ 1) if语句中条件的结果必须为boolean类型。

​ 2) 一个if语句中可以有0个或1个else语句。

​ 3) else语句必须出现在if语句的最后。

​ 4) 一个if语句中可以有0个或多个else if语句。

5) 当匹配到一个分支后,不再匹配其它的分支。

​ 6) if的大括号可以省略,如果省略if的作用范围只有一行JAVA代码。

​ 三元运算符和if语句第二种格式的关系

​ 所有的三元运算符能够实现的,if语句的第二种格式都能实现。反之不成立,如果if语句第二种格式控制的语句体是输出语句,就不可以。因为三元运算符是一个运算符,必须要有一个结果返回,不能是一个输出语句。

switch 语句

​ 格式:

1
2
3
4
5
6
7
8
9
10
11
12
switch(switch表达式){
case1:
语句(组)1;
break;
case2:      //case:后面的值就是要和表达式进行比较的值
语句(组)2;
break;
……
default:      //如果所有的情况都不匹配,就执行这里,相当于if语句中的else
语句(组)n+1;
break;     //表示程序到这里中断,跳出switch语句
}

​ 注意事项

​ 1) switch语句中的表达式只能为byte,short,int,char。从JDK1.5开始可以使用枚举类型。从JDK1.7开始可以使用String。

​ 2) case后面的值不能重复

​ 3) case后面只能为常量或字面值

​ 4) case后面可以为算术表达式。

5) 当匹配到一个分支后,switch会从此分支开始自顶向下执行所有的分支,直到switch的结束或遇到第一个break为止。

​ 6) default可以出现在switch语句中的任意位置。

​ 7) 无论default出现在哪,switch都会先匹配所有的case分支。如果没有匹配到任何case分支后,再执行default分支。

​ 8) break可以省略,但是结果可能不是我们想要的。会出现一个现象:case穿透(如下示例)。建议不要省略

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
switch (month) {
case 1:
case 2:
case 12:
System.out.println("冬季");
break;
case 3:
case 4:
case 5:
System.out.println("春季");
break;
case 6:
case 7:
case 8:
System.out.println("夏季");
break;
case 9:
case 10:
case 11:
System.out.println("秋季");
break;
default:
System.out.println("你输入的月份有误");
}

​ 9) default可以省略,但是不建议,因为它的作用是对不正确的情况给出提示。

if 和 switch 的区别

    if语句:

      A:针对结果是boolean类型的判断

      B:针对一个范围的判断

      C:针对几个常量值的判断

    switch语句:

      针对几个常量值的判断

循环结构

​ 做一些重复的代码

while循环

​ 当不确定循环次数时,建议使用

​ 格式:

1
2
3
4
while(循环条件){
// 循环体
语句(组);
}

​ 注意事项

​ 1) 当循环条件返回true,执行循环。当循环条件返回false,结束循环。

​ 2) 循环条件的结果必须为boolean类型。

3) while:先判断,再循环。

do..while循环

​ 当不确定循环次数时,建议使用

​ 格式:

1
2
3
4
do {
//循环体
语句(组);
} while (循环条件);

​ 注意事项

​ 1) 大括号不能省略。

2) do..while:先循环,再判断。至少会循环一次。

for循环

​ 当确定循环次数时,建议使用

​ 格式:

1
2
3
4
5
6
7
8
for(初始操作;循环条件;每次迭代后的操作){
//循环体
语句(组);
}

for ( int i = 1 ; i < 100 ; System.out.println(i), i++); //该语句正确

for ( ; ; )

​ 注意事项

​ 1) for循环的三部分都可以省略。

​ 2) Math.random():返回大于等于0.0,小于1.0的double类型的随机数。0.0—0.99999999999999999

​ 3) for循环第一部分声明变量只能在for循环内使用。

​ 4) for循环的第一部分可以同时声明多个类型相同的变量

demo

一:求出1-100之间偶数和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 方式1
int sum2 = 0;
for (int x = 1; x <= 100; x++) {
if (x % 2 == 0) {
sum2 += x;
}
}
System.out.println(sum2); // 2550

// 方式2
int sum3 = 0;
for (int x = 0; x <= 100; x += 2) {
sum3 += x;
}
System.out.println(sum3); // 2550

二:在控制台输出所有的”水仙花数”

水仙花数是指一个 n 位正整数 ( n≥3 ),它的每个位上的数字的 n 次幂之和等于它本身。(例如:1^3 + 5^3+ 3^3 = 153)

这里以三位正整数为例:

1
2
3
4
5
6
7
8
9
10
11
for (int x = 100; x < 1000; x++) {
int ge = x % 10;
int shi = x / 10 % 10;
int bai = x / 10 / 10 % 10;
// 让ge*ge*ge+shi*shi*shi+bai*bai*bai和该数据比较
if (x == (ge * ge * ge + shi * shi * shi + bai * bai * bai)) {
// 如果相同,就把该数据在控制台输出。
System.out.println(x);
}
}
// 结果:153、370、371、407

中断循环

​ 1. break(中断):只能出现在switch语句与循环语句中。出现在循环语句中的作用:立即结束所在循环

​ 2. continue(继续):只能出现在循环语句。作用:立即结束本次循环,使所在循环直接进入下一次循环

​ 3. return(返回):用于结束方法的(作用不是结束循环),一旦遇到return,程序就不会在继续往后执行。

for 和 while 的区别

​ 1. 使用上的区别

​ for语句的那个控制条件变量,在循环结束后不能在使用了。而while的可以继续使用。

​ 2. 理解上的区别

​ for适合于一个范围的判断,while适合次数不明确的。

嵌套循环

​ 1. 请输出一个4行5列的星星(*)图案

1
2
3
4
5
6
7
8
9
10
11
12
/*  
*****
*****
*****
*****
*/
for (int y = 0; y < 4; y++) {
for (int x = 0; x < 5; x++) {
System.out.print("*");
}
System.out.println();
}

​ 2. 请输出下列的形状

1
2
3
4
5
6
7
8
9
10
11
// *
// **
// ***
// ****
// *****
for (int x = 0; x < 5; x++) {
for (int y = 0; y <= x; y++) {
System.out.print("*");
}
System.out.println();
}

​ 3. 在控制台输出九九乘法表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 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*9=9 2*9=18 3*9=27 ...
for (int x = 1; x <= 9; x++) {
for (int y = 1; y <= x; y++) {
System.out.print(y + "*" + x + "=" + y * x + "\t");
}
System.out.println();
}
// '\x' x表示任意,这种做法叫转移字符。
//
// '\t' tab键的位置
//
// '\r' 回车
//
// '\n' 换行

数组

​ 一组相同数据类型的集合。

​ JAVA中的数组都是引用数据类型。但数组中的元素可以为基本数据类型,也可以为引用数据类型。

一维数组

​ 声明一维数组:数据类型[] 数组名/数据类型 数组名[];在栈中开辟一个空间,保存数据的名字(首地址)。在声明数组时不能指定数组的长度

​ 创建一维数组:在堆中开辟连续的空间。所以在创建数组时必须指定数组的长度。

1
2
3
4
5
6
int[] array = { 10, 20, 30, 40 }; // 静态初始化,给出值,系统决定长度

int array[] = { 10, 20, 30, 40 }; // 该定义格式就忘了吧!

double[] array1 = new double[10]; // 动态初始化,只给长度,系统给出默认值
String[] array2 = new String[] { "abc", "def", "123" };

img

​ 注意事项

​ 1. 使用下标访问数组中的元素,[]

​ 2. 数组的下标从0开始,最大下标数组的长度减1.

​ 3. 数组中的默认值:byte,short,int默认为0,long默认为0L,float默认为0.0F,double默认为0.0,char默认为’\u0000’,boolean默认为false。

​ 4. 引用数据类型默认为null。

​ 5. 数组的长度确定后不能改变

​ 6. 数组的长度可以为0,但不能为负数,否则运行时发生异常。

​ 7. 通过数组的.length属性,获得数组的长度。

Java的内存分配

​ A:栈 存储局部变量

​ B:堆 存储所有new出来的

​ C:方法区(面向对象部分详细讲解)

​ D:本地方法区(系统相关)

​ E:寄存器(CPU使用)

​ 注意:

​ a:局部变量 在方法定义中或者方法声明上定义的变量。

​ b:栈内存和堆内存的区别

:数据使用完毕,就消失。

:1)每一个new出来的东西都有地址。

​ 2)每一个变量都有默认值。

​ 3)数据使用完毕后,在垃圾回收器空闲的时候回收。

数组与循环

​ foreach循环:从JDK1.5开始出现。

​ a) 作用:遍历集合

​ b) 格式:

1
2
3
for(数据类型 变量名 :集合名){
代码;
}

​ c) 通常用于从集合取数据

命令行参数

​ a) 格式:java 类名 命令行参数

​ b) 命令行参数由main()中参数String[]数组接收。

​ c) 命令行参数以空格作为分隔的标记。

二维数组

​ 元素是一维数组的数组。

​ 格式:

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
	A:数据类型[][] 数组名 = new 数据类型[m][n];	// m:表示这个二维数组有多少个一维数组。n:表示每一个一维数组的元素有多少个。
a:数据类型 数组名[][] = new 数据类型[m][n];
b:数据类型[] 数组名[] = new 数据类型[m][n];
B:数据类型[][] 数组名 = new 数据类型[m][]; // m:表示这个二维数组有多少个一维数组。列数没有给出,可以动态的给。

/*************************************************************************************/
int[][] arr = new int[3][]; // 定义数组
System.out.println(arr); // [[I@175078b
System.out.println(arr[0]); // null
System.out.println(arr[1]); // null
System.out.println(arr[2]); // null

// 动态的为每一个一维数组分配空间
arr[0] = new int[2];
arr[1] = new int[3];
arr[2] = new int[1];
System.out.println(arr[0]); // [I@42552c
System.out.println(arr[1]); // [I@e5bbd6
System.out.println(arr[2]); // [I@8ee016
System.out.println(arr[0][0]); // 0
System.out.println(arr[0][1]); // 0
System.out.println(arr[0][2]); // 错误,ArrayIndexOutOfBoundsException
/*************************************************************************************/

C:数据类型[][] 数组名 = new 数据类型[][]{{...},{...},{...}};

D:数据类型[][] 数组名 = {{...},{...},{...}};

/*************************************************************************************/
int[][] arr = { { 1, 2, 3 }, { 4, 5 }, { 6 } }; // 定义数组

System.out.println(arr); // [[I@7852e922
System.out.println(arr[0]); // [I@4e25154f
System.out.println(arr[1]); // [I@70dea4e
System.out.println(arr[2]); // [I@5c647e05
System.out.println(arr[0][0]); // 1
System.out.println(arr[1][0]); // 4
System.out.println(arr[2][0]); // 6
System.out.println(arr[0][1]); // 2
System.out.println(arr[1][1]); // 5
System.out.println(arr[2][1]); // 错误,越界
/*************************************************************************************/

​ 注意下面定义的区别:

1
2
3
4
5
6
7
int x;
int y;
int x,y;

int[] x;
int[] y[];
int[] x,y[];

​ 案例:

​ A:二维数组的遍历

​ B:二维数组的求和

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class ArrayTest {
public static void main(String[] args) {
int[][] arr2 = { { 1, 2, 3 }, { 4, 5 }, { 6 } };
printArray2(arr2);
}

public static void printArray2(int[][] arr) {
int sum = 0;
for (int x = 0; x < arr.length; x++) {
for (int y = 0; y < arr[x].length; y++) {
System.out.print(arr[x][y] + " ");
sum += arr[x][y];
}
System.out.println();
}
System.out.println(sum);
}
}

​ C:杨辉三角形(行数可以键盘录入)

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
/**
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
分析:看这种图像的规律
A:任何一行的第一列和最后一列都是1
B:从第三行开始,每一个数据是它上一行的前一列和它上一行的本列之和。
*/
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个数据:");
int n = sc.nextInt();

// 1、首先定义一个二维数组。行数如果是n,我们把列数也先定义为n。
int[][] arr = new int[n][n];

// 2、给这个二维数组任何一行的第一列和最后一列赋值为1
for (int x = 0; x < arr.length; x++) {
arr[x][0] = 1; // 任何一行第1列
arr[x][x] = 1; // 任何一行的最后1列
}

// 3、按照规律给其他元素赋值。从第三行开始,每一个数据是它上一行的前一列和它上一行的本列之和。
for (int x = 2; x < arr.length; x++) {
// 这里如果y<=x是有个小问题的,就是最后一列的问题,所以这里要减去1,并且y也应该从1开始,因为第一列也是有值了
for (int y = 1; y <= x - 1; y++) {
// 每一个数据是它上一行的前一列和它上一行的本列之和。
arr[x][y] = arr[x - 1][y - 1] + arr[x - 1][y];
}
}

// 4、遍历这个二维数组。
for (int x = 0; x < arr.length; x++) {
for (int y = 0; y < arr[x].length; y++) {
System.out.print(arr[x][y] + "\t");
}
System.out.println();
}

// 这个时候,要注意了,内循环的变化必须和曾经讲过的九九乘法表类似
for (int x = 0; x < arr.length; x++) {
for (int y = 0; y <= x; y++) {
System.out.print(arr[x][y] + "\t");
}
System.out.println();
}

Java中只有值传递

​ 基本类型:形式参数的改变不影响实际参数

​ 引用类型:形式参数的改变直接影响实际参数