JavaSE基础 - 基础语法

Java基础 - 基础语法

基础语法(上)

1.关键字和保留字

关键字(keyword):被java语言赋予了特殊含义,用于专门用途的字符串。(注意:关键字都是小写字母)

保留字(reserved word): 现在java版本中尚未使用的,但在以后版本可能会作为关键字使用。自己命名标识符时要避免使用。(保留字:goto const)

2.标识符(Identifier)

标识符:对 **变量、方法、类、接口、包名**等要素命名时,使用的字符序列就是标识符。

简单说 **标识符** 就是自定义起名字的地方都叫 **标识符**。

(1)标识符命名规则:

1. 26个英文字符(区分大小写)、数字(0-9)、_ 、$ 组成;

2. 数字不能开头;

3. 不可以使用关键字或者保留字,但是能包含关键字和保留字。

4. 标识符中 不能使用空格;

5. java是严格区分大小写的; 如:定义变量 int A; int a; A 和 a 指的是两个不同的变量。

6. 标识符的长度没有限制;

注意:如果不遵守上述规则,编译不通过,需要严格遵守。

(2)标识符的命名规范:

1. 包名:所有字母小写;如:yu.bai

2. 类名、接口名 : 单个单词或多个单词组成时,首字母大写。 如:MyName

3. 变量名、方法名:多单词组成时,首字母小写,第二个单词开始每个单词的首字母大写。如:myName

4. 常量名 : 所有字母大写,单词与单词之间使用 _ 分隔; 如:MY_NAME

注意 : 如果不遵守上述的规范,编译也是可以通过的,但是建议遵守。(要规范编码)

补充 :java采用的是 **unicode** 字符集,因此 标识符也可以使用中文,但是不建议。

3. 变量

(1)变量声明与赋值

变量类型 变量名 = 变量值;
int num = 0;

(2)变量定义:

内存中的一个存储空间(区域)。

该空间(区域)的数据可以在同一类型范围内不断变化。

变量是程序中最基本的存储单元。

变量的包括 变量类型 变量名称 变量存储的值。

(3)变量的作用:

用于在内存中保存数据;

(4)使用变量需要注意:

  • Java中每个变量必须先声明,后使用。(【编译错误】不先声明变量,则内存中就没有该变量的空间,则就使用不了)

  • Java中 未被初始化值的变量,也不能直接使用。(【编译错误】变量没有被赋值,内存中只是有了空间名称。但是不知道具体值)

  • 通过 变量名 来访问 该变量所在的区域。

  • 变量的作用域: {} 花括号 ,变量只有在其作用域内才有效,同一个作用域中,不能定义同名的变量名。

(5)变量的类型:

对于每一种数据都定义了明确的数据类型(强类型语言),在内存中分配了不同大小内存空间

数据类型分为 : 基本数据类型引用数据类型

1)基本数据类型:

  • 数值型

    • 整数类型 : byte short int long

    • 浮点类型 : float double

  • 字符型 : char

  • 布尔型 : boolean

2) 引用数据类型:

  • 类 (class) 如:String、自定义的任何类型等;

  • 接口 (interface)

  • 数组 ([])

(6)变量的分类(按声明的位置不同)

  • 在方法体外,类体内声明的变量称为成员变量

    成员变量的体现形式:

    • 实例变量 (对象变量【不是static修饰】)

    • 类变量 (以static修饰)

  • 在方法体内部声明的变量称为局部变量

    局部变量的体现形式:

    • 形式参数 (方法、构造器中参数定义的变量)

    • 方法中定义的变量 (在方法的 {} 作用域中的)

    • 在代码块中定义的变量 (在 代码块 {} 作用域中的)

  • 注意:二者在初始化值方面的异同点:

    • 相同:都有生命周期

    • 不同点:局部变量除了形式参数外,需要显示初始值

(7)基本数据类型详解

整数类型

类型 占用字节(1字节(byte) = 8位(bit)) 表数范围
byte 1字节 -128 ~ 127
short 2字节 -2^15 ~ 2^15 - 1
int 4字节 -2^31 ~ 2^31 - 1
long 8字节 -2^63 ~ 2^63 - 1
  • Java 个整数类型有固定的表数范围和字符长度,不受具体OS(操作系统)的影响,保证Java程序的可移植性。

  • Java 中默认的整数类型为 int

  • 声明 long 型变量时,需在变量值后 添加 L 或 l; 如:long l1 = 100L; long l1 = 100l;

  • bit(位) 是 计算机中最小的存储单位

  • byte(字节) 是 计算机中基本存储单元。计算机处理数据的最小单位是1个字节

浮点类型

类型(精度) 占用字节 表数范围
float (单精度) 4字节 -3.403E38 ~ 3.403E38
double(双精度) 8字节 -1.798E308 ~ 1.798E308

E 表示 :E是计算机中的科学技术法的标志。 你可以把它理解成 10^x 次方

  • float:单精度,尾数可以精确到7位有效数字。很多情况下,精度很难满足需求。

  • double:双精度,精度是float的两倍。通常采用此类型。

  • Java 的浮点型常量默认为double型声明float型常量,须后加 f 或 F。如:float f1 = 100F;

字符类型

类型 占用字节 表数范围
char 2字节
  • char 型数据用来表示通常意义上“字符”(2字节)

  • Java中的所有字符都使用Unicode编码,故一个字符可以存储一个字母,一个汉字,或其他书面语的一个字符。

  • 字符型变量的三种表现形式:

  • 字符常量是用单引号(' ')括起来的单个字符。如:char c1 = 'a'; char c2 = '中'; char c3 = '9';

  • Java中还允许使用转义字符' \ '来将其后的字符转变为特殊字符型常量。

    例如:char c3 = ‘\n’; // '\n'表示换行符

  • 直接使用 Unicode 值来表示字符型常量:‘\uXXXX’。其中,XXXX代表一个十六进制整数。

    如:\u000a 表示 \n。

  • char类型是可以进行运算的。因为它都对应有Unicode码。

布尔类型

类型 占用字节 表数范围
boolean 4字节 (《java虚拟机规范 8版》)
  • Java虚拟机中没有任何供boolean值专用的字节码指令,

    Java语言表达所操作的boolean值,在编译之后都使用java虚拟机中的int数据类型来代替:

    true用1表示,false用0表示。———《java虚拟机规范 8版》

  • boolean 的 取值 只能是 true | false

(8)基本数据类型的容量排序

从小到大排序:(boolean 类型不进行排序)

编号 类型 占用字节 所属类型
1 byte 1字节 整数型
2 char 2字节 字符型
3 short 2字节 整数型
4 int 4字节 整数型
5 long 8字节 整数型
6 float 4字节 浮点型
7 double 8字节 浮点型

浮点型的容量要比整数型的存储容量大。

[图片上传失败...(image-e136ff-1607962841161)]

(9)基本数据类型之间的转换

1) 自动类型转换:

byte 、char 、 short ---> int ---> long ---> float ---> double

特别说明:当 byte 、 char 、short 三种类型的变量做运算时或各类型与自己作用算时,结果为 int 类型。

  • 容量小的类型 自动向 容量大的类型转换。

  • 有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的那种数据类型,然后在进行计算。

  • byte short char 之间不会相互转换,他们三者在计算时,首先转换为 int 类型。

  • boolean 类型不能与其他数据类型进行运算。

  • 当基本数据类型的值,与字符串(String)进行 加法运算时,基本数据类型的值,将为自动转换为字符串(String)类型。

2) 强制类型转换:

  • 将容量大的数据类型转换为容量小的数据类型。转换时,要加上强制转换符号 ()。在进行强制转换时,可能造成精度降低或溢出,需要格外小心。

  • 通常,字符串不能直接转换为基本数据类型。但通过基本类型的包装类,可以实现将字符串转换为基本数据类型。

    如: String str = "43";

    int i = Integer.parseInt(str);

  • boolean 类型不能转换为其他的数据类型。

(10) 基本数据类型 与 String 类型之间的转换

String类型变量的使用:

  1. String属于引用数据类型,翻译为:字符串

  2. 声明String类型变量时,使用一对""

  3. String可以和8种基本数据类型变量做运算,且运算只能是连接运算:+

  4. 运算的结果仍然是 String 类型;

4.进制

所有数字计算机底层都是以 二进制 形式存在。

对于整数,有四种进制的表现形式:

进制名称 底层表示 进位方式 以什么符号开头
二进制 0 和 1 满 2 进 1 以数字0和字母B开头 :0b 或者 0B
十进制 0 ~ 9 满 10 进 1
八进制 0 ~ 7 满 8 进 1 以数字 0 开头
十六进制 0 ~ 9 以及 A ~ F 满 16 进 1 以数字0和字母X开头:0x 或者 0X

5.运算符

算数运算符 赋值运算符 比较运算符(关系运算符) 逻辑运算符 位运算符 三元运算符

(1) 算数运算符

运算符 运算 范例 结果
+ 正号 +3 3
- 符号 b=4; -b; b=-4
+ 5+5 10
- 6-4 2
* 3*5 15
/ 5(被除数) / 5(除数) 1
% 取模(取余) 7(被模数) % 5(模数) 2
++ 自增(前):先运算后赋值 a=2; b=++a; a=3 b=3
++ 自增(后):先赋值后运算 a=2; b=a++; a=3 b=2
-- 自减(前):先运算后赋值 a=2; b=--a; a=1 b=1
-- 自减(后):先赋值后运算 a=2; b=a--; a=1 b=2
+ 字符串连接 "he"+"llo" "hello"

(2) 赋值运算符

赋值运算符:=

等号 右边 的值,赋值给等号 左边 的变量。 int a = 10;

当 " = " 两侧数据类型不一致时,可以使用自动类型转换或强制类型转换原则进行处理。

支持连续赋值: int a = 10; int b = 20; int c = a = b;

扩展赋值运算符:+= -= *= /= %=

自动强制类型转换的功能。(原变量的类型不会变化)

(3) 比较运算符

比较运算符 运算 范例 结果
== 相等于 4==3 false
!= 不等于 4 != 3 true
< 小于 4 < 3 false
> 大于 4 > 3 true
<= 小于或等于 4 <= 3 false
>= 大于或等于 4 >= 3 true
instanceof 检查是否是类的对象 "hello" instanceof String true

比较运算符的结果都是 boolean 型的。结果只有 truefalse.

(4) 逻辑运算符

& : 逻辑 (判断是否有false)
&&短路与 (判断是否有 false,第一个为false时,则不执行后面表达式)

只要有一个表达式的结果为 false,则这个逻辑判断的返回值就是 false

如果所有的表达式的结果都为true,则这个逻辑判断的返回值就是 true

| :逻辑 (判断是否有true)
||短路或 (判断是否有true,第一个为true时,则不执行后面的表达式)

只要有一个表达式的结果为 true,则这个逻辑判断的返回值就是 true

如果所有的表达式的结果都为 false,则这个逻辑判断的返回值就是 false

! :逻辑

^ :逻辑异或

多个表达式的结果都为 true 或者 都为 false 时, 则 逻辑异或 的结果是 false

多个表达式的结果 有 true 也有 false 时,则 逻辑异或 的结果是 true

a b a&b a&&b a|b a||b !a a^b
true true true true true true false false
true false false false true true false true
false true false false true true true true
false false false false false false true false
  1. 逻辑运算符操作的都是boolean类型的变量。

(5) 位运算符

位运算符 运算 范例
<< 左移 3 << 2 = 12 ---> 322=12
>> 右移 3 >> 1 = 1 ---> 3 / 2 = 1
>>> 无符号右移 3 >>> 1 = 1 ---> 3 / 2 = 1
& 与运算 6 & 3 = 2
或运算 6 3 = 7
^ 异或运算 6 ^ 3 = 5
~ 取反运算 ~ 6 = -7
  1. 位运算是直接对整数的二进制进行的运算。

  2. 位运算符操作的是 整数型 ,不能操作字符 、字符串 、布尔型

位运算符 补位
<< 空位补0,被移除的高位丢弃,空缺位补0
>>> 被移除的二进制最高位是0,右移后,空缺位都补0。最高位是1.空缺位都补1.
>>> 被移位二进制最高位无论是0或者是1,空缺位都用0补。
& 二进制位 进行 & 运算,只有 1 & 1时,结果是 1 ,否则是0
| 二进制位 进行 | 运算,只有 0 | 0 时,结果是 0,否则是1
^ 相同二进制位进行 ^ 运算,结果是 0; 如:1 ^ 1 = 0 、 0 ^ 0 = 0 ; 不同二进制位进行 ^ 运算结果是 1 。 如: 1 ^ 0 = 1 、 0 ^ 1 = 1
~ 正数取反,各二进制码按补码各位取反 负数取反,各二进制码按补码各位取反

[图片上传失败...(image-7ea475-1607962841161)]

[图片上传失败...(image-27794e-1607962841161)]

[图片上传失败...(image-8a80c4-1607962841161)]

(6) 三元运算符

符号语法: 条件表达式 ? 表达式1 : 表达式2;

说明: 条件表达式的结果是 boolean 类型。 条件表达式成立 true,则结果是 表达式 1 条件表达式不成立 false ,则结果是 表达式 2

能使用 三元运算符的地方,都可以改成使用 if-else 如果在实际开发中,遇到了既可以使用三元运算符也可以使用 if-else 的地方。那么优先选择使用 三元运算符,原因是 简洁执行效率高

(7) 运算符的优先级

小括号() 的优先级最高,如果想先计算的话,则加上小括号就行。

基础语法(下)

1.程序流程控制

顺序结构:程序从上到下逐行的执行,中间没有任何判断和跳转。

分支结构:根据条件,选择性的执行某段代码。有 if ... else 和 switch-case 两种分支语句。

循环结构:根据循环条件,重复的执行某段代码。有 while 、 do...while 、for 三种循环语句。

注:JDK1.5提供了 foreach 循环,方便的遍历集合、数组元素。

2.分支结构

(1) if else

if 语句,条件表达式成立才会执行if中的代码块。

    if(条件表达式){
        代码块;
    }
    其他代码;

if - else 语句,又叫 二选一(表明给出的两个代码块,必须执行其中的一个)

    if(条件表达式){
        代码块1;
    }else{
        代码块2;
    }

if - else if ... - else 语句,又叫多选一 (表明给出的多个代码块,必须执行其中的一个(前提是有else语句时))

    if(条件表达式1){
        代码块1;
    }else if(条件表达式2){
        代码块2;
    }else if(条件表达式3){
        代码块3;
    }
    ...
    else{
        代码块n;
    }

(2)switch-case

语法:

switch(表达式){
    case 常量1: 
        语句块1;//(可以写多条语句,每条语句以分号结束)
        break; // break 按照实际的需求决定加不加
    case 常量2: 语句块2;
        break;
    ...
    case 常量n: 语句块n;
        break;
    default: 语句块;
        //break; // 最后面的这个 break 可以不加,因为位置在最后,执行完直接就跳出了switch case
}

[图片上传失败...(image-d1fe43-1607962841160)]

  1. 根据 switch 表达式中的值,依次匹配各个 case 中的常量。一旦匹配成功,则进入相应的 case 结构中,执行该case中的语句块。当执行完语句块后,如果没有遇见 break关键字或到了此switch语句的结果处,则仍然向下执行其他的case结构中的语句块。直到遇到break关键字或到了此switch-case结构末尾结束为止。
  2. break,可以使用在 switch-case 结构中,表示一旦执行到此关键字,就跳出 switch-case 结构。
  3. switch 结构中 [switch(表达式)] 的表达式的结果,只能是如下6种类型:
    byte
    short
    char
    int
    枚举类型 (JDK5.0新增的支持类型)
    String类型 (JDK7.0新增的支持类型)
  4. case 之后 只能声明常量,不能设定(声明)范围
  5. break 关键字是可选的。根据实际情况来判定是否需要 break
  6. default 相当于 if-else 结构中的 else 。
    default 可选的,根据实际情况来决定要不要编写 default:
    default 的位置是灵活的。(可以放在最后面,也可以放在case 前面,也可以放在 case 和 case 中间),
    但是不管位置在哪里,都是最后执行的。需要注意的是,放在前面或者中间位置,需要添加break关键字.

(3)if和switch语句很像,具体什么场景下,应用哪个语句呢?

  1. 如果判断的具体数值不多,而且符合byte、short 、char、int、String、枚举等几种类型。虽然两个语句都可以使用, 建议使用switch语句。因为效率稍高。

  2. 其他情况:对区间判断,对结果为boolean类型判断,使用if,if的使用范围更广。 也就是说,使用switch-case的,都可以改写为if-else。反之不成立。

3.循环结构

在某些条件满足的情况下,反复执行特定代码的功能。

java中循环的分类:

  • for 循环

  • while 循环

  • do-while 循环

循环语句的四个组成部分:

  • 初始化部分(init_statement)

  • 循环条件部分(test_exp)

  • 循环体部分(body_statement)

  • 迭代部分(alter_statement)

[图片上传失败...(image-2cfb25-1607962841160)]

(1) for 循环

语法:

  for (①初始化部分; ②循环条件部分; ④迭代部分){
      ③循环体部分;
  } 

执行过程:

1. 先执行 :

① 初始化部分 (该部分只会被执行一次)

2. 在执行:

② 循环条件部分 (该部分的结果值必须是 boolean 类型的)

循环条件成立 则 执行 ③循环体部分

循环条件不成立,则退出循环不执行。

3. ③循环体部分 执行完后 执行:

④迭代部分

  1. 执行 ② 循环条件部分

    循环条件成立 则 执行 ③循环体部分

    循环条件不成立,则退出循环不执行。

    ......

    [图片上传失败...(image-ec204a-1607962841142)]

说明:

  • ②循环条件部分boolean类型表达式,当值为false时,退出循环;

  • ①初始化部分 可以声明多个变量,但必须同一类型,用逗号分隔;

  • ④迭代部分 可以有多个变量更新,用逗号分隔;

(2) while 循环

语法:

  ①初始化部分
  while(②循环条件部分){
    ③循环体部分; 
    ④迭代部分;   
  }

执行过程:

先执行:

①初始化部分 (该部分只会被执行一次)

然后执行:

②循环条件部分 -----> 循环条件是 boolean 类型

注意:循环条件为 false 时,不会进入循环执行 ③ 和 ④

循环条件为 true 时,才会进入循环执行 ③ 和 ④

在执行:

③循环体部分;

④迭代部分;

......

说明:

1. 注意不要忘记声明④迭代部分。否则,循环将不能结束,变成死循环。

2. for循环和while循环可以相互转换

(3) do-while循环

语法:

  ①初始化部分;
  do{
      ③循环体部分
      ④迭代部分
  }while(②循环条件部分);

执行过程:

先执行 :

①初始化部分 (该部分只会被执行一次)

然后执行:

③循环体部分;

④迭代部分;

然后执行:

②循环条件部分 -----> 循环条件的类型一定是 boolean

说明:

循环条件的结果为 false ,则不继续执行 ③ 和 ④

循环条件的结果为 true ,则继续执行 ③ 和 ④

然后执行:

③循环体部分;

④迭代部分;

......

说明:

1. do-while循环至少执行一次循环体。

  1. 开发中,使用 for 和 while 较多,使用 do-while 较少。

(4) 无限循环

最简单“无限” 循环格式:

方式一:while(true) {}

方式二:for(;;){}

无限循环存在的原因是并不知道循环多少次,需要根据循环体内部某些条件,来控制循环的结束。

结束循环的两种方式:

方式一:使循环条件部分的值变为 false

方式二:在循环体中,使用 break 关键字

(5) 嵌套循环(多重循环)

一个循环放在另一个循环体内,就形成了嵌套循环。其中:for ,while ,do-while 均可以作为外层循环内层循环

实质上,嵌套循环就是把内层循环当成外层循环的循环体。当只有内层循环的循环条件为false时,才会完全跳出内层循环,才可结束外层的当次循环,开始下一次的循环。

设外层循环次数为m次,内层为n次,则内层循环体实际上需要执行m*n次。

总结:

嵌套循环的使用

1. 嵌套循环:将一个循环结构A声明在另一个循环结构B的循环体中,就构成了嵌套循环

2. 外层循环:循环结构B
内层循环:循环结构A

  1. 说明 ① 内层循环结构遍历一遍,只相当于外层循环循环体执行了一次 ② 假设外层循环需要执行m次,内层循环需要执行n次。此时内层循环的循环体一共执行了m * n次

  2. 技巧: 外层循环控制行数,内层循环控制列数

4. 特殊关键字的使用 break | continue

关键字 使用范围 循环中使用的作用(不同点) 相同点
break switch-case
循环结构中 结束当前循环 关键字后面不能声明执行语句
continue 循环结构中 结束当次循环 关键字后面不能声明执行语句

数组

1.数组的概念

数组(Array),是多个 相同类型数据一定顺序排列的集合 ,并使用 一个名字命名,并通过 编号 的方式对这些数据进行统一的管理。

2.数组相关的概念

  • 数组名

  • 元素

  • 下标(角标、索引)

  • 数组的长度:也就是一个数组中元素的个数

3.数组的特点

(1) 数组是有序排列的

(2) 数组属于 引用数据类型 的变量,但是数组中的元素,既可以是基本数据类型,也可以是引用数据类型。

(3) 创建数组对象时,会在内存中开辟一块连续的空间

(4) 数组的长度一旦确定就不能修改

4.数组的分类

(1) 按照维数:一维数组、二维数组、三维数组、......

(2) 按照数组元素的类型:基本数据类型元素的数组、引用数据类型元素的数组。

5.一维数组

(1) 使用

  • a 如何 声明和初始化 一维数组

  • b 如何调用 数组 的指定位置的元素

  • c 如何获取数组的长度

  • d 如何遍历数组

  • e 数组元素的默认初始化值是多少?

  • f 数组的内存解析

a 如何 声明和初始化 一维数组
//1.1 静态初始化的方式:数组的初始化和数组的赋值操作同时进行
int[] ids = new int[]{1001,1002,1003,1004};
 ​
//先声明,在创建数组对象的方式
//int[] ids;
//ids = new int[]{1001,1002,1003,1004};

//1.2 动态初始化的方式:数组的初始化和数组的赋值操作分开进行
String[] names = new String[4];
 ​
//先声明,在创建数组对象的方式
//String[] names;
//names = new String[4];
//一维数组的错误写法: int[] arr1 = new int[]; //动态实例化数组,不指定长度的错误写法。 int[5] arr2 = new int[]; //动态实例化数组,将长度的位置写错了位置。 int[15] arr3 = new int[15]; //动态实例化数组,将数组的长度也写在了 声明数组的位置 int[] arr4 = new int[2]{1,2}; //静态和动态初始化数组的方式进行了混合使用的错误写法

总结:一维数组一旦初始化(实例化)完成,数组的长度就确定了。

b 如何调用数组给指定位置的角标赋值元素:通过角标的方式调用
//2.如何调用数组给指定位置的角标赋值元素:通过角标的方式调用
//数组的角标 从0开始,到数组的 长度 - 1 结束。
names[0] = "张零";
names[1] = "张一";
names[2] = "张二";
names[3] = "张三";

总结: 数组的角标 从 0 开始,到数组 的 长度 - 1 结束。
如:
int[] arr = new int[5]; // 声明数组,并设定数组的 长度为 5

上述代码中的数组角标 分别是: 0 1 2 3 4

c 如何获取数组的长度
 int length = names.length;
 System.out.println("names数组的长度是:" + length);

总结:获取数组的长度,通过数组提供的 属性 length 获取。

d 如何遍历数组
 System.out.print("names数组的遍历结果是:");
 for (int i = 0; i < names.length ; i++) {
  System.out.print(names[i] + " ");
 }
 System.out.println();

总结:遍历数组,获取数组中的元素,需要使用 数组名[角标] 的方式获取,该角标所对应的数组元素。

e 数组元素的默认初始化值

总结:

  • 数组元素为 整型 (byte short int long)时,数组元素的默认值: 0

  • 数组元素为 浮点型 (float double)时,数组元素的默认值: 0.0

  • 数组元素为 字符型 (char)时,数组元素的默认值:0 或写为:’\u0000’(表现为空)

  • 数组元素为 布尔型 (boolean)时,数组元素的默认值:false

  • 数组元素为 引用数据类型 (String Integer 等)时,数组元素的默认值:null

//整型元素
//(1) 演示 数组中 元素为 byte 型时,默认值是多少? 答: 0
byte[] arrByte = new byte[3];
System.out.print("数组中元素为byte时,默认值为:");
for (int i = 0; i < arrByte.length ; i++) {
   System.out.print(arrByte[i] + "  ");
}
System.out.println();
 
//(2) 演示 数组中 元素为 short 型时,默认值是多少? 答: 0
short[] arrShort = new short[3];
System.out.print("数组中元素为short时,默认值为:");
for (int i = 0; i < arrShort.length ; i++) {
  System.out.print(arrShort[i] + "  ");
}
System.out.println();
 ​
//(3) 演示 数组中 元素为 int 型时,默认值是多少? 答: 0
int[] arrInt = new int[3];
System.out.print("数组中元素为int时,默认值为:");
for (int i = 0; i < arrInt.length ; i++) {
  System.out.print(arrInt[i] + "  ");
}
System.out.println();
 ​
//(3) 演示 数组中 元素为 long 型时,默认值是多少? 答: 0
long[] arrLong = new long[3];
System.out.print("数组中元素为long时,默认值为:");
for (int i = 0; i < arrLong.length ; i++) {
  System.out.print(arrLong[i] + "  ");
}
System.out.println();
/**
 * 总结:数组中元素为 整型时(byte、short、int), 这默认的初始化值为 0
 */
 ​
//浮点型元素
//(1)演示 数组中 元素为 float 型时,默认值是多少? 答: 0.0
float[] arrFloat = new float[4];
System.out.print("数组中元素为 float 时,默认值为:");
for (int i = 0; i < arrFloat.length ; i++) {
  System.out.print(arrFloat[i] + "  ");
}
System.out.println();
 ​
//(2)演示 数组中 元素为 double 型时,默认值是多少? 答: 0.0
double[] arrDouble = new double[3];
System.out.print("数组中元素为 double 时,默认值为:");
for (int i = 0; i < arrDouble.length ; i++) {
  System.out.print(arrDouble[i] + "  ");
}
System.out.println();
/**
 * 总结:数组中的元素 为 浮点型时,数组元素的默认值为: 0.0
 */
 ​
//字符型元素:char
//演示 数组中 元素为 char 型时,默认值是多少? 答:0 或写为:’\u0000’(表现为空)
char[] arrChar = new char[5];
System.out.print("数组中元素为 char 时,默认值为:");
for (int i = 0; i < arrChar.length ; i++) {
  System.out.print("-*" + arrChar[i] + "*-    ,");
}
System.out.println();
//打印的结果像是一个 空格,那我们测试下这 像空格 的代表的是 0 么
if(arrChar[0] == 0){
  System.out.println("arrChar[0] 的元素就是等于 0 ");
}
/**
 * 总结:数组中的元素为 char 型时,数组元素的默认值为: 0 或写为:’\u0000’(表现为空)
 */
 ​
//boolean 型元素
//演示 数组中 元素为 boolean 型时,默认值是多少? 答:false
boolean[] arrBoolean = new boolean[2];
System.out.print("数组中元素为 boolean 时,默认值为:");
for (int i = 0; i < arrBoolean.length ; i++) {
  System.out.print(arrBoolean[i] + "  ");
}
System.out.println();
/**
 * 总结: 数组中元素为 boolean 时,数组的默认值为:false
 *
 *      因为在二进制的底层, false 是用 0 表示的。所以,这里自然而然的默认结果就是 false
 */
 ​
//引用型元素时,数组的默认值为:null  注意不是 'null' 或者 "null"
//(1) 演示 String
String[] arrString = new String[5];
System.out.print("数组中的元素类型为引用数据类型时(String),数组的默认值为:");
System.out.println(arrString[1]);
 ​
//(2) 演示 Integer
Integer[] arrInteger = new Integer[3];
System.out.print("数组中的元素类型为引用数据类型时(Integer),数组的默认值为:");
System.out.println(arrInteger[1]);
/**
 * 总结:数组中的元素类型为 Integer 时,数组元素的默认值为: null 而不是为 "null"
 */
//演示 引用数据类型的值到底是 null  还是  "null"
if(arrString[0] == "null"){
   System.out.println("我是双引号的 null");
}else{
   System.out.println("我是没有带引号的 null");//执行结果为 这个
}
f 数组的内存解析
1) 内存的简单图示

内存中简单的换份为了 三份空间:

  1. 栈 空间: 用来存放 局部变量。 (局部变量就是出现在方法中的变量)
  2. 堆 空间: 用来存放 new 出来的结构(对象、数组)
  3. 方法区 空间:包括了 常量池、静态域

[图片上传失败...(image-5dbb32-1607962841158)]

2)一维数组的内存解析
int[] arr = new int[]{1,2,3};
String[] arr1 = new String[4];
arr1[1] = "刘德华";
arr1[2] = "张学友";
arr1 = new String[3];
System.out.println(arr1[1]); // null

[图片上传失败...(image-9389c4-1607962841157)]

6.多维数组-二维数组

对于二维数组的理解,我们可以看成是一维数组arr1作为另一个一维数组 arr2元素存在。其实,从底层的运行机制来看,其实没有多维数组。

(1) 使用

  • a 如何 声明和初始化 二维数组

  • b 如何调用 数组 的指定位置的元素

  • c 如何获取数组的长度

  • d 如何遍历数组

  • e 数组元素的默认初始化值是多少?

  • f 数组的内存解析

a 如何 声明和初始化 二维数组
//1.二维数组的 声明 和 初始化
//静态方式:一维数组
int[] arrOne = new int[]{20,30,40};
//静态方式:二维数组
int[][] arrTwo = new int[][]{{10,20,30},{50,60},{100,300,600}};//标准写法
int arrTwo1[][] = new int[][]{{10,20,30},{50,60},{100,300,600}};//扩展写法
int[] arrTwo2[] = new int[][]{{10,20,30},{50,60},{100,300,600}};//扩展写法
/**
 * 解析二维数组:
 *  有三个一维数组
 *  这三个一维数组中存放了 另外一个数组
 *      arrTwo[0] 中存放了 {10,20,30} 三个元素的数组
 *      arrTwo[1] 中存放了 {50,60}    二个元素的数组
 *      arrTwo[2] 中存放了 {100,300,600}    三个元素的数组
 */
 ​
//动态方式:一维数组
int[] arrOne1 = new int[5];
//动态方式1:二维数组   表示3个一维数组中,分别存放了一个元素个数为2的一维数组。
String[][] arrTwo11 = new String[3][2];//标准写法
String arrTwo12[][] = new String[3][2];//扩展写法
String[] arrTwo13[] = new String[3][2];//扩展写法
​
//动态方式2:二维数组   表示3个一维数组中,还没有存放一维数组
String[][] arrTwo22 = new String[3][];//标准写法
String arrTwo23[][] = new String[3][];//扩展写法
String[] arrTwo24[] = new String[3][];//扩展写法
​
//二位数组错误的声明 和 赋值演示
//String[][] arr1 = new String[][4];
//String[][] arr2 = new String[][4];
//String[4][] arr3 = new String[][];
//String[][2] arr4 = new String[][];
//String[5][2] arr5 = new String[][];
//String[][] arr6 = new String[2][2]{{1,2},{1,2}};
b 如何调用数组给指定位置的角标赋值元素:通过角标的方式调用
//静态方式:二维数组
int[][] arrTwo = new int[][]{{10,20,30},{50,60},{100,300,600}};//标准写法
//动态方式1:二维数组   表示3个一维数组中,分别存放了一个元素个数为2的一维数组。
String[][] arrTwo1 = new String[3][2];//标准写法
//动态方式2:二维数组   表示3个一维数组中,还没有存放一维数组
String[][] arrTwo2 = new String[3][];//标准写法
 ​
//2.如何调用 二位数组 的指定位置的 元素
//调用 arrTwo 数组中的 {{10,20,30},{50,60},{100,300,600}} 的 第0个数组中的第1个元素
System.out.println(arrTwo[0][1]);//20
 ​
//调用 arrTwo11 数组中的 第 1 个一维数组中 存放的 一维数组的 第 1 个元素
System.out.println(arrTwo1[1][1]);//null ​

//如何给数组赋值
//arrTwo2[0] = new int[2];//编译报错,因为 arrTwo2 数组的类型是 String
arrTwo2[0] = new String[2];// 给 arrTwo2 的数组 的 外层 下标0 的元素赋值 一个长度为2的空数组。
arrTwo2[0][1] = "ni"; //给 arrTwo2 的数组 的 外层 下标0 的元素中的数组下标1的元素赋值。
System.out.println(arrTwo2[0][1]);//ni
c 如何获取数组的长度
//3.获取二位数组的长度
//获取arrTwo数组的长度:int[][] arrTwo = new int[][]{{10,20,30},{50,60},{100,300,600}};
System.out.println(arrTwo.length);//3
 ​
//获取二维数组中外层一维数组的下标1的元素中存放的数组的长度。
System.out.println(arrTwo[1].length);//2
 ​
//获取二维数组中外层一维数组的下标0的元素中存放的数组的长度。
System.out.println(arrTwo[0].length);//3
 ​
//获取二维数组中外层一维数组的下标2的元素中存放的数组的长度。
System.out.println(arrTwo[2].length);//3 
d 如何遍历数组
//4.如何遍历二维数组
//遍历 arrTwo 数组 :int[][] arrTwo = new int[][]{{10,20,30},{50,60},{100,300,600}};
//arrTwo.length 获取数组的长度
for (int i = 0; i < arrTwo.length ; i++) {
  System.out.print("arrTwo[" + i + "] = ");
  //arrTwo[i].length 获取外层数组中元素数组的长度。
  for (int j = 0; j < arrTwo[i].length ; j++) {
    System.out.print(arrTwo[i][j] + ",");
  }
  System.out.println();
}
e 数组元素的默认初始化值
//1.整数类型 byte short int long ,我们使用 int 来举例
int[][] arr = new int[3][2];
System.out.println(arr);//[[I@4554617c
/**
 * [[I@4554617c 表示地址值。
 *  剖析地址值:
 *      [[  表示这个是一个 二维数组
 *      I   表示 这个数组的类型是 int 型的
 *      @   中间连接的词语(我认为跟 微信群聊的@ 是一个意思)
 *      4554617c  表示这个二维数组的地址值
 */
 ​
System.out.println(arr[0]);//[I@74a14482  外层的数组也是地址值  
//为什么外层的数组也是个地址值呢?
//答:因为外层数组存放的元素也是个数组,需要通过地址值去找内层的数组中的元素
/**
 * [I@74a14482
 *      [ : 表示对象是个一维数组
 *      I :表示数组的类型为 int
 */
System.out.println(arr[0][0]); // 0
 ​
System.out.println("------------------------ 浮点类型 -----------------------------");
//2.浮点类型 double float ,使用 float 举例
float[][] arr1 = new float[3][2];
System.out.println(arr1);//地址值
System.out.println(arr1[0]);//地址值
System.out.println(arr1[0][0]);//0.0
 ​
System.out.println("------------------------ 字符类型 -----------------------------");
//3.字符类型 char
char[][] arr2 = new char[3][2];
System.out.println(arr2);//地址值
System.out.println(arr2[1]);//地址值?
System.out.println(arr2[0][0]);//0 或写为:’\u0000’(表现为空)
 ​
System.out.println("------------------------ 布尔类型 -----------------------------");
//4.布尔类型 boolean
boolean[][] arr3 = new boolean[3][2];
System.out.println(arr3);//地址值
System.out.println(arr3[1]);//地址值
System.out.println(arr3[0][0]);//false
 ​
System.out.println("------------------------ 引用类型 -----------------------------");
String[][] arr4 = new String[3][2];
System.out.println(arr4);//地址值   [[Ljava.lang.String;@135fbaa4
System.out.println(arr4[1]);//地址值  [Ljava.lang.String;@45ee12a7
System.out.println(arr4[0][0]);//null
 ​
System.out.println("------------------------ [3][] -----------------------------");
//演示 int[][] arr5 = new int[3][];
int[][] arr5 = new int[3][];
System.out.println(arr5[0]);//null  因为数组是引用数据类型,在外层数组中么有元素的情况下,则为 null
System.out.println(arr5[0][0]);//报错:空指针异常java.lang.NullPointerException
f 数组的内存解析
二维数组的内存解析---图一:

[图片上传失败...(image-ec253f-1607962841155)]

二维数组内存解析 --- 图2:

[图片上传失败...(image-148e44-1607962841155)]

二维数组内存解析 --- 图3:

[图片上传失败...(image-5f2749-1607962841155)]

复习一维数组内存图:将代码转换为内存图

public class TestQuestions2 {
  public static void main(String[] args){
    int[] array1 = new int[]{2,3,5,7,11,13,17,19};
    System.out.print("显示array1数组中的元素:");
    for (int i = 0; i < array1.length ; i++) {
       System.out.print(array1[i] + "  ");
     }
    System.out.println();
    // array1 和 array2 指向了同一个 堆内存空间
    //注意:这个操作不能称为是数组的复制,因为此操作,堆内存中仅仅只有一块数组存储空间。
    int[] array2 = array1;
    for (int i = 0; i < array2.length ; i++) {
      if (i % 2 == 0){
        array2[i] = i;
      }
    }
    //遍历 array1 和 遍历 array2 的结果是一样的
    System.out.print("array1 数组中的元素:");
    for (int i = 0; i < array1.length ; i++) {
      System.out.print(array1[i] + "  ");
    }
    System.out.println();
    System.out.print("array2 数组中的元素:");
    for (int i = 0; i < array2.length ; i++) {
      System.out.print(array2[i] + "  ");
    }
    System.out.println();
  }
}

[图片上传失败...(image-269bfc-1607962841154)]

7.数组中涉及到的算法

算法相关的请关注 数据结构和算法 相关内容的文档(待上传)。

(1) 数组中涉及的常见算法

  • 数组元素的赋值(杨辉三角、回形数等)

  • 求数值型数组中元素的最大值、最小值、平均数、总和

  • 数组的复制、反转、查找(线性查找、二分法查找)

    [图片上传失败...(image-fde2e3-1607962841141)]

  • 数组元素的排序算法

(2) 十大内部排序算法

  • 选择排序

    • 直接选择排序

    • 堆排序

  • 交换排序

    • 冒泡排序

    • 快速排序

  • 插入排序

    • 直接插入排序

    • 折半插入排序

    • Shell排序

  • 归并排序

  • 桶式排序

  • 基数排序

8. Arrays工具类的使用

Java 类库中提供的:
  在 java.util.Arrays 包 , 需要时去查询相关的API,这里不做过多的说明。

9. 数组使用中的常见异常

数组脚标越界异常 (ArrayIndexOutOfBoundsException)
  int[] arr = new int[2];
  System.out.println(arr[2]);
  System.out.println(arr[-1]);
  //访问到了数组中的不存在的脚标时发生
 ​
 空指针异常 (NullPointerException)
  int[] arr = null;
  System.out.println(arr[0]);
  //arr引用没有指向实体,却在操作实体中的元素时。

你可能感兴趣的:(JavaSE基础 - 基础语法)