2-基本语法

一、变量

1.按数据类型分类

image-20220213024251587

详细说明:

  1. 整型:byte(1字节=8bit) \ short(2字节) \ int(4字节) \ long(8字节)

byte范围:-128 ~ 127

声明long型变量,必须以"l"或"L"结尾

通常,定义整型变量时,使用int型。

整型的常量,默认类型是:int型

  1. 浮点型:float(4字节) \ double(8字节)

浮点型,表示带小数点的数值

float表示数值的范围比long还大

定义float类型变量时,变量要以"f"或"F"结尾

通常,定义浮点型变量时,使用double型。

浮点型的常量,默认类型为:double

  1. 字符型:char (1字符=2字节)

定义char型变量,通常使用一对’’,内部只能写一个字符

表示方式:1.声明一个字符 2.转义字符 3.直接使用 Unicode 值来表示字符型常量

  1. 布尔型:boolean

只能取两个值之一:true 、 false

常常在条件判断、循环结构中使用

2.按声明的位置分类

image-20220213024753296

3.定义变量的格式

  • 数据类型 变量名 = 变量值;
  • 数据类型 变量名;
  • 变量名 = 变量值;

变量使用的注意点:

  1. 变量必须先声明,后使用

  2. 变量都定义在其作用域内。在作用域内,它是有效的。换句话说,出了作用域,就失效了

  3. 同一个作用域内,不可以声明两个同名的变量

4.基本数据类型变量间运算规则

涉及到的基本数据类型:除了boolean之外的其他7种,自动类型转换(只涉及7种基本数据类型)。

结论:当容量小的数据类型的变量与容量大的数据类型的变量做运算时,结果自动提升为容量大的数据类型。

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

特别的:当 byte、char、short 三种类型的变量做运算时,结果为int型。

说明:此时的容量大小指的是,表示数的范围的大和小。比如:float容量要大于long的容量

强制类型转换(只涉及7种基本数据类型):自动类型提升运算的逆运算。

  1. 需要使用强转符:()

  2. 注意点:强制类型转换,可能导致精度损失。

String 与8种基本数据类型间的运算

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

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

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

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

避免:

String s = 123;//编译错误

String s1 = "123";

int i = (int)s1;//编译错误

5.进制

1.编程中涉及的进制及表示方式

  • 二进制(bianary):0,1 , 满 2 进 1. 以 0b 或 0B开头

  • 十进制(decimal):0-9,满10进1

  • 八进制(octal):0-7,满8进1,以数字0开头

  • 十六进值(hex):0-9及A-F,满16进1. 以0x或0X开头表示。此处的A-F不区分大小写。

  • 如:0x21AF + 1 =0X21B0

2.二进制的使用说明

计算机底层的存储方式:所有数字在计算机底层都以二进制形式存在。

二进制数据的存储方式:所有的数值,不管正负,底层都以补码的方式存储。

原码、反码、补码的说明:

正数:三码合一

负数:

原 码 : 直 接 将 一 个 数 值 换 成 二 进 制 数 。 最 高 位 是 符 号 位

负 数 的 反 码 : 是 对 原 码 按 位 取 反 , 只 是 最 高 位 ( 符 号 位 ) 确 定 为 1 。

负 数 的 补 码 : 其 反 码 加 1 。

3.进制间的转换

image-20220213025310341

图示二进制转换为十进制:

image-20220213030912758

image-20220213031500545

image-20220213033110216

图示十进制转换为二进制:

image-20220213035809722

二进制与八进制、十六进制间的转换:

image-20220214083207777

对应图示:

image-20220214085057147

6.Scanner类的使用

/*
如何从键盘获取不同类型的变量:需要使用Scanner类
具体实现步骤:
1.导包:import java.util.Scanner;
2.Scanner的实例化:Scanner scan = new Scanner(System.in);
3.调用Scanner类的相关方法(next() / nextXxx()),来获取指定类型的变量
注意:
需要根据相应的方法,来输入指定类型的值。如果输入的数据类型与要求的类型不匹配时,会报异常:InputMisMatchException
导致程序终止。
*/
//1.导包:import java.util.Scanner;
import java.util.Scanner;

class ScannerTest{
    public static void main(String[] args){
        //2.Scanner的实例化
        Scanner scan = new Scanner(System.in);
        //3.调用Scanner类的相关方法
        System.out.println("请输入你的姓名:");
        String name = scan.next();
        System.out.println(name);

        System.out.println("请输入你的芳龄:");
        int age = scan.nextInt();
        System.out.println(age);

        System.out.println("请输入你的体重:");
        double weight = scan.nextDouble();
        System.out.println(weight);

        System.out.println("你是否相中我了呢?(true/false)");
        boolean isLove = scan.nextBoolean();
        System.out.println(isLove);

        //对于char型的获取,Scanner没有提供相关的方法。只能获取一个字符串
        System.out.println("请输入你的性别:(男/女)");
        String gender = scan.next();//"男"
        char genderChar = gender.charAt(0);//获取索引为0位置上的字符
        System.out.println(genderChar);
    }
}

二、关键字与标识符

1.java关键字的使用

**定义:**被Java语言赋予了特殊含义,用做专门用途的字符串(单词)

**特点:**关键字中所字母都为小写

用于定义数据类型的关键字:
classinterfaceenumbyteshort
intlongfloatdoublechar
booleanvoid
用于定义流程控制的关键字
ifelseswitchcasedefault
whiledoforbreakcontinue
return
用于定义访问权限修饰符的关键字:
privateprotectedpublic
用于定义类,函数,变量修饰符的关键字:
abstractfinalstaticsynchronized
用于定义类与类之间的关键字:
extendsimplements
用于定义建立实例及引用实例,判断实例的关键字
newthissuperinstanceof
用于异常处理的关键字:
trycatchfinallythrowthrows
用于包的关键字
packageimport
其它修饰符关键字
nativestrictfptransientvolatileassert
用于定义数据类型值的字面值
truefalsenull

2.保留字

现Java版本尚未使用,但以后版本可能会作为关键字使用。

具体哪些保留字:goto 、const

注意:自己命名标识符时要避免使用这些保留字

3.标识符的使用

**定义:**凡是自己可以起名字的地方都叫标识符。

涉及到的结构:

包名、类名、接口名、变量名、方法名、常量名

规则:(必须要遵守。否则,编译不通过)

由 26 个 英 文 字 母 大 小 写 , 0 . 9 , 一 或 $ 组 成

数 字 不 可 以 开 头 。

不 可 以 使 用 关 键 字 和 保 留 字 , 但 能 包 含 关 键 字 和 保 留 字 。

Java 中 严 格 区 分 大 小 写 , 长 度 无 限 制。

标 识 符 不 能 包 含 空 格 。

规范:(可以不遵守,不影响编译和运行。但是我要求自己遵守)

包名:多单词组成时所有字母都小写, xxxyyyzzz

类名、接囗名:多单词组成时,所有单词的首字母大写:XxxYyyZzz

变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个

单词首字母大写:xxxYyyZzz

常量名:所有字毋都大写:多单词时每个单词厍下划线连接:XXX_YYY_ZZZ

注意:

在命名时,为了提高阅读性,要尽量意义,“见名知意”。

4.代码整洁之道

整理人:尚硅谷 - 宋红康

第2章 有意义的命名

2.1 介绍

软件中随处可见命名。我们给变量、函数、参数、类和包命名。我们给源代码及源代码所在目录命名。

这么多命名要做,不妨做好它。下文列出了取个好名字的几条简单规则。

2.2 名副其实,见名知意

变量名太随意,haha、list1、ok、theList 这些都没啥意义

2.3 避免误导

包含List、import、java等类名、关键字或特殊字;

字母o与数字0,字母l与数字1等

提防使用不同之处较小的名称。比如:XYZControllerForEfficientHandlingOfStrings与XYZControllerForEfficientStorageOfStrings

2.4 做有意义的区分

反面教材,变量名:a1、a2、a3

避免冗余,不要出现Variable、表字段中避免出现table、字符串避免出现nameString,直接name就行,知道是字符串类型

再比如:定义了两个类:Customer类和CustomerObject类,如何区分?

定义了三个方法:getActiveAccount()、getActiveAccounts()、getActiveAccountInfo(),如何区分?

2.5 使用读得出来的名称

不要使用自己拼凑出来的单词,比如:xsxm(学生姓名);genymdhms(生成日期,年、月、日、时、分、秒)

所谓的驼峰命名法,尽量使用完整的单词

2.6 使用可搜索的名称

一些常量,最好不直接使用数字,而指定一个变量名,这个变量名可以便于搜索到.

比如:找MAX_CLASSES_PER_STUDENT很容易,但想找数字7就麻烦了。

2.7 避免使用编码

2.7.1 匈牙利语标记法

即变量名表明该变量数据类型的小写字母开始。例如,szCmdLine的前缀sz表示“以零结束的字符串”。

2.7.2 成员前缀

避免使用前缀,但是Android中一个比较好的喜欢用m表示私有等,个人感觉比较好

2.7.3 接口和实现

作者不喜欢把接口使用I来开头,实现也希望只是在后面添加Imp

2.8 避免思维映射

比如传统上惯用单字母名称做循环计数器。所以就不要给一些非计数器的变量命名为:i、j、k等

2.9 类名

类名与对象名应该是名词与名词短语。如Customer、WikiPage、Account和AddressParser。避免使用Data或Info这样的类名。

不能使动词。比如:Manage、Process

2.10 方法名

方法名应当是动词或者动词短语。如postPayment、deletePage或save

2.11 别扮可爱

有的变量名叫haha、banana

别用eatMyShorts()表示abort()

2.12 每个概念对应一个词

项目中同时出现controllers与managers,为什么不统一使用其中一种?

对于那些会用到你代码的程序员,一以贯之的命名法简直就是天降福音。

2.13 别用双关语

有时可能使用add并不合适,比例insert、append。add表示完整的新添加的含义。

2.14 使用解决方案领域名称

看代码的都是程序员,所以尽量用那些计算机科学术语、算法名、模式名、数学术语,

依据问题所涉领域来命名不算是聪明的做法。

2.15 使用源自所涉问题领域的名称

如果不能用程序员熟悉的术语来给手头的工作命名,就采用从所涉问题领域而来的名称吧。

至少,负责维护代码的程序员就能去请教领域专家了。

2.16 添加有意义的语境

可以把相关的变量放到一个类中,使用这个类来表明语境。

2.17 不要添加没用的语境

名字中带有项目的缩写,这样完全没有必要。比如有一个名为“加油站豪华版”(Gas Station Deluxe)的项目,

在其中给每个类添加GSD前缀就不是什么好策略。

2.18 最后的话

取好名字最难的地方在于需要良好的描述技巧和共有文化背景。

三、循环

1.循环结构的四要素

① 初始化条件

② 循环条件 —>是boolean类型

③ 循环体

④ 迭代条件

说明:通常情况下,循环结束都是因为②中循环条件返回false了。

2.三种循环结构

for循环结构

for(①;②;④){

}

执行过程:① - ② - ③ - ④ - ② - ③ - ④ - … - ②

while循环结构

while(②){

③;

④;

}

执行过程:① - ② - ③ - ④ - ② - ③ - ④ - … - ②

说明:写while循环千万小心不要丢了迭代条件。一旦丢了,就可能导致死循环!

do-while循环结构

do{

③;

④;

}while(②);

执行过程:① - ③ - ④ - ② - ③ - ④ - … - ②

说明:

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

  2. 开发中,使用for和while更多一些。较少使用do-while

  3. “无限循环”结构: while(true) 或 for(;😉

总结

如何结束一个循环结构?

方式一:当循环条件是false时

方式二:在循环体中,执行break

for和while循环总结:

  1. 开发中,基本上我们都会从for、while中进行选择,实现循环结构。

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

  3. 我们写程序,要避免出现死循环。

区别:for循环和while循环的初始化条件部分的作用范围不同。

3.嵌套循环

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

内层循环:循环结构A

外层循环:循环结构B

说明:

① 内层循环结构遍历一遍,只相当于外层循环循环体执行了一次

② 假设外层循环需要执行m次,内层循环需要执行n次。此时内层循环的循环体一共执行了m * n次

③ 外层循环控制行数,内层循环控制列数

【典型练习】

//练习一:
/*
******
******
******
******
*/
for(int j = 1;j <= 4;j++ ){
    for(int i = 1;i <= 6;i++){
        System.out.print('*');
    }
    System.out.println();
}
//练习二:
/*                      i(行号)               j(*的个数)
*                      1                      1
**                      2                      2
***                      3                      3
****               4                      4
*****               5                      5
*/

for(int i = 1;i <= 5;i++){//控制行数
    for(int j = 1;j <= i;j++){//控制列数
        System.out.print("*");
    }
    System.out.println();
}
//练习三:九九乘法表
//练习四:100以内的质数

补充:衡量一个功能代码的优劣:

  1. 正确性

  2. 可读性

  3. 健壮性

  4. 高效率与低存储:时间复杂度 、空间复杂度 (衡量算法的好坏)

如何理解流程控制的练习:流程控制结构的使用 + 算法逻辑。

4.分支结构

1.if-else条件判断结构

结构一:

if(条件表达式){

执行表达式

}

结构二:二选一

if(条件表达式){

执行表达式1

}else{

执行表达式2

}

结构三:n选一

if(条件表达式){

执行表达式1

}else if(条件表达式){

执行表达式2

}else if(条件表达式){

执行表达式3

}

else{

执行表达式n

}

说明:

  1. else 结构是可选的。

  2. if-else结构是可以相互嵌套的。

  3. 如果if-else结构中的执行语句只有一行时,对应的一对{}可以省略的。但是,不建议大家省略。

  4. 针对于条件表达式:

如果多个条件表达式之间是“互斥”关系(或没有交集的关系),哪个判断和执行语句声明在上面还是下面,无所谓。

如果多个条件表达式之间有交集的关系,需要根据实际情况,考虑清楚应该将哪个结构声明在上面。

如果多个条件表达式之间有包含的关系,通常情况下,需要将范围小的声明在范围大的上面。否则,范围小的就没机会执行了。

2.switch-case选择结构

switch(表达式){

case 常量1:

执行语句1;

//break;

case 常量2:

执行语句2;

//break;

default:

执行语句n;

//break;

}

说明:

  1. 根据switch表达式中的值,依次匹配各个case中的常量。一旦匹配成功,则进入相应case结构中,调用其执行语句。

当调用完执行语句以后,则仍然继续向下执行其他case结构中的执行语句,直到遇到break关键字或此switch-case结构

末尾结束为止。

  1. break,可以使用在switch-case结构中,表示一旦执行到此关键字,就跳出switch-case结构

  2. switch结构中的表达式,只能是如下的6种数据类型之一:

byte 、short、char、int、枚举类型(JDK5.0新增)、String类型(JDK7.0新增)

  1. case 之后只能声明常量。不能声明范围。

  2. break关键字是可选的。

  3. default:相当于if-else结构中的else。default结构是可选的,而且位置是灵活的。

  4. 如果switch-case结构中的多个case的执行语句相同,则可以考虑进行合并。

  5. break在switch-case中是可选的

5.break和continue关键字的使用

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

补充:带标签的breakcontinue的使用。

四、运算符

1.算术运算符

+ - + - * / % (前)++ (后)++ (前)-- (后)-- +

【典型代码】

//除号:/
int num1 = 12;
int num2 = 5;
int result1 = num1 / num2;
System.out.println(result1);//2
// %:取余运算
//结果的符号与被模数的符号相同
//开发中,经常使用%来判断能否被除尽的情况。
int m1 = 12;
int n1 = 5;
System.out.println("m1 % n1 = " + m1 % n1);

int m2 = -12;
int n2 = 5;
System.out.println("m2 % n2 = " + m2 % n2);

int m3 = 12;
int n3 = -5;
System.out.println("m3 % n3 = " + m3 % n3);

int m4 = -12;
int n4 = -5;
System.out.println("m4 % n4 = " + m4 % n4);
//(前)++ :先自增1,后运算
//(后)++ :先运算,后自增1
int a1 = 10;
int b1 = ++a1;
System.out.println("a1 = " + a1 + ",b1 = " + b1);
int a2 = 10;
int b2 = a2++;
System.out.println("a2 = " + a2 + ",b2 = " + b2);
int a3 = 10;
++a3;//a3++;
int b3 = a3;
//(前)-- :先自减1,后运算
//(后)-- :先运算,后自减1
int a4 = 10;
int b4 = a4--;//int b4 = --a4;
System.out.println("a4 = " + a4 + ",b4 = " + b4);

特别说明

  • (前)++ :先自增1,后运算

  • (后)++ :先运算,后自增1

  • (前)-- :先自减1,后运算

  • (后)-- :先运算,后自减1

  • 连接符:+:只能使用在String与其他数据类型变量之间使用。

2.赋值运算符

= += -= *= /= %=

【典型代码】

int i2,j2;
//连续赋值
i2 = j2 = 10;
//***************
int i3 = 10,j3 = 20;
int num1 = 10;
num1 += 2;//num1 = num1 + 2;
System.out.println(num1);//12

int num2 = 12;
num2 %= 5;//num2 = num2 % 5;
System.out.println(num2);

short s1 = 10;
//s1 = s1 + 2;//编译失败
s1 += 2;//结论:不会改变变量本身的数据类型
System.out.println(s1);

特别说明

  • 运算的结果不会改变变量本身的数据类型
//开发中,如果希望变量实现+2的操作,有几种方法?(前提:int num = 10;)
num = num + 2;//方式一
num += 2; //方式二(推荐)
//开发中,如果希望变量实现+1的操作,有几种方法?(前提:int num = 10;)
num = num + 1;//方式一
num += 1;//方式二
num++;//方式三(推荐)

3.比较运算符

(关系运算符): == != > < >= <= instanceof

【典型代码】

int i = 10;
int j = 20;

System.out.println(i == j);//false
System.out.println(i = j);//20

boolean b1 = true;
boolean b2 = false;
System.out.println(b2 == b1);//false
System.out.println(b2 = b1);//true

特别说明

  1. 比较运算符的结果是boolean类型

  2. > < >= <= :只能使用在数值类型的数据之间。

  3. == 和 !=: 不仅可以使用在数值类型数据之间,还可以使用在其他引用类型变量之间。

    Account acct1 = new Account(1000);
    Account acct2 = new Account(1000);
    boolean b1 = (acct1 == acct2);//比较两个Account是否是同一个账户。
    boolean b2 = (acct1 != acct2);//
    

4.逻辑运算符

& && | || ! ^

//区分& 与 &&
//相同点1:& 与 && 的运算结果相同
//相同点2:当符号左边是true时,二者都会执行符号右边的运算
//不同点:当符号左边是false时,&继续执行符号右边的运算。&&不再执行符号右边的运算。
//开发中,推荐使用&&
boolean b1 = true;
b1 = false;
int num1 = 10;
if(b1 & (num1++ > 0)){
    System.out.println("我现在在北京");
}else{
    System.out.println("我现在在南京");
}

System.out.println("num1 = " + num1);

boolean b2 = true;
b2 = false;
int num2 = 10;
if(b2 && (num2++ > 0)){
    System.out.println("我现在在北京");
}else{
    System.out.println("我现在在南京");
}

System.out.println("num2 = " + num2);

// 区分:| 与 || 
//相同点1:| 与 || 的运算结果相同
//相同点2:当符号左边是false时,二者都会执行符号右边的运算
//不同点3:当符号左边是true时,|继续执行符号右边的运算,而||不再执行符号右边的运算
//开发中,推荐使用||
boolean b3 = false;
b3 = true;
int num3 = 10;
if(b3 | (num3++ > 0)){
    System.out.println("我现在在北京");
}else{
    System.out.println("我现在在南京");
}
System.out.println("num3 = " + num3);


boolean b4 = false;
b4 = true;
int num4 = 10;
if(b4 || (num4++ > 0)){
    System.out.println("我现在在北京");
}else{
    System.out.println("我现在在南京");
}
System.out.println("num4 = " + num4);


特别说明

  • 逻辑运算符操作的都是boolean类型的变量。而且结果也是boolean类型

5.位运算符

<< >> >>> & | ^ ~

【典型代码】

int i = 21;
i = -21;
System.out.println("i << 2 :" + (i << 2));
System.out.println("i << 3 :" + (i << 3));
System.out.println("i << 27 :" + (i << 27));

int m = 12;
int n = 5;
System.out.println("m & n :" + (m & n));
System.out.println("m | n :" + (m | n));
System.out.println("m ^ n :" + (m ^ n));

面试题:你能否写出最高效的2 * 8的实现方式?

答案:2 << 38 << 1

特别说明

  • 位运算符操作的都是整型的数据

  • <<:在一定范围内,每向左移1位,相当于 * 2

  • >> :在一定范围内,每向右移1位,相当于 / 2

典型题目

  1. 交换两个变量的值。
  2. 实现60的二进制到十六进制的转换。

非(~)运算

非运算即取反运算,在二进制中1变0,0变1
110110进行非运算后为
001001即1001

6.三元运算符

(条件表达式)? 表达式1 : 表达式2

【典型代码】

//获取两个整数的较大值
int m = 12;
int n = 5;
int max = (m > n)? m : n;

特别说明

  1. 条件表达式的结果为boolean类型

  2. 根据条件表达式真或假,决定执行表达式1,还是表达式2.

    • 如果表达式为true,则执行表达式1。
    • 如果表达式为false,则执行表达式2。
  3. 表达式1 和表达式2要求是一致的。

  4. 三元运算符可以嵌套使用

凡是可以使用三元运算符的地方,都可以改写为if-else。反之,不成立。

如果程序既可以使用三元运算符,又可以使用if-else结构,那么优先选择三元运算符。原因:简洁、执行效率高。

五、数组

1.一维数组

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

  2. 数组相关的概念:数组名,元素,角标、下标、索引,数组的长度:元素的个数

  3. 数组的特点

    1. 数组是序排列的

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

    3. 创建数组对象会在内存中开辟一整块连续的空间

    4. 数组的长度一旦确定,就不能修改。

  4. 数组的分类

    1. 照维数:一维数组、二维数组、…
    2. 照数组元素的类型:基本数据类型元素的数组、引用数据类型元素的数组

数据结构

  • 数据与数据之间的逻辑关系:集合、一对一、一对多、多对多

数据的存储结构

  • 线性表:顺序表(比如:数组)、链表、栈、队列

  • 树形结构:二叉树

  • 图形结构:

算法

排序算法:

搜索算法:

1.一维数组的声明与初始化

正确的方式:

int num;//声明
num = 10;//初始化
int id = 1001;//声明 + 初始化
int[] ids;//声明
//1.1 静态初始化:数组的初始化和数组元素的赋值操作同时进行
ids = new int[]{1001,1002,1003,1004};
//1.2动态初始化:数组的初始化和数组元素的赋值操作分开进行
String[] names = new String[5];

int[] arr4 = {1,2,3,4,5};//类型推断

错误的方式:

int[] arr1 = new int[];
int[5] arr2 = new int[5];
int[] arr3 = new int[3]{1,2,3};

2.一维数组元素的引用

通过角标的方式调用。

//数组的角标(或索引从0开始的,到数组的长度-1结束。
names[0] = "Gogo";
names[1] = "Tony";
names[2] = "Jenny";
names[3] = "Paul";
names[4] = "Mike";//charAt(0)

3.数组的属性:length

System.out.println(names.length);//5
System.out.println(ids.length);

说明:

数组一旦初始化,其长度就是确定的。arr.length

数组长度一旦确定,就不可修改。

4.一维数组的遍历

for(int i = 0;i < names.length;i++){
    System.out.println(names[i]);
}

5.一维数组元素的默认初始化值

  • 数组元素是整型:0

  • 数组元素是浮点型:0.0

  • 数组元素是char型:0或’\u0000’,而非’0’

  • 数组元素是boolean型:false

  • 数组元素是引用数据类型:null

6.一维数组的内存解析

int arr = new int[]{1,2,3};
String[] str1 = new String[4];
str1[1] = "Peter";
str1[2] = "Ben";
str1 = new String[3];
System.out.println(str[1]);//null

image-20220214092745603

2.二维数组

1.如何理解二维数组?

数组属于引用数据类型

数组的元素也可以是引用数据类型

一个一维数组A的元素如果还是一个一维数组类型的,则,此数组A称为二维数组。

2.二维数组的声明与初始化

正确的方式:

int[] arr = new int[]{1,2,3};//一维数组
//静态初始化
int[][] arr1 = new int[][]{{1,2,3},{4,5},{6,7,8}};
//动态初始化1
String[][] arr2 = new String[3][2];
//动态初始化2
String[][] arr3 = new String[3][];
//也是正确的写法:
int[] arr4[] = new int[][]{{1,2,3},{4,5,9,10},{6,7,8}};
int[] arr5[] = {{1,2,3},{4,5},{6,7,8}};//类型推断

错误的方式:

String[][] arr4 = new String[][4];
String[4][3] arr5 = new String[][];
int[][] arr6 = new int[4][3]{{1,2,3},{4,5},{6,7,8}};

3.如何调用二维数组元素

System.out.println(arr1[0][1]);//2
System.out.println(arr2[1][1]);//null
arr3[1] = new String[4];
System.out.println(arr3[1][0]);
System.out.println(arr3[0]);//

4.二维数组的属性

System.out.println(arr4.length);//3
System.out.println(arr4[0].length);//3
System.out.println(arr4[1].length);//4

5.遍历二维数组元素

for(int i = 0;i < arr4.length;i++){
    for(int j = 0;j < arr4[i].length;j++){
        System.out.print(arr4[i][j] + "  ");
    }
    System.out.println();
}

6.二维数组元素的默认初始化值

规定:二维数组分为外层数组的元素,内层数组的元素
int[][] arr = new int[4][3];
外层元素:arr[0],arr[1]等
内层元素:arr[0][0],arr[1][2]等

数组元素的默认初始化值 
针对于初始化方式一:比如:int[][] arr = new int[4][3];
外层元素的初始化值为:地址值
内层元素的初始化值为:与一维数组初始化情况相同
针对于初始化方式二:比如:int[][] arr = new int[4][];
外层元素的初始化值为:null
内层元素的初始化值为:不能调用,否则报错。

7.二维数组的内存结构

int[][] arr1 = new int[4][];
arr[1] = new int[]{1,2,3};
arr1[2] = new int[4];
arr[2][2] = 9;

image-20220214103737529

3.数组常见的异常

1.数组角标越界异常

ArrayIndexOutOfBoundsException

int[] arr = new int[]{1,2,3,4,5};
for(int i = 0;i <= arr.length;i++){
    System.out.println(arr[i]);
}
System.out.println(arr[-2]);
System.out.println("hello");

2.空指针异常

NullPointerException

//情况一:
//int[] arr1 = new int[]{1,2,3};
//arr1 = null;
//System.out.println(arr1[0]);
//情况二:
//int[][] arr2 = new int[4][];
//System.out.println(arr2[0][0]);
//情况:
String[] arr3 = new String[]{"AA","BB","CC"};
arr3[0] = null;
System.out.println(arr3[0].toString());

小知识:一旦程序出现异常,未处理时,就终止执行。

4.数组常见算法

1.数组的创建与元素赋值

杨辉三角(二维数组)、回形数(二维数组)、6个数,1-30之间随机生成且不重复。

2.针对于数值型的数组

最大值、最小值、总和、平均数等

3.数组的赋值与复制

int[] array1,array2;
array1 = new int[]{2,3,3,3,5,5,6,6};
array2 = array1;
for(int i = 0; i < array2.length; i++){
    if(i % 2 == 0){
        array2[i] = i;
    }
}

赋值:array2 = array1;

如何理解:将array1保存的数组的地址值赋给了array2,使得array1和array2共同指向堆空间中的同一个数组实体。

image-20220214095847966

复制:

array2 = new int[array1.length];
for(int i = 0;i < array2.length;i++){
    array2[i] = array1[i];
}

如何理解:我们通过new的方式,给array2在堆空间中新开辟了数组的空间。将array1数组中的元素值一个一个的赋值到array2数组中。

image-20220214100301771

4.数组元素的反转

//方法一:
for(int i = 0;i < arr.length / 2;i++){
	String temp = arr[i];
	arr[i] = arr[arr.length - i -1];
	arr[arr.length - i -1] = temp;
}
//方法二:
for(int i = 0,j = arr.length - 1;i < j;i++,j--){
	String temp = arr[i];
	arr[i] = arr[j];
	arr[j] = temp;
}

5.数组中指定元素的查找:搜索、检索

线性查找:

实现思路:通过遍历的方式,一个一个的数据进行比较、查找。

适用性:具有普遍适用性。

二分法查找:

实现思路:每次比较中间值,折半的方式检索。

适用性:(前提:数组必须有序)

6.数组的排序算法

十大内部排序算法

  • 选择排序
    • 直接选择排序
    • 堆排序
  • 交换排序
    • 冒泡排序
    • 快速排序
  • 插入排序
    • 直接插入排序
    • 折半插入排序
    • Shell排序
  • 归并排序
  • 桶式排序
  • 基数排序

理解:

  1. 衡量排序算法的优劣:**时间复杂度、**空间复杂度、稳定性

  2. 排序的分类:内部排序 与 外部排序(需要借助于磁盘)

  3. 不同排序算法的时间复杂度

    image-20220214101238145

  4. 手写冒泡排序

    int[] arr = new int[]{43,32,76,-98,0,64,33,-21,32,99};
    //冒泡排序
    for (int i = 0; i < arr.length - 1; i++) {
        for (int j = 0; j < arr.length - 1 - i; j++) {
            if (arr[j] > arr[j + 1]) {
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
    

5.Arrays工具类的使用

Arrays定义在java.util包下。Arrays提供了很多操作数组的方法。

使用

//1.boolean equals(int[] a,int[] b):判断两个数组是否相等。
int[] arr1 = new int[]{1,2,3,4};
int[] arr2 = new int[]{1,3,2,4};
boolean isEquals = Arrays.equals(arr1, arr2);
System.out.println(isEquals);
//2.String toString(int[] a):输出数组信息。
System.out.println(Arrays.toString(arr1));
//3.void fill(int[] a,int val):将指定值填充到数组之中。
Arrays.fill(arr1,10);
System.out.println(Arrays.toString(arr1));

//4.void sort(int[] a):对数组进行排序。
Arrays.sort(arr2);
System.out.println(Arrays.toString(arr2));
//5.int binarySearch(int[] a,int key)
int[] arr3 = new int[]{-98,-34,2,34,54,66,79,105,210,333};
int index = Arrays.binarySearch(arr3, 210);
if (index >= 0) {
    System.out.println(index);
} else {
    System.out.println("未找到");
}

六、注释与API文档

1.注释(comment)

单行注释://

多行注释:/* */

文档注释:/** */

作用:

  1. 对所写的程序进行解释说明,增强可读性。方便自己,方便别人。

  2. 调试所写的代码。

特点:

  1. 单行注释和多行注释,注释了的内容不参与编译。换句话说,编译以后生成的.class结尾的字节码文件中不包含注释掉的信息

  2. 注释内容可以被JDK提供的工具 javadoc 所解析,生成一套以网页文件形式体现的该程序的说明文档。

  3. 多行注释不可以嵌套使用

2.Java API 文档:

API:application programming interface。习惯上:将语言提供的类库,都称为api。

API文档:针对于提供的类库如何使用,给的一个说明书。类似于《新华字典》。

3.良好的编程风格

正确的注释和注释风格

  • 使用文档注释来注释整个类或整个方法

  • 如果注释方法中的某一个步骤,使用单行或多行注释。

正确的缩进和空白

  • 使用一次Tab操作,实现缩进

  • 运算符两边习惯性加一个空格。比如:2 + 4 * 5。

块的风格

Java API 源代码选择了行尾风格

//行尾风格
public class Test{
	public static void main(String[] args){
		System.out.println("Block Style!");
	}
}
//次行风格
public class Test
{
	public static void main(String[] args)
	{
		System.out.println("Block Style!");
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值