摘要:本文学习了Java编程的基础知识。
环境
Windows 10 企业版 LTSC 21H2
Java 1.8
1 注释
支持多种注释方式:
- 行注释:可以注释单行内容,使用
//
注释从当前位置到行结尾。 - 块注释:可以注释多行内容,使用
/*
和*/
注释两个符号之间的内容。 - 文档注释:可以生成文档,使用
/**
标记文档开始,使用*/
标记文档结束,每行开头使用*
标记文档内容。
2 命名
2.1 标识符
为各种变量、方法、类和包等起的名字,统统称之为标识符。
命名规则:
- 应以字母、下划线、美元符开头,不能以数字开头,不能使用空格或非法的字符,如:#,%,&等。
- 后跟字母、下划线、美元符、数字。
- 大小写敏感,长度无限制。
- 不能使用关键字。
命名约定:
- 类和接口的首字母大写,比如TestClass。
- 方法的首字母小写,其余首字母大写,尽量少用下划线,比如setTime。这种命名方法叫做驼峰式命名。
- 基本数据类型常量的全部字母都大写,字与字之间用下划线分隔,比如SIZE_NAME。对象常量可大小混写,比如Person。
- 变量可大小写混写,首字母小写,字间分隔符的首字母大写。不用下划线,少用美元符号。
2.2 关键字
关键字对编译器有特殊意义,它们用来表示一种数据类型,或则表示程序的结构等,关键字不能用作变量名、方法名、类名、包名和参数名。
常见关键字:
分类 | 关键字 | 说明 |
---|---|---|
保留字 | const | 其他计算机语言中的关键字,用于修改字段或局部变量的声明,指定字段或局部变量的值是常数,不能被修改。 |
goto | 其他计算机语言中的关键字,指定跳转到标签,找到标签后,程序将处理从下一行开始的命令。 | |
包相关 | import | 引入包的关键字。 |
package | 定义包的关键字。 | |
访问控制 | public | 公有的,可跨包使用。 |
protected | 受保护的,只能在当前包内使用。 | |
private | 私有的,当前类可用。 | |
异常处理 | try | 执行有可能抛出异常的代码块。 |
catch | 捕获异常。 | |
throw | 抛出一个异常对象。 | |
finally | 有没有异常都执行的代码块。 | |
throws | 声明一个异常,可能被抛出。 | |
实例相关 | new | 新建,用于创建类的实例。 |
this | 本类,用于引用当前实例。 | |
super | 父类,用于引用当前实例所属类的父类。也成为超类 | |
instanceof | 实例,用于确定对象所属的类。 | |
特殊值 | true | boolean类型的值,表示真。 |
false | boolean类型的值,表示假。 | |
null | 空值。 | |
数据类型 | byte | 字节型的数据。 |
char | 字符型的数据。 | |
boolean | 布尔型的数据。 | |
short | 短整型的数据。 | |
int | 整型的数据。 | |
float | 浮点型的数据。 | |
long | 长整型的数据。 | |
double | 双精度的数据。 | |
void | 表示null类型或者无返回值。 | |
流程控制 | if | 如果,指示有条件地执行代码块。条件的计算结果必须是布尔值。 |
else | 否则,与if关键字结合使用。else子句是可选的,如果if条件为false,则执行该子句。 | |
for | 循环,用于指定一个在每次迭代结束前检查其条件的循环。 | |
while | 循环,用于指定一个只要条件为真就会重复的循环。 | |
do | 运行,用于指定一个在每次迭代结束时检查其条件的循环。 | |
switch | 观察,基于某个表达式,选择执行多个代码块中的某一个。 | |
case | 返回观察里的结果,用来标记switch语句中的每个分支。 | |
default | 默认,用来标记switch语句中的默认分支。 | |
break | 跳出,中断,关键字用于提前退出循环。 | |
continue | 继续,用来跳转到循环的下一个迭代。 | |
return | 返回,会导致方法返回到调用它的方法,从而传递与返回类型匹配的值。 | |
类和接口 | class | 类,用来定义类。 |
interface | 接口,用来定义接口。 | |
extends | 继承,声明类和接口继承的父类和父接口。 | |
implements | 实现,声明类实现的接口。 | |
修饰 | abstract | 声明抽象,修饰类和方法。 |
final | 终极,不可改变的,修饰类和方法。 | |
static | 静态,意味着应用它的实体在声明该实体的类的任何特定实例外部可用。 | |
synchronized | 线程,同步。 | |
native | 本地,表示该方法是用Java以外的语言实现的。 | |
strictfp | 严格,精准,声明一个类、接口或者方法,所声明的范围内会完全依照浮点规范执行。 | |
transient | 短暂,应用于类的成员变量,表示成员变量不应被序列化。 | |
volatile | 易失,表示可以被多个线程异步修改的成员变量。 |
3 变量
3.1 定义
一块内存中的数据存储空间,因为里面的数据可以更改,所以称为变量。
分类:
- 局部变量:方法或语句块内部定义的变量,作用域是当前方法或当前语句块,需要在初始化时赋值,存在栈内存中。
- 成员变量:方法外部或类的内部定义的变量,作用域是整个类,有默认值,存在堆内存中。
3.2 常量
常量是特殊的变量,常量存储的数据不可以更改。
4 数据类型
4.1 说明
Java语言是一种强类型语言。通俗点说,在Java中存储的数据都是有类型的,而且必须在编译时就确定其类型。
4.2 分类
分类:
- 基本类型变量:保存原始值,它代表的值就是数值本身。通过值传递进行赋值。
- 引用类型变量:保存引用值,指向内存空间的地址,代表了某个对象的引用,对象本身存放在这个引用值所表示的地址的位置。通过引用传递进行赋值。
图示:
基本数据类型:
分类 | 类型 | 内容 | 默认值 | 大小 | 范围 |
---|---|---|---|---|---|
布尔型 | boolean | true false | false | 1bit | true false |
字符型 | char | Unicode字符集 | \u0000 | 16bits | \u0000 ~ \uFFFF |
整数类型 | byte | 带符号整数 | 0 | 8bits | -2^7 ~ 2^7-1 |
short | 带符号整数 | 0 | 16bits | -2^15 ~ 2^15-1 | |
int | 带符号整数 | 0 | 32bits | -2^31 ~ 2^31-1 | |
long | 带符号整数 | 0L | 64bits | -2^63 ~ 2^63-1 | |
浮点类型 | float | IEEE 754标准的浮点数 | 0.0f | 32bits | -2^63 ~ 2^63-1 |
double | IEEE 754标准的浮点数 | 0.0 | 64bits | -2^63 ~ 2^63-1 |
4.2.1 布尔型
boolean类型表示1位的信息,只有true和false两个取值,这种类型只作为一种标志来记录true和false情况。
默认值是false。
4.2.2 字符型
char类型是一个单一的16位Unicode字符,单引号括起来的单个字符表达,通常用16进制表示。
最小值是\u0000
(即为0),最大值是\uffff
(即为65535),可以当整数来用,它的每一个字符都对应一个数字。
字符常量指用单引号括起来的单个字符,比如'a'
和'A'
。请特别注意,字符的定界符是单引号,而非双引号。
除了以上所述形式的字符常量值之外,还有一种特殊形式的字符常量值,这通常用于表示难以用一般字符来表示的字符,这种特殊形式的字符是以一个\
开头的字符序列,称为转义字符。
常用转义字符:
转义字符 | 意义 | ASCII码值(十进制) |
---|---|---|
\a | 响铃(BEL) | 007 |
\b | 退格(BS),将当前位置移到前一列 | 008 |
\f | 换页(FF),将当前位置移到下一页 | 012 |
\n | 换行(LF),将当前位置移到下一行 | 010 |
\r | 回车(CR),将当前位置移到本行开头 | 013 |
\t | 水平制表(HT),跳到下一个TAB位置 | 009 |
\v | 垂直制表(VT) | 011 |
\\ | 代表\反斜线字符 | 092 |
\' | 代表'单引号字符 | 039 |
\" | 代表"双引号字符 | 034 |
\0 | 空字符(NULL) | 000 |
4.2.3 整数类型
4.2.3.1 byte
byte类型是8位的有符号的以二进制补码表示的整数,占1字节。
最小值是-128(-2^7),最大值是127(2^7-1),默认值是0。
4.2.3.2 short
short类型是16位的有符号的以二进制补码表示的整数,占2字节。
最小值是-32768(-2^15),最大值是32767(2^15-1),默认值是0。
4.2.3.3 int
int类型是32位的有符号的以二进制补码表示的整数,占4字节。
最小值是-2^31,最大值是2^31-1,默认值是0。
4.2.3.4 long
long类型是64位的有符号的以二进制补码表示的整数,占8字节。
最小值是-2^63,最大值是2^63-1,默认值是0L。
4.2.4 浮点类型
4.2.4.1 float
float类型是32位的单精度的符合IEEE 754标准的浮点数,占4字节。
默认值是0.0F。
4.2.4.2 double
double类型是64位的双精度的符合IEEE 754标准的浮点数,占8字节。
默认值是0.0D,浮点数的默认类型为double类型。
4.3 类型转换
字符型、整型、浮点型的数据在混合运算中相互转换,遵循以下规则:
- boolean类型不可以转换为其他的数据类型。
- 容量小的类型自动转换为容量大的类型,顺序为:
- byte/short/char int long float double
- byte/short/char之间不会相互转换,他们在计算时会首先转为int类型。
- 容量大的数据类型转为容量小的数据类型时,要加上强制转换符,但可能造成精度降低或溢出。
- 有多种类型的数据类型混合运算时,首先自动将所有的数据转换成容量最大的数据类型,然后在进行计算。
5 运算符
5.1 说明
运算符用于执行程序代码运算,会针对一个以上操作数项目来进行运算。
支持如下运算符:
- 算术运算符:++,–,+,-,*,/,%。
- 赋值运算符:=,+=,-=,*=,/=,%=。
- 关系运算符:>,<,>=,<=,==,!=。
- 逻辑运算符:&,|,!,^,&&,||。
- 条件运算符:?:。
- 位运算符:&,|,~,^,>>,<<,>>>。
优先级如下图所示:
优先级 | 运算符 | 名称 | 结合性 |
---|---|---|---|
1 | . | 点 | 从左到右 |
() | 圆括号 | 从左到右 | |
[] | 方括号 | 从左到右 | |
2 | + | 取正 | 从右到左 |
- | 取负 | 从右到左 | |
++ | 自增 | 从右到左 | |
-- | 自减 | 从右到左 | |
~ | 按位非 | 从右到左 | |
! | 逻辑非 | 从右到左 | |
3 | * | 相乘 | 从左到右 |
/ | 相除 | 从左到右 | |
% | 取余 | 从左到右 | |
4 | + | 相加 | 从左到右 |
- | 相减 | 从左到右 | |
5 | << | 带符号左移 | 从左到右 |
>> | 带符号右移 | 从左到右 | |
>>> | 无符号右移 | 从左到右 | |
6 | < | 小于 | 从左到右 |
<= | 小于等于 | 从左到右 | |
> | 大于 | 从左到右 | |
>= | 大于等于 | 从左到右 | |
instanceof | 是否属于类 | 从左到右 | |
7 | == | 等于 | 从左到右 |
!= | 不等于 | 从左到右 | |
8 | & | 逻辑与(按位与) | 从左到右 |
9 | | | 逻辑或(按位或) | 从左到右 |
10 | ^ | 逻辑异或(按位异或) | 从左到右 |
11 | && | 短路与 | 从左到右 |
12 | || | 短路或 | 从左到右 |
13 | ?: | 条件运算符 | 从右到左 |
14 | = | 将右侧的值赋给左侧的变量 | 从右到左 |
+= | 左侧的变量加右侧的值取和,将和赋给左侧的变量 | 从右到左 | |
-= | 左侧的变量减右侧的值取差,将差赋给左侧的变量 | 从右到左 | |
*= | 左侧的变量乘右侧的值取积,将积赋给左侧的变量 | 从右到左 | |
/= | 左侧的变量除右侧的值取商,将商赋给左侧的变量 | 从右到左 | |
%= | 左侧的变量除右侧的值取余,将余赋给左侧的变量 | 从右到左 |
5.2 分类
5.2.1 算术运算符
算术运算符主要用于进行基本的算术运算,如加法、减法、乘法、除法等。
分类:
- 单目运算符主要有+(取正),-(取负),++(自增),–(自减)。
- 双目运算符主要有+(相加),-(相减),*(相乘),/(相除),%(取余)。
5.2.2 自增和自减
只能用来操作变量,不能用来操作数值或者常量。
自增(++)或自减(–)在变量后面,会先赋值,然后再计算:
1 | public static void main(String [] args) { |
自增(++)或自减(–)在变量前面,会先计算,然后再赋值:
1 | public static void main(String [] args) { |
5.2.3 赋值运算符
赋值运算符是指为变量或常量指定数值的符号,如可以使用=
将右边的表达式结果赋给左边的操作数。
说明:
a += b
等价于a = a + b
a -= b
等价于a = a - b
a *= b
等价于a = a * b
a /= b
等价于a = a / b
a %= b
等价于a = a % b
5.2.4 关系运算符
比较运算符用于判断两个数据的大小,如大于、等于、不等于,比较的结果是一个布尔值。
注意不要对浮点数进行相等性运算,比如1.0 - 0.3 == 0.7
。
注意:
- 使用
> < >= <=
只支持左右两边操作数是数值类型。 - 使用
== !=
两边的操作数既可以是数值类型,也可以是引用类型。
比较equals和==的区别:
变量类型 | 存储位置 | == | equals |
---|---|---|---|
值类型 | 栈 | 比较值是否相等 | 无(值类型通常使用==比较) |
引用类型 | 栈中存储地址,对象存储在堆中 | 比较地址是否相同(栈中内容是否相同) | 判断对象的内容是否相同 |
说明:
- ==比较的是地址,equals比较的是内容。当equals为true时,==不一定为true。
5.2.5 逻辑运算符
逻辑运算符主要用于进行逻辑运算:
- 逻辑与(&):只有当两边都为真,结果才为真,如果有一边为假,结果为假。
- 逻辑或(|):如果有一边为真,结果为真,只有当两边都为假,结果才为假。
- 逻辑非(!):当右边为假,结果为真,当右边为真,结果为假。
- 逻辑异或(^):当两边真假不一致,结果才为真,两边同为真或两边同为假,结果均为假。
- 短路与(&&):当左边为假,则不再判断右边,直接得出结果为假。
- 短路或(||):当左边为真,则不再判断右边,直接得出结果为真。
5.2.6 条件运算符
条件运算符(?:)也称为三元运算符。
语法:
1 | 布尔表达式 ? 表达式1 : 表达式2; |
运算过程:
- 如果布尔表达式的值为真,则返回表达式1的值。
- 如果布尔表达式的值为假,则返回表达式2的值。
5.2.7 位运算符
主要有按位与(&),按位或(|),按位非(~),按位异或(^),带符号左移(<<),带符号右移(>>),无符号右移(>>>)。
位运算是以二进制位为单位进行的运算,其操作数和运算结果都是整型值。
位运算与逻辑运算的相应操作的真值表完全相同,其差别只是位运算操作的操作数和运算结果都是二进制整数,而逻辑运算相应操作的操作数和运算结果都是逻辑值布尔型。
移位运算符:
- 带符号左移(<<)是将一个二进制数按指定移动的位数向左移位,移掉的被丢弃,右边移进的部分正数补0负数补1。将一个数带符号左移会使该值乘以2的幂。
- 带符号右移(>>)是将一个二进制数按指定移动的位数向右移位,移掉的被丢弃,左边移进的部分正数补0负数补1。将一个数带符号右移会使该值除以2的幂。
- 无符号右移(>>>)是将一个二进制数按指定移动的位数向右移位,左边移进的部分始终补0,所以永远不会产生负号。将一个数无符号右移会使该值除以2的幂,如果是负数,可能会得到一个很大的正数。
6 进制
6.1 介绍
二进制的前缀是0B或0b,范围是0-1
。
八进制的前缀是0,范围是0-7
。
十进制不需要前缀,范围是0-9
。
十六进制的前缀是0X或0x,范围是0-9 A-F
或者0-9 a-f
。
6.2 转换
6.2.1 其他进制转换为十进制
6.2.1.1 二进制转换为十进制
从右往左开始计算,底数为2,指数从0开始依次递增,最后结果累加。
二进制数字0111
转为十进制的计算逻辑:
1 | 1 * 2 ^ 0 + 1 * 2 ^ 1 + 1 * 2 ^ 2 + 0 * 2 ^ 3 = 7 |
6.2.1.2 八进制转换为十进制
从右往左开始计算,底数为8,指数从0开始依次递增,最后结果累加。
八进制数字017
转为十进制的计算逻辑:
1 | 7 * 8 ^ 0 + 1 * 8 ^ 1 = 15 |
6.2.1.3 十六进制转换为十进制
从右往左开始计算,底数为16,指数从0开始依次递增,最后结果累加。
十六进制数字0x2c
转为十进制的计算逻辑:
1 | 12 * 16 ^ 0 + 2 * 16 ^ 1 = 44 |
6.2.2 十进制转换为其他进制
6.2.2.1 十进制转换为二进制
一直除以2,求出每次的余数,直到商为0为止,最后余数倒过来就是二进制数。
十进制数字10
转二进制数字为1010
。
6.2.2.2 十进制转换为八进制
一直除以8,求出每次的余数,直到商为0为止,最后余数倒过来就是八进制数。
十进制数字10
转八进制数字为012
。
6.2.2.3 十进制转换为十六进制
一直除以16,求出每次的余数,直到商为0为止,最后余数倒过来就是十六进制数。
十进制数字10
转十六进制数字为A
。
6.2.3 其他进制转换为二进制
6.2.3.1 八进制转换为二进制
从最低位开始算,每一位转换一个三位的二进制数,最后拼成一个最终的二进制数。
八进制数字0136
转二进制数字为000 001 011 110
。
6.2.3.2 十六进制转换为二进制
从最低位开始算,每一位转换成一个四位的二进制数,最后拼成一个最终的二进制数。
十六进制数字5E
转二进制数字为0101 1110
。
6.2.4 二进制转换为其他进制
6.2.4.1 二进制转换为八进制
从最低位开始算,每三位转换成一个十进制数,最后拼成一个八进制数。
二进制数字000 001 011 110
转八进制数字为0136
。
6.2.4.2 二进制转换为十六进制
从最低位开始算,每四位转换成一个十进制数,最后拼成一个十六进制数。
二进制数字0101 1110
转十六进制数字为5E
。
6.3 码制
相关概念:
- 原码:人最容易看得懂和理解的一种形式,进制转换都是原码。
- 反码:计算机为了让符号位参与运算,所以有了反码。
- 补码:计算机为了解决0的符号问题,所以有了补码。
- 移码:不管正负数,只要将其补码的符号位取反即可得到移码。
特点:
- 正数:正数的原码、反码、补码都一样。
- 负数:负数的反码符号位不变,其他位取反。负数对的补码符号位不变,在反码基础上加1。
7 流程控制
流程控制指的是在程序运行的过程中控制程序运行走向的方式。主要分为以下三种:
- 顺序结构:从上到下依次执行每条语句操作。
- 分支结构:根据条件判断执行哪些语句操作。
- 循环结构:根据循环初始条件和终结要求,执行循环体内的操作。
7.1 分支结构
分支结构有if
分支结构和switch
分支结构:
if
分支结构使用布尔表达式或者布尔值进行判断来进行分支的控制。switch
分支结构使用整数、String类型、枚举类型进行判断来进行分支的控制。
分支的各种情况要满足不重复,不遗漏的原则。相互独立,完全穷尽(MECE,Mutually Exclusive Collectively Exhaustive)。
7.1.1 if分支结构
7.1.1.1 if语句
语法:
1 | if (条件) { |
说明:
- 如果条件成立,执行大括号中的语句。
- 如果条件不成立,跳过大括号,执行后面的语句。
判断一个数字是否是正数:
1 | int i = 1; |
7.1.1.2 if … else语句
语法:
1 | if (条件) { |
说明:
- 如果条件成立,执行大括号中的语句。
- 如果条件不成立,执行else后面大括号中的语句。
判断成绩是否及格:
1 | int i = 58; |
7.1.1.3 if … else … if语句
语法:
1 | if (条件) { |
说明:
- 如果第一个条件成立,执行第一个条件后面大括号里的语句。
- 如果第一个条件不成立,判断下一个条件,依次类推。
- 如果所有条件都不成立,执行else中的语句。
判断成绩级别:
1 | int i = 78; |
7.1.2 switch分支结构
语法:
1 | switch (表达式) { |
说明:
- 拿着变量或表达式得到的值,去和各个case后面常量的值做判断,看是否匹配,
- 如果有匹配,则执行当前常量后面的语句,遇见break则跳出匹配,否则继续匹配。
- 如果没有匹配,则执行default后面的语句。
判断性别:
1 | int sex = 1; |
注意:
- switch只能做等值判断,支持基本类型的byte、short、int、char,在JDK1.7以后还支持引用类型的String和Enum。
- case后的常量值不可以重复。
- default可以省略,而且default位置也可以提到前面,只是不建议。
- break可以省略。
7.1.3 对比
相同点:
- 都可以实现分支结构。
不同点:
- 能用switch解决的题目肯定能用if解决,switch结构的效率比if结构的效率高。
- 能用if解决的题目不一定可以用switch解决,switch只能处理等值的条件判断,且条件是整型变量或字符变量的等值判断。
7.2 循环结构
循环语句也称作迭代语句,循环语句可以在满足条件的情况下反复执行某一段代码。
7.2.1 while循环结构
语法:
1 | while (条件) { |
说明:
- 先判断条件是否满足,如果不满足则跳出循环,如果满足则执行语句。
- 然后再次判断条件是否满足,直到条件不满足或跳出循环。
循环打印从0到10的数字:
1 | int i = 0; |
7.2.2 do … while循环结构
语法:
1 | do { |
说明:
- 先执行一次语句,然后判断条件是否满足,如果不满足则跳出循环,如果满足则执行循环语句。
- 继续判断条件是否满足,直到条件不满足或跳出循环。
循环打印从0到10的数字:
1 | int i = 0; |
7.2.3 for循环结构
语法:
1 | for (初始化表达式; 条件; 变量更新) { |
说明:
- 先执行一次初始化表达式,然后判断条件,如果不满足则跳出循环,如果满足则执行语句,然后执行变量更新。
- 判断条件是否满足,不满足则跳出,满足则执行语句和变量更新,直到条件不满足或跳出循环。
循环打印从0到10的数字:
1 | for (int i = 0; i <= 10; i++) { |
注意事项:
- 两个分号必不可少。
- 三个表达式可以不写,但有可能造成死循环。
- 表达式1可以有多个变量初始化,要用逗号隔开。
- 表达式3可以有多个变量更新,要用逗号隔开。
7.2.4 对比
相同点:
- 都具备循环的四要素:循环变量初始化,循环条件,循环操作(循环体),循环变量更新(迭代)。
不同点:
- 语法不同。
- 执行顺序不同,while循环和for循环都是先判断后执行,do-while是先执行后判断。
- 执行效率不同,do-while的执行效率最高。
7.3 跳转结构
跳转语句用于实现循环执行过程中程序流程的跳转。
7.3.1 break语句
在switch条件语句和循环语句中都可以使用break语句。
当它出现在switch条件语句中时,作用是终止某个case并跳出switch结构。
当它出现在循环语句中,作用是跳出循环语句,执行后面的代码。
循环打印从0到10的数字,要求当要打印6时停止循环:
1 | for (int i = 0; i <= 10; i++) { |
当条件判断i为6时,循环终止,不再打印6和之后的数字。
7.3.2 continue语句
只能用在循环语句中,它的作用是跳过本次循环,执行下一次循环。
循环打印从0到10的数字,要求当要打印6时跳过,继续打印剩下的:
1 | for (int i = 0; i <= 10; i++) { |
当条件判断i为6时,循环跳过,不再打印6,继续打印之后的数字。
7.3.3 return语句
用于跳出循环结构。
8 数组
8.1 定义
数组可以理解成保存一组数的容器,而变量可以理解为保存一个数的容器。
数组是一种引用类型,用于保存一组相同类型的数据。
数组定义的类型可以为任意类型,可以定义int类型的数组,也可以定义String类型的数组,或其他任何类型的数组。
数组实际在内存的存储和基本类型不同,实际上是在堆中申请空间保存一组数,栈中只是有一个地址的引用。
8.2 使用
8.2.1 声明
语法:
1 | 类型[] 数组名; |
示例:
1 | int[] sum; |
此时只是声明了一个数组变量,并没有在内存中开辟空间。
8.2.2 开辟空间
语法:
1 | 数组名 = new 类型[长度]; |
示例:
1 | sum = new int[5]; |
数组开辟空间时,必须要设置开辟的空间长度。
这时会根据类型对数组里的数据设置默认值。
8.2.3 赋值
语法:
1 | 数组名[下标] = 值; |
示例:
1 | sum[0] = 10; |
除了上面通过下标赋值,还可以在声明时开辟空间并赋值,或者在开辟空间时赋值。
语法:
1 | 数组名 = new 类型[]{值, 值}; |
示例:
1 | int[] sum = {1, 2}; |
在对数组进行赋值时,注意下标不要超过数组的长度范围,否则会产生错误。
在开辟空间时赋值,不需要在中括号里面填写数组长度。
8.2.4 访问元素
语法:
1 | 数组名[下标] |
示例:
1 | System.out.println(sum[0]); |
同样需要注意下标不要超过数组的长度范围。
8.2.5 注意
数组不赋值也有默认值。
数组中每个元素的赋值和访问都是通过数组名[下标]
实现的,不能直接使用数组名。
通过数组名.length
获取数组的长度,经常用在循环中,提高代码的维护性。
数组的下标从0
到数组名.length - 1
,如果不是这个范围,会导致一个数组下标越界的异常(ArrayIndexOutOfBoundsException)。
数组没有开辟空间直接使用,会导致一个空指针异常(NullPointerException)。
8.3 进阶使用
8.3.1 复制
8.3.1.1 复制引用地址
引用类型的数组复制的是引用地址,二者共同引用一个地址,其中一个对数组做了更改,都会影响另一个。
示例:
1 | int[] a1 = {1, 2, 3}; |
8.3.1.2 复制数值内容
基本类型的数组复制的是数值内容,实际上是一个备份,其中一个对它更改,不会影响另一个。
示例:
1 | int[] a1={1, 7, 8}; |
8.8.2 排序
示例:
1 | int[] nums = {1, 9, 3, 5, 2, 8, 4}; |
8.8.3 倒置
示例:
1 | int[] nums = {1, 9, 3, 5, 2, 8, 4}; |
8.4 工具类
排序:
1 | Arrays.sort(nums) |
填充:
1 | Arrays.fill(nums, 1) |
比较:
1 | Arrays.equals(a1, a2) |
转字符串:
1 | Arrays.toString(nums) |
8.5 二维数组
二维数组可以看做是一个数组,里面存放的元素是一维数组。
声明:
1 | int[][] nums; |
开辟空间:
1 | nums = new int[3][];// 行固定,列不固定 |
数组赋值:
- 动态初始化,使用时赋值,需要指明行和列:
java 1
nums[0][1] = 1;
- 静态初始化,声明时赋值,不必也不能指明行和列,否则会提示错误:
java 1
2int[][] nums = new int[][]{{1}, {9, 3, 5, 2}, {7, 6}};
int[][] nums = {{1}, {9, 3, 5, 2}, {7, 6}};
说明:
- 如果在动态初始化时明确了二维数组的行数和列数,那么一维数组的长度就是固定的列数。
- 如果在动态初始化时仅仅明确了行数,或者通过静态初始化赋值,那么一维数组可以有不同的长度。
8.6 排序算法
8.6.1 冒泡排序
思路:
- 属于交换排序。
- 从第一个元素开始,比较两个相邻的元素,如果两个元素位置不正确,则进行交换,否则继续比较下面相邻的两个元素。
示例:
1 | public void test() { |
8.6.2 快速排序
思路:
- 属于交换排序。
- 任取序列的某个元素作为界点,将序列分为两个子序列,左子序列的元素小于界点,右子序列的元素大于界点,然后递归每个子序列,直到每个子序列只有一个元素。
示例:
1 | public void test() { |
8.6.3 直接选择排序
思路:
- 属于选择排序。
- 每次都选取最小值放在起始位上,一共通过n-1次。
示例:
1 | public void test() { |
条