Java SE基础

入门

1.Java特性和优势

  • 简单性
  • 面向对象
  • 可移植性
  • 高性能
  • 分布式
  • 动态性
  • 多线程
  • 安全性
  • 健壮性

2.java三大版本

  • Write Once、Run Anywhere
  • JavaSE :标准版(桌面程序,控制台开发……)
  • JavaME:嵌入式开发(手机,小家电……)
  • JavaEE:企业级开发(Web端,服务器开发……)

3.JDK、JRE、JVM

  • JDK:Java Development Kit
  • JRE:Java Runtime Environment
  • JVM:Java Virtual Machine

JDK,JRE,JVM三者之间的关系

4.HelloWorld

1.随便新建一个文件夹,存放代码

2.新建一个Java文件

  • 文件后缀名为.java
  • 例如:Hello.java
  • 系统可能没有显示文件后缀名,我们需要手动打开

3.编写代码

1
2
3
4
5
public class Hello{
public static void main(String[] args){
System.out.print("Hello World!Java!");
}
}

4.编译javac java文件,会生成一个class文件

5.运行class文件,java class文件

可能出现的情况

  • 单词大小写问题
  • 尽量使用英文
  • 文件名要和类名相同,并且首字母大写
  • 符号使用了中文

5.编译型和解释型

  • Java运行机制

    • 编译型
    • 解释型
  • 程序运行机制

基础

1.注释

平时我们编写代码,在代码量比较少的时候,我们还可以看懂自己写的代码,但是当项目结构一旦复杂起来,我们就需要使用到注释了。

注释并不会被执行,是给我们写代码的人看的

书写注释是一个非常好的习惯

Java中的注释有三种:

  • 单行注释
  • 多行注释
  • 文档注释
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
public class HelloWorld {
public static void main(String[] args) {
//单行注释
//输出一个Hello,World!
System.out.println("Hello,World!");
}

//多行注释 /* 注释 */
/*
我是多行注释
我是多行注释
我是多行注释
我是多行注释
*/

//JavaDoc 文档注释 /** 注释内容 */
/**
* @Description HelloWorld
* @Author liuyunxuan
*/

/***
* _ooOoo_
* o8888888o
* 88" . "88
* (| -_- |)
* O\ = /O
* ____/`---'\____
* . ' \\| |// `.
* / \\||| : |||// \
* / _||||| -:- |||||- \
* | | \\\ - /// | |
* | \_| ''\---/'' | |
* \ .-\__ `-` ___/-. /
* ___`. .' /--.--\ `. . __
* ."" '< `.___\_<|>_/___.' >'"".
* | | : `- \`.;`\ _ /`;.`/ - ` : | |
* \ \ `-. \_ __\ /__ _/ .-` / /
* ======`-.____`-.___\_____/___.-`____.-'======
* `=---='
*
* .............................................
* 佛祖保佑 永无BUG
*/
}

2.标识符和关键字

  • 标识符
    • 所有的标识符都应该以字母(A-Z 或者 a-z),美元符($),或者下划线(_)开始;
    • 首字符之后可以是字母(A-Z 或者 a-z)美元符($)、下划线()或数字的任何字符组合;
    • 不能使用关键字作为变量名或方法名;
    • 标识符是大小写敏感的;
    • 可以使用中文命名,但是一般不建议这样去使用,也不建议使用拼音。
1
2
3
4
5
6
7
8
9
10
11
12
13
public class Demo01 {
public static void main(String[] args) {

String Ahello = "liuyunxuan";
String hello = "liuyunxuan";
String $hello = "liuyunxuan";
String _hello = "liuyunxuan";

String _vvhh = "liuyunxuan";
String 王者荣耀 = "liuyunxuan";

}
}
  • 关键字
关键字描述
abstract用于声明抽象类和方法
assert断言
boolean基本数据类型之一
break终止循环或 switch 结构
byte基本数据类型之一
caseswitch 语句的一部分
catch异常处理的一部分
char基本数据类型之一
class定义类
const保留关键字,未使用
continue继续执行循环的下一次迭代
defaultswitch 语句的一部分或 enum 中的默认方法
do循环结构的一部分
double基本数据类型之一
elseif 语句的一部分
enum定义枚举
extends继承
final表示不可更改
finally异常处理的一部分
float基本数据类型之一
for循环结构
goto保留关键字,未使用
if条件语句
implements实现接口
import导入包或类
instanceof类型检查运算符
int基本数据类型之一
interface定义接口
long基本数据类型之一
native方法属性,指示方法由本地代码实现
new创建新对象
null空引用
package定义包
private访问修饰符
protected访问修饰符
public访问修饰符
return返回值或退出方法
short基本数据类型之一
static表示静态成员
strictfp浮点数运算严格控制
super引用父类
switch多分支选择语句
synchronized控制对共享资源的访问
this当前对象的引用
throw抛出异常
throws方法声明抛出异常
transient变量属性,表示变量不参与序列化
try异常处理的一部分
void表示没有返回值
volatile变量属性,表示变量的值可能被不同线程改变
while循环结构

3.数据类型

  • 强类型语言
    • 要求变量的使用要严格符合规定,所有变量都必须先定义后才能使用。
  • 弱类型语言
  • 数据类型基本分类
    • 基本类型
      • 数值类型
        • 整数类型
          • 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
        • 浮点类型
          • float占4字节
          • double占8字节
        • 字符类型:char占2字节
      • boolean类型:占1位其值只有tue和fase两个。
    • 引用类型
      • 接口
      • 数组
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
public class Demo02 {
public static void main(String[] args) {
// 八大基本数据类型

// 整数
int num1 = 10; // 最常用
byte num2 = 20;
short num3 = 30;
long num4 = 40L; // Long类型要在数字后面加L

// 小数:浮点数
float num5 = 50.1F; // float类型要在数字后面加F
double num6 = 3.1415926534546246455;

// 字符类型
char name = 'A';

// 字符串,String不是关键字,类
String names = "liuyunxaun";

// 布尔值
boolean flag = true;
boolean flag2 = false;
}
}

什么是字节

  • 位(bit):是计算机内部数据储存的最小单位,11001100是一个八位二进制数。
  • 字节(byte):是计算机中数据处理的基本单位,习惯上用大写B来表示,1B(byte字节)=8bit(位)。
  • 字符:是指计算机中使用的字母、数字、字和符号。
    • 1bit表示1位
    • 1Byte表示一个字节1B=8b
    • 1024B=1KB
    • 1024KB=1M
    • 1024M=1G

拓展

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
public class Demo03 {
public static void main(String[] args) {
// 整数拓展: 进制 二进制0b 十进制 八进制0 十六进制0x

int i = 10;
int i1 = 010; // 八进制0
int i2 = 0x10; // 十六进制0x

System.out.println(i); // 10
System.out.println(i1); // 8
System.out.println(i2); // 16

System.out.println("-------------------------------------");
//************************************************
// 浮点数拓展
// BigDecimal 数据工具类
// float 有限 离散 舍入误差 大约 接近但不等于
// 最好完全使用浮点数进行比较

float f = 0.1f; // 0.1
double d = 1.0 / 10; // 0.1

System.out.println(f == d); // false

float d1 = 2425444564215654564f;
float d2 = d1 + 1;

System.out.println(d1 == d2); // true

System.out.println("-------------------------------------");
//************************************************
// 字符拓展
char c1 = 'a';
char c2 = '中';

System.out.println(c1);
System.out.println((int) c1); // 强制转换

System.out.println(c2);
System.out.println((int) c2); // 强制转换

// 所有字符的本质还是数字
// 编码 Unicode 2字节 0 - 65536 Excel

char c3 = '\u0061';

System.out.println(c3); // a

// 转义字符
// \t 制表符
// \n 换行
// ......

System.out.println("hello\tworld!");
System.out.println("hello\nworld!");

System.out.println("-------------------------------------");

//
String sa = "hello world";
String sb = "hello world";
System.out.println(sa == sb); // false

String sc = "hello world";
String sd = "hello world";
System.out.println(sc == sd); // true

// 布尔值扩展
boolean flag = true;

if (flag) {
} // 新手
if (flag) {
} // 老油条

// 代码要精简易读
}
}

4.类型转换

  • 由于Java是强类型语言,所以要进行有些运算的时候的,需要用到类型转换。

    1
    2
    低 ------------------------------------------------> 高
    byte -> short -> char -> int -> long -> float -> double
  • 运算中,不同类型的数据先转化为同一类型,然后进行运算。

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
public class Demo04 {
public static void main(String[] args) {
int i = 128;
byte b = (byte)i; // 内存溢出
double b1 = i;

// 强制转换 (类型)变量名 高--低
// 自动转换 低--高

System.out.println(i);
System.out.println(b);
System.out.println(b1);

/*
注意点:
1.不能对布尔类型转换
2.不能将对象类型转换为不相干的类型
3.在把高容量转换到低容量时,强制转换
4.转换的时候可能存在内存溢出,或者精度问题!
*/

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

System.out.println((int)123.7);
System.out.println((int)-45.89f);

System.out.println("=======================");
char a = 'a';
int c = a+1;

System.out.println(c); // 98
System.out.println((char)c); // b

}
}
  • 常见问题
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Demo05 {
public static void main(String[] args) {
// 操作比较大时,注意溢出
// JDK7新特性,数字之间可以用下划线分割
int money = 10_0000_0000;
System.out.println(money);

int years = 20;
int total = money*years; // -1474836480 计算时溢出
System.out.println(total);

long total2 = money*years;
System.out.println(total2); // 默认是int,转换之前已经存在问题了!!!

long total3 = money*(long)years;
System.out.println(total3); // 20000000000

}
}

5.变量

  • 变量:可以变化的量。
  • Java是一种强类型语言,每个变量都必须声明其类型。
  • Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。
  • 注意事项
    • 每个变量都有类型,类型可以是基本类型,也可以是引用类型;
    • 变量名必须是合法的标识符;
    • 变量声明是一条完整的语句,因此每一个声明都必须以分号结束。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Demo06 {

static int allClicks = 0; // 类变量
String str = "hello world"; // 实例变量

public static void main(String[] args) {
// int a,b,c;
// int a=1,b=2,c=3;
String name = "wahaha";
char x = 'X';
double pi = 3.14;

}

public void method() {
int i = 0; // 局部变量
}
}
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
public class Demo07 {
// 类变量 static
static double salary = 2500;

// 属性:变量

// 实例变量:从属于对象:实例变量:从属于对象;如果不自行初始化,这个类型的默认值 0 0.0
// 布尔值:默认是 faLse
// 除了基本类型,其余的都是null
String name;
int age;

// main 方法
public static void main(String[] args) {
// 局部变量:必须声明和初始化值
int i = 10;

System.out.println(i);

// 变量类型 变量名字 = new Demo08();
Demo07 demo07 = new Demo07();
System.out.println(demo07.age);
System.out.println(demo07.name);

// 类变量 static
System.out.println(salary);

}

// 其他方法
public void add(int i) {
System.out.println(i);
}
}
  • 常量( Constant):初始化( initialize)后不能再改变值!不会变动的值;
  • 所谓常量可以理解成一种特殊的变量,它的值被设定后,在程序运行过程中不允许被改变。
  • 常量名一般使用大写字符。
1
2
3
4
5
6
7
8
9
public class Demo08 {

// 修饰符,不存在先后顺序
static final double PI = 3.14;

public static void main(String[] args) {
System.out.println(PI);
}
}
  • 变量的命名规范
    • 所有变量、方法、类名:见名知意;
    • 类成员变量:首字母小和驼峰原则:monthSalary;
    • 局部变量:首字母小写和驼峰原则;
    • 常量:大写字母和下划线:MAX_VALUE;
    • 类名:首字母大写和驼峰原则:Man, GoodMan;
    • 方法名:首字母小写和驼峰原则:run(),runRun()。

6.基本运算符

Java语言支持如下运算符:

  • 算术运算符:+,-,*,/,%,++,–
  • 赋值运算符: =
  • 关系运算符:>,≤,>=,<=,==,!=, instanceof
  • 逻辑运算符:&&,‖,!
  • 位运算符:&,|,A,~,>>,<<,>>>(了解!!!)
  • 条件运算符: ?:
  • 扩展赋值运算符:+=,-=,*=,/=
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package operator;

public class Demo01 {
public static void main(String[] args) {
// 二元运算符
//Ctrl + D : 复制当前行到下一行
int a = 10;
int b = 20;
int c = 25;
int d = 25;

System.out.println(a+b);
System.out.println(a-b);
System.out.println(a*b);
System.out.println(a/b);
System.out.println(a/(double)b);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package operator;

public class Demo02 {
public static void main(String[] args) {
long a = 123123123123123L;
int b = 123;
short c = 10;
byte d = 8;

System.out.println(a+b+c+d);//Long
System.out.println(b+c+d);//Int
System.out.println(c+d);//Int
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package operator;

public class Demo03 {
public static void main(String[] args) {
// 关系运算符返回的结果:正确,错误 布尔值
// if
int a = 10;
int b = 20;
int c = 22;
// 取余
System.out.println(c%a); // c / a 21/10=2...1
System.out.println(a>b);
System.out.println(a<b);
System.out.println(a==b);
System.out.println(a!=b);
}
}

8.自增自减运算符、初识Math类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package operator;

public class Demo04 {
public static void main(String[] args) {
// ++ -- 自增,自减 一元运算符
int a = 3;

int b = a++; // 执行完这一行代码后,先给b赋值,再自增
System.out.println(a);
int c = ++a; // 执行完这一行代码前,先自增,再给c赋值

System.out.println(a);
System.out.println(b);
System.out.println(c);

// 幂运算 2^3
double pow = Math.pow(2,3);
System.out.println(pow);

}
}

9.逻辑运算符、位运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package operator;

public class Demo05 {
// 逻辑运算符
public static void main(String[] args) {
// 与(and) 或(or) 非(取反)
boolean a = true;
boolean b = false;

System.out.println("a && b:" + (a && b)); // 逻辑与:两个变量都为真,结果才为true
System.out.println("a || b:" + (a || b)); // 逻辑或:两个变量有一个为真,则结果才为true
System.out.println("!(a && b):" + !(a && b)); // 取反:如果为真,则变为假;如果为假,则变为真

// 短路运算
int c = 5;
boolean d = (c < 4) && (c++ < 4);
System.out.println(d);
System.out.println(c);

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package operator;

public class Demo06 {
public static void main(String[] args) {
/*
A = 0011 1100
B = 0000 1101
--------------------------
A&B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001
~B = 1111 0010

2*8 = 16 2*2*2*2
效率极高!
<< *2
>> /2

*/

System.out.println(2<<3);
}
}

10.三元运算符及小结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package operator;

public class Demo07 {
public static void main(String[] args) {
int a = 10;
int b = 20;

a += b; // a = a+b
a -= b; // a = a-b

System.out.println(a);

// 字符串连接
System.out.println(""+a+b);

System.out.println(a+b+"");

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package operator;

// 三元运算符
public class Demo08 {
public static void main(String[] args) {
// x ? y : z
// 如果x==true,则结果为y,否则结果为z

int score = 80;
String type = score < 60 ? "不及格" : "及格";
System.out.println(type);

}
}

11.包机制

  • 为了更好地组织类,Java提供了包机制,用于区别类名的命名空间。
  • 包语句的语法格式为:
1
package pkg1[.pkg2[.pkg3...]];
  • 一般利用公司域名倒置作为包名;
  • 为了能够使用某一个包的成员,我们需要在Java程序中明确导入该包。使用” import”语句可完成此功能。
1
import package1[.package2...].(classname|*);

12.JavaDoc生成文档

  • javadoc命令是用来生成自己API文档的。
  • 参数信息
    • @ author作者名
    • @ version版本号
    • @ since指明需要最早使用的jdk版本
    • @ paran参数名
    • @ return返回值情况
    • @ throws异常抛出情况
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package operator;

public class Doc {

String name;

/**
* @param name
* @return
* @throws Exception
* @author
*/
public String test(String name) throws Exception {
return name;
}
}
1
2
javadoc -encoding UTF-8 -charset UTF-8 Doc.java
//DOS命令生成文档

流程控制

1.用户交互 Scanner

  • 之前我们学的基本语法中我们并没有实现程序和人的交互,但是Java给我们提供了这样一个工具类,我们可以获取用户的输入。 java. util. Scanner是Java5的新特征,我们可以通过Scanner类来获取用户的输入。

  • 基本语法

    1
    Scanner s = new Scanner(System.in);
  • 通过 Scanner类的next()与 nextLine()方法获取输入的字符串,在读取前我们一般需要使用 hasNext()与 hasNextLine()判断是否还有输入的数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package scanner;

import java.util.Scanner;

public class Demo01 {
public static void main(String[] args) {
// 创建一个扫描器对象,用于接收键盘数据
Scanner scanner = new Scanner(System.in);

System.out.println("使用next方法接收:");

// 判断用户有没有输入字符串
if(scanner.hasNext()){
String str = scanner.next();
System.out.println("输入的内容为:" + str);
}

// 凡是属于IO流的类如果不关闭会一直占用资源,要养成好习惯用完就关掉
scanner.close();
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package scanner;

import java.util.Scanner;

public class Demo02 {
public static void main(String[] args) {
// 从键盘接收数据
Scanner scanner = new Scanner(System.in);

System.out.println("使用nextLine方式接收:");

// 判断是否还有输入
if(scanner.hasNextLine()){
String str = scanner.nextLine();
System.out.println("输出的内容为:" + str);
}

scanner.close();
}
}

  • next():
    • 1、一定要读取到有效字符后才可以结束输入。
    • 2、对输入有效字符之前遇到的空白,next()方法会自动将其去掉。
    • 3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。
    • 4、next()不能得到带有空格的字符串。
  • nextLine():
    • 1、以 Enter为结束符也就是说 nextLine()方法返回的是输入回车之前的所有字符。
    • 2、可以获得空白。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package scanner;

import java.util.Scanner;

public class Demo03 {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);

System.out.println("请输入数据:");

String str = scanner.nextLine();

System.out.println("输出的内容为:"+str);

scanner.close();
}
}

2.Scanner进阶使用

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
package scanner;

import java.util.Scanner;

public class Demo04 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);

// 从键盘接收数据
int i = 0;
float f = 0.0f;

System.out.println("请输入整数:");

// 如果……那么……
if (scanner.hasNextInt()) {
i = scanner.nextInt();
System.out.println("整数数据:" + i);
} else {
System.out.println("输入的不是整数数据!");
}

System.out.println("请输入小数:");

// 如果……那么……
if (scanner.hasNextFloat()) {
f = scanner.nextFloat();
System.out.println("小数数据:" + f);
} else {
System.out.println("输入的不是小数数据!");
}

scanner.close();
}
}
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
package scanner;

import java.util.Scanner;

public class Demo05 {
public static void main(String[] args) {
// 求输入的数字的总和及平均数
Scanner scanner = new Scanner(System.in);

// 和
double sum = 0;
// 计算输入了多少个数字
int m = 0;

// 通过循环判断是否输入,并统计求和
while (scanner.hasNextDouble()) {
double x = scanner.nextDouble();
System.out.println("你输入了第" + m + "个数据,当前结果为sum=" + sum);
m = m + 1;
sum = sum + x;
}

System.out.println(m + "个数的和为:" + sum);
System.out.println(m + "个数的平均数是:" + (sum / m));

scanner.close();
}
}

2.顺序结构

  • JAVA的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行。
  • 顺序结构是最简单的算法结构。
  • 语句与语句之间,框与框之间是按从上到下的顺序进行的,它是由若干个依次执行的处理步骤组成的,==它是任何一个算法都离不开的一种基本算法结构==。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package struct;

public class ShunXuDemo {
public static void main(String[] args) {
System.out.println("hello1");
System.out.println("hello2");
System.out.println("hello3");
System.out.println("hello4");
System.out.println("hello5");
System.out.println("hello6");
System.out.println("hello7");
System.out.println("hello8");
}
}

3.if选择结构

  • if单选择结构

    • 我们很多时候需要去判断一个东西是否可行,然后我们才去执行,这样一个过程在程序中用if语句来表示。
    1
    2
    3
    if(布尔表达式){
    // 如果布尔表达式为true将执行的语句
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    package struct;

    import java.util.Scanner;

    public class IfDemo01 {
    public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);

    System.out.println("请输入内容:");
    String s = scanner.nextLine();

    // equals:判断字符串是否相等
    if (s.equals("Hello")) {
    System.out.println(s);
    }

    System.out.println("End");

    scanner.close();
    }
    }
  • if双选择结构

    1
    2
    3
    4
    5
    if(布尔表达式){
    // 如果布尔表达式为true
    }else{
    // 如果布尔表达式值为false
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    package struct;

    import java.util.Scanner;

    public class IfDemo02 {
    public static void main(String[] args) {
    // 考试分数大于60就是及格,小于60则为不及格
    Scanner scanner = new Scanner(System.in);

    System.out.println("请输入成绩:");
    int score = scanner.nextInt();

    if (score > 60) {
    System.out.println("及格");
    } else {
    System.out.println("不及格");
    }

    scanner.close();
    }
    }
  • if多选择结构

    1
    2
    3
    4
    5
    6
    7
    8
    9
    if(布尔表达式1){
    // 如果布尔表达式1为true执行代码
    }else if(布尔表达式2){
    // 如果布尔表达式2为true执行代码
    }else if(布尔表达式3){
    // 如果布尔表达式3为true执行代码
    }else{
    // 如果以上布尔表达式值都不为true执行代码
    }
    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
    package struct;

    import java.util.Scanner;

    public class IfDemo03 {
    public static void main(String[] args) {
    // 考试分数大于60就是及格,小于60则为不及格
    Scanner scanner = new Scanner(System.in);

    System.out.println("请输入成绩:");
    int score = scanner.nextInt();

    if (score == 100) {
    System.out.println("恭喜满分!");
    } else if (score < 100 && score >= 90) {
    System.out.println("A级");
    } else if (score < 90 && score >= 80) {
    System.out.println("B级");
    } else if (score < 80 && score >= 70) {
    System.out.println("C级");
    } else if (score < 70 && score >= 60) {
    System.out.println("D级");
    } else if (score < 60 && score >= 0) {
    System.out.println("不及格");
    } else {
    System.out.println("成绩不合法");
    }

    scanner.close();
    }
    }
1
2
3
4
5
6
7
8
9
10
    
- 嵌套的f结构

```java
if(布尔表达式1){
// 如果布尔表达式1为true执行代码
if(布尔表达式2){
// 如果布尔表达式2为true执行代码
}
}

4.switch多选择结构

  • 多选择结构还有一个实现方式就是 switch case语句。

  • switch case语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。

  • switch语句中的变量类型可以是:

    • byte、short、int或者char
    • 从Java SE 7开始
    • switch支持字符串String类型了
    • 同时case标签必须为字符串常量或者字面量。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    switch(expression){
    case value:
    //语句
    break;//可选
    case value:
    //语句
    break;//可选
    //你可以有任意数量的case语句
    default://可选
    //语句
    }
    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
    package struct;

    import java.util.Scanner;

    public class SwitchDemo01 {
    public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);

    //
    char grade = 'C';
    switch (grade) {
    case 'A':
    System.out.println("优秀");
    break;
    case 'B':
    System.out.println("良好");
    break;
    case 'C':
    System.out.println("及格");
    break;
    case 'D':
    System.out.println("再接再厉");
    break;
    case 'E':
    System.out.println("挂科");
    break;
    default:
    System.out.println("成绩错误!!!");
    }

    scanner.close();
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    package struct;

    public class SwitchDemo02 {
    public static void main(String[] args) {
    String name = "张三";
    //JDK7的新特性,表达式结果可以是字符串
    //字符串的本质还是数字
    //反编译 java---class(字节码文件)---反编译(IDEA)

    switch (name) {
    case "张三":
    System.out.println("张三");
    break;
    case "李四":
    System.out.println("李四");
    break;
    default:
    System.out.println("未知");
    }
    }
    }

5.while循环结构

  • while循环

    1
    2
    3
    while(布尔表达式){
    // 循环内容
    }
    • 只要布尔表达式为true,循环就会一直执行下去。
    • ==我们大多数情况是会让循环停止下来的,我们需要一个让表达式失效的方式来结束循环==。
    • 少部分情况需要循环一直执行,比如服务器的请求响应监听等。
    • 循环条件一直为true就会造成无限循环【死循环】,我们正常的业务编程中应该尽量避免死循环。会影响程序性能或者造成程序卡死奔溃!
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    package struct;

    public class WhileDemo01 {
    public static void main(String[] args) {
    // 输出1~100
    int i = 0;

    while (i < 100) {
    i++;
    System.out.println(i);
    }
    }
    }
    1
    2
    package struct;

public class WhileDemo02 {
public static void main(String[] args) {
// 死循环
while(true){
// 等待客户链接
// 定时检查
// ……
}
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

```java
package struct;

public class WhileDemo03 {
public static void main(String[] args) {
// 计算1+2+3+...+100=?

int i = 0;
int sum = 0;

while (i <= 100) {
sum = sum + i;
i++;
}

System.out.println(sum);
}
}

6.DoWhile循环

  • do……while循环

    1
    2
    3
    do{
    // 代码语句
    }while(布尔表达式);
    • do……while循环和 while循环相似,不同的是,do…while循环至少会执行一次。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    package struct;

    public class DoWhileDemo01 {
    public static void main(String[] args) {
    // 计算1+2+3+...+100=?

    int i = 0;
    int sum = 0;

    do {
    sum = sum + i;
    i++;
    } while (i <= 100);

    System.out.println(sum);
    }
    }
    1
    2
    package struct;

public class DoWhileDemo02 {
public static void main(String[] args) {
int a = 0;
while (a < 0) {
System.out.println(a);
a++;
}
System.out.println(“==================”);
do {
System.out.println(a);
a++;
} while (a < 0);
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

>- While和do- While的区别:
>- while先判断后执行。 do……while是先执行后判断!
>- Do……while总是保证循环体会被至少执行一次!这是他们的主要差别。

### 7.For循环

- for循环

- for循环语句是支持迭代的一种通用结构,是最有效、最灵活的循环结构。
- for循环执行的次数是在执行前就确定的。语法格式如下:

```java
for(初始化;布尔表达式;更新){
// 代码语句
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package struct;

public class ForDemo01 {
public static void main(String[] args) {
int a = 1; // 初始化条件
while (a <= 100) { // 条件判断
System.out.println(a); // 循环体
a += 2; // 迭代
}

System.out.println("while循环结束!");

// 初始化 条件判断 迭代
for (int i = 1; i <= 100; i++) {
System.out.println(i);
}

System.out.println("for循环结束!");
}
}
  • 关于for循环有以下几点说明:
    • 最先执行初始化步骤。可以声明一种类型,但可初始化一个或多个循环控制变量,也可以是空语句。
    • 然后,检测布尔表达式的值。如果为true,循环体被执行。如果为false,循环终止,开始执行循环体后面的语句。
  • 执行一次循环后,更新循环控制变量(迭代因子控制循环变量的增减)。
    • 再次检测布尔表达式,执行上面的过程。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package struct;

public class ForDemo02 {
public static void main(String[] args) {
// 计算0到100之间的奇数和偶数的和

int oddSum = 0;
int evenSum = 0;

for (int i = 0; i <= 100; i++) {
if (i % 2 != 0) {
oddSum += i;
} else {
evenSum += i;
}
}

System.out.println("奇数的和:" + oddSum);
System.out.println("偶数的和:" + evenSum);
}
}
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
package struct;

public class ForDemo03 {
public static void main(String[] args) {
// 用whiLe或for循环输出1-1000之间能被5整除的数,并且每行输出3个
// for (int i = 0; i < 1000; i++) {
// if(i%5==0){
// System.out.print(i + "\t");
// }
// if(i%(5*3)==0){ // 每行
// System.out.println();
// // System.out.print("\n");
// }
//
// /*
// println : 输出完会换行
// print : 输出完不会换行
// */
// }

int i = 0;
while (i < 1000) {
if (i % 5 == 0) {
System.out.print(i + "\t");
}
if (i % (5 * 3) == 0) { // 每行
System.out.println();
}
i++;
}

}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
package struct;

public class ForDemo04 {
public static void main(String[] args) {
// 打印9*9乘法表
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(i + "*" + j + "=" + i * j + "\t");
}
System.out.println();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package struct;

public class ForDemo05 {
public static void main(String[] args) {
int[] numbers = {10,20,30,40,50}; // 定义一个数组

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

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

// 遍历数组的元素
for(int x:numbers){
System.out.println(x);
}

}
}

5.break、continue、goto

  • break在任何循环语句的主体部分,均可用 break控制循环的流程。 ==break用于强行退出循环==,不执行循环中剩余的语句。( break语句也在 switch语句中使用)。
  • continue语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。
  • 关于goto关键字
    • goto关键字很早就在程序设计语言中出现。尽管goto仍是Java的一个保留字,但并未在语言中得到正式使用;Java没有goto。然而,在 breaki和 continue这两个关键字的身上,我们仍然能看出一些goto的影子—带标签的 break和continue。
    • “标签”是指后面跟一个冒号的标识符,例如:label;
    • 对Java来说唯一用到标签的地方是在循环语句之前。而在循环之前设置标签的唯一理由是:我们希望在其中嵌套另一个循环,由于 break和 continue关键字通常只中断当前循环,但若随同标签使用,它们就会中断到存在标签的地方。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package struct;

public class BreakDemo {
public static void main(String[] args) {
int i = 0;
while (i < 100) {
i++;
System.out.println(i);
if (i == 30) {
break;
}
}

System.out.println("123");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package struct;

public class ContinueDemo {
public static void main(String[] args) {
int i = 0;
while (i < 100) {
i++;
if (i % 10 == 0) {
System.out.println();
continue;
}
System.out.println(i);
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package struct;

public class LabelDemo {
public static void main(String[] args) {
// 打印101~150之间的所有质数
// 质数是指在大的自然数中,除1和它本身以外不再有其他因数的自然数。

int count = 0;

outer:
for (int i = 101; i < 150; i++) {
for (int j = 2; j < i / 2; j++) {
if (i % j == 0) {
continue outer;
}
}
System.out.print(i + " ");
}

}
}
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
package struct;

public class TestDemo {
// 打印三角形
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
for (int j = 5; j >= i; j--) {
System.out.print(" ");
}
for (int j = 1; j <= i; j++) {
System.out.print("*");
}
for (int j = 1; j < i; j++) {
System.out.print("*");
}
System.out.println();
}
}
}

/*
*
***
*****
*******
*********

进程已结束,退出代码0
*/

方法

1.什么是方法

  • Java方法是语句的集合,它们在一起执行一个功能。
    • 方法是解决一类问题的步骤的有序组合;
    • 方法包含于类或对象中;
    • 方法在程序中被创建,在其他地方被引用。
  • 设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合。我们设计方法的时候,最好保持方法的原子性,就是一个方法只完成1个功能,这样利于我们后期的扩展
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package method;

public class Demo01 {
// main方法
public static void main(String[] args) {
int sum = add(1, 2);
System.out.println(sum);
}

// 加法
public static int add(int a, int b) {
return a + b;
}
}

2.方法的定义及调用

  • Java的方法类似于其它语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个方法包含以下语法:

  • 方法包含一个方法头和一个方法体。下面是一个方法的所有部分:

    • 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
    • 返回值类型:方法可能会返回值。 returnValueType是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下, returnValueType是关键字void。
    • 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
    • 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
      • 形式参数:在方法被调用时用于接收外界输入的数据。
      • 实参:调用方法时实际传给方法的数据。
    • 方法体:方法体包含具体的语句,定义该方法的功能。
    1
    2
    3
    4
    5
    6
    修饰符 返回值类型 方法名(参数类型 参数名){
    ...
    方法体
    ...
    return 返回值;
    }
  • 调用方法:对象名.方法名(实参列表)

  • Java支持两种调用方法的方式,根据方法是否返回值来选择,当方法返回一个值的时候,方法调用通常被当做一个值。例如:

1
int larger = max(30,40);
  • 如果方法返回值是void,方法调用一定是一条语句。
1
System.out.println("Hello,liuyunxaun!");
  • 案例
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
package method;

public class Demo02 {
public static void main(String[] args) {
int max = max(10, 20);
System.out.println(max);
}

// 比大小
public static int max(int num1, int num2) {
int result = 0;

if (num1 == num2) {
System.out.println("num1==num2");
return 0; // 终止方法
}

if (num1 > num2) {
result = num1;
} else {
result = num2;
}

return result;
}
}

课后作业:值传递和引用传递

1
2
3
4
值传递 (Pass-by-Value)
在值传递中,当调用函数时,实际参数的值会被复制给形式参数。这意味着函数内部对形参所做的任何修改都不会影响到实参的原始值。
引用传递 (Pass-by-Reference)
在引用传递中,当调用函数时,不是传递参数的值,而是传递指向该参数的引用(即内存地址)。这意味着函数内部对形参所做的任何修改都会反映到实参上。

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
43
44
45
46
47
48
package method;

public class Demo02 {

public static void main(String[] args) {
int max = max(10, 20);
System.out.println(max);

double max2 = max2(10.0, 20.0);
System.out.println(max);
}

// 比大小
public static int max(int num1, int num2) {
int result = 0;

if (num1 == num2) {
System.out.println("num1==num2");
return 0; // 终止方法
}

if (num1 > num2) {
result = num1;
} else {
result = num2;
}

return result;
}

// 比大小
public static double max2(double num1, double num2) {
double result = 0;

if (num1 == num2) {
System.out.println("num1==num2");
return 0; // 终止方法
}

if (num1 > num2) {
result = num1;
} else {
result = num2;
}

return result;
}
}

4.命令行传参

1
2
3
4
5
6
7
8
9
10
package method;

public class Demo03 {
public static void main(String[] args) {
// args.length 数组长度
for(int i=0;i < args.length;i++){
System.out.println("args[" + i + "]:" + args[i]);
}
}
}

5.可变参数

  • JDK1.5开始,Java支持传递同类型的可变参数给一个方法。
  • 在方法声明中,在指定参数类型后加一个省略号()。
  • 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package method;

public class Demo04 {
public static void main(String[] args) {
Demo04 demo04 = new Demo04();
demo04.test(1, 2, 3, 4, 5);
}

public void test(int... i) {
System.out.println(i[0]);
System.out.println(i[1]);
System.out.println(i[2]);
System.out.println(i[3]);
System.out.println(i[4]);
}
}
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
package method;

public class Demo04 {
public static void main(String[] args) {
// 调用可变参数的方法
printMax(34, 3, 3, 2, 56.5);
printMax(new double[]{1, 2, 3});

}

public static void printMax(double... numbers) {
if (numbers.length == 0) {
System.out.println("没有数据!");
return;
}

double result = numbers[0];

// 排序
for (int i = 1; i < numbers.length; i++) {
if (numbers[i] > result) {
result = numbers[i];
}
}
System.out.println("The max Value is " + result);
}
}

6.递归

  • A方法调用B方法,我们很容易理解!
  • 递归就是:A方法调用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
package method;

import java.util.Scanner;

public class Demo05 {
// 5! 5*4*3*2*1
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个数:");
int number = scanner.nextInt();

int test = test(number);

System.out.println(number + "的阶乘:" + test);
}

public static int test(int n){
if(n==1){
return 1;
}else{
return n*test(n-1);
}
}
}

数组

1.数组概述

  • 数组是相同类型数据的有序集合。
  • 数组描述的是相同类型的若干个数据按照一定的先后次序排列组合而成。
  • 其中每一个数据称作一个数组元素每个数组元素可以通过一个下标来访问它们。

2.数组声明创建

  • 首先必须声明数组变量,才能在程序中使用数组。下面是声明数组变量的语法:
1
2
3
dataType[] arrayRefVar;	// 首选的方法

dataType arrayRefVar[]; // 效果相同,但不是首选方法
  • Java语言使用new操作符来创建数组,语法如下:
1
dataType[] arrayRefVar = new dataType[arraySize];
  • 数组的元素是通过索引访问的,数组索引从0开始。
  • 获取数组长度:arrays. length
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
package array;

public class ArrayDemo01 {
// 变量的类型 变量的名字 = 变量的值

public static void main(String[] args) {
int[] numbers; // 1.定义

numbers = new int[10]; // 2.创建一个数组
// 这里面可以存放10个int型数字

// 3.给数组赋值
numbers[0]=1;
numbers[1]=2;
numbers[2]=3;
numbers[3]=4;
numbers[4]=5;
numbers[5]=6;
numbers[6]=7;
numbers[7]=8;
numbers[8]=9;
numbers[9]=10;

System.out.println(numbers[9]);
}

}
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
package array;

public class ArrayDemo01 {
// 变量的类型 变量的名字 = 变量的值

public static void main(String[] args) {
int[] numbers; // 1.定义

numbers = new int[10]; // 2.创建一个数组
// 这里面可以存放10个int型数字

// 3.给数组赋值
numbers[0]=1;
numbers[1]=2;
numbers[2]=3;
numbers[3]=4;
numbers[4]=5;
numbers[5]=6;
numbers[6]=7;
numbers[7]=8;
numbers[8]=9;
numbers[9]=10;

// 计算所有数字的和
int sum = 0;
// 获取数组的长度: arrays.length
for(int i = 0;i<numbers.length;i++){
sum = sum + numbers[i];
}

System.out.println(sum);
}

}

内存分析


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package github.array;

public class ArrayDemo02 {
public static void main(String[] args) {
// 静态初始化 : 创建 + 赋值
int[] a = {1,2,3,4,5,6,7,8};
System.out.println(a[0]);

// 动态初始化
int[] b = new int[2];
b[0]=10;

System.out.println(b[0]);

}
}

数组的四个基本特点:

  • 其长度是确定的。数组一旦被创建,它的大小就是不可以改变的;
  • 其元素必须是相同类型不允许出现混合类型。
  • 数组中的元素可以是任何数据类型,包括基本类型和引用类型。
  • 数组变量属引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,==数组对象本身是在堆中的==。

下标越界及小结:

  • 下标的合法区间:[0, length-1],如果越界就会报错:
1
2
3
4
5
6
7
8
package github.array;

public class ArrayDemo03 {
public static void main(String[] args) {
int[] a = new int[2];
System.out.println(a[2]);
}
}
  • ArraylndexOutofBounds Exception:数组下标越界异常!
  • 数组是相同数据类型(数据类型可以为任意类型)的有序集合数组也是对象。
  • 数组元素相当于对象的成员变量。
  • 数组长度的确定的,不可变的。如果越界,则报:ArrayIndexOutofBounds。

3.数组使用

  • 普通的for循环

  • For-Each循环

  • 数组作方法入参

  • 数组作返回值

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
package array;

public class ArrayDemo04 {
public static void main(String[] args) {
int[] arrays = {1,2,3,4,5,6};

// JDK1.5,没有下标
// for(int array:arrays){
// System.out.println(array);
// }

// printArray(arrays);

int[] reverse = reverse(arrays);
printArray(reverse);

}
// 打印数组元素
public static void printArray(int[] arrays){
for(int i=0;i< arrays.length;i++){
System.out.println(arrays[i]+"");
}
}

// 反转数组
public static int[] reverse(int[] arrays){
int[] result = new int[arrays.length];

// 反转的操作
for (int i = 0,j= result.length-1; i < arrays.length; i++,j--) {
// result[] = arrays[i];
result[j] = arrays[i];
}

return result;
}
}

4.多维数组

  • 多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。
  • 二维数组
1
2
int a[][] = new int[2][5];
// 解析:以上二维数组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
package array;

public class ArrayDemo05 {
public static void main(String[] args) {
// [4][2]
/*
1,2 array[0]
2,3 array[1]
3,4 array[2]
5,6 array[3]
*/
int[][] array = {{1,2},{3,4},{5,6},{7,8}};

// 输出单个元素
printArray(array[0]);
System.out.println(array[0][0]);

System.out.println("----------------");

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

// 打印数组元素
public static void printArray(int[] arrays){
for(int i=0;i< arrays.length;i++){
System.out.println(arrays[i]+"");
}
}
}

5.Arrays类

  • 数组的工具类 javautil. Arrays
  • 由于数组对象本身并没有什么方法可以供我们调用但AP中提供了一个工具类 Arrays供我们使用从而可以对数据对象进行一些基本的操作。
  • 查看JDK帮助文档。
  • Arrays类中的方法都是 static 修饰的静态方法在使用的时候可以直接使用类名进行调用,而”不用”使用对象来调用(注意:是“不用”而不是“不能”)。
  • 具有以下常用功能:
    • 给数组赋值:通过fill方法。
    • 对数组排序:通过sort方法按升序。
    • 比较数组:通过 equals方法比较数组中元素值是否相等。
    • 查找数组元素:通过 binarySearch方法能对排序好的数组进行二分查找法操作。
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
package array;

import java.util.Arrays;

public class ArrayDemo06 {
public static void main(String[] args) {
int[] a = {1,2,3,4,9090,543,21,3,23};

System.out.println(a); // 地址值:[I@14ae5a5

// 打印数组元素Arrays.toString
System.out.print("系统打印数组方法:");
System.out.println(Arrays.toString(a));
System.out.print("自定义打印数组方法:");
printfArray(a);

// 数组排序
Arrays.sort(a);

System.out.println(Arrays.toString(a));

// 数组填充
Arrays.fill(a,2,4,12); // 数组2~4之间填充12
System.out.println("数组填充:" + Arrays.toString(a));

// 数组查找
int i = Arrays.binarySearch(a, 23);
System.out.println("查找的元素在数组中的位置:" + i);
}

public static void printfArray(int[] a){
for (int i = 0; i < a.length; i++) {
if(i==0){
System.out.print("[");
}
if(i==a.length-1){
System.out.print(a[i] + "]");
}else {
System.out.print(a[i] + ", ");
}
}
System.out.println();
}
}

6.冒泡排序

  • 冒泡排序无疑是最为出名的排序算法之一,总共有八大排序!
  • 两层循环,外层冒泡轮数,里层依次比较。
  • 这个算法的时间复杂度为O(n^2^)。
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
package array;

import java.util.Arrays;

public class ArrayDemo07 {
public static void main(String[] args) {
// 调用排序
int[] array = {12,63,1,95,44,62,78};
System.out.println("排序前:" + Arrays.toString(array));
int[] sort = sort(array); // 调用自定义冒泡排序函数
System.out.println("排序后:" + Arrays.toString(sort));

}
// 冒泡排序
/*
1.比较数组中,两个相邻的元素,如果第一个数比第二个数大,我们就交换他们的位置。
2.每一次比较,都会产生出一个最大或最小的数。
3.下一轮则可以少一次排序!
4.依次循环,直到结束。
*/

public static int[] sort(int[] array){
// 临时变量
int temp = 0;
// 外层循环,判断要走多少次;
for (int i = 0; i < array.length-1; i++) {

boolean flag = false; // 通过flag标识位减少没有意义的比较

// 内层循环,比较大小,如果第一个数比第二个数大,交换位置
for (int j = 0; j < array.length-1-i; j++) {
if (array[j] > array[j+1]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
flag = true;
}
}
if(flag==false){
break;
}
}
return array;
}
}

7.稀疏数组

  • 当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
  • 稀疏数组的处理方式是:
    • 记录数组一共有几行几列,有多少个不同值。
    • 把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模。
  • 如下图:左边是原始数组,右边是稀疏数组。

1622349200598

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package array;

public class ArrayDemo08 {
public static void main(String[] args) {
// 1.创建一个二维数组
int[][] array1 = new int[11][11];
array1[1][2] = 1;
array1[2][3] = 2;
// 输出原始数组
System.out.println("输出原始的数组");

for(int[] ints:array1){
for(int anInt : ints){
System.out.print(anInt + "\t");
}
System.out.println();
}

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

// 转换为稀疏数组保存
// 获取有效值的个数
int sum = 0;
for(int i = 0;i < 11;i++){
for (int j = 0; j < 11; j++) {
if(array1[i][j]!=0){
sum++;
}
}
}
System.out.println("有效值的个数:" + sum);

// 2.创建一个稀疏数组的数组
int[][] array2 = new int[sum+1][3];

array2[0][0] = 11;
array2[0][1] = 11;
array2[0][2] = sum;

// 遍历二维数组,将非零的值,存放到稀疏数组
int count = 0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
if(array1[i][j]!=0){
count++;
array2[count][0] = i;
array2[count][1] = j;
array2[count][2] = array1[i][j];
}
}
}

// 输出稀疏数组
System.out.println("稀疏数组:");

for (int i = 0; i < array2.length; i++) {
System.out.println(array2[i][0] + "\t"
+ array2[i][1] + "\t"
+ array2[i][2] + "\t");
}

System.out.println("===========");
System.out.println("还原");
// 1.读取稀疏数组
int[][] array3 = new int[array2[0][0]][array2[0][1]];
// 2.给元素还原值
for (int i = 1; i < array2.length; i++) {
array3[array2[i][0]][array2[i][1]] = array2[i][2];
}

// 3.打印
System.out.println("输出原始的数组:");

for(int[] ints:array3){
for(int anInt : ints){
System.out.print(anInt + "\t");
}
System.out.println();
}
}
}

面向对象

1.初识面向对象

  • 面向过程思想
    • 步骤清晰简单,第一步做什么,第二步做什么…
    • 面对过程适合处理一些较为简单的问题。
  • 面向对象思想
    • 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后,才对某个分类下的细节进行面向过程的思索。
    • 面向对象适合处理复杂的问题,适合处理需要多人协作的问题!
  • 对于描述复杂的事物,为了从宏观上把握、从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是,具体到微观操作,仍然需要面向过程的思路去处理。
  • 面向对象编程( Object- Oriented Programming,OOP)
  • 面向对象编程的本质就是:==以类的方式组织代码,以对象的组织(封装)数据==。
  • 三大特征:
    • 继承
    • 封装
    • 多态
  • 从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象。
  • 从代码运行角度考虑是先有类后有对象。类是对象的模板。

2.方法回顾和加深

  • 方法的定义

    • 修饰符
    • 返回类型
    • break:跳出 switch,结束循环和 return的区别。
    • 方法名:注意规范就OK,见名知意
    • 参数列表:(参数类型,参数名) …
    • 异常抛出:疑问,参考下文!
    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
    package oop;

    import java.io.IOException;

    // 类
    public class Demo01 {
    // main方法
    public static void main(String[] args) {

    }

    /*
    修饰符 返回值类型 方法名(...){
    // 方法体
    return 返回值;
    }
    */
    public String sayHello(){
    return "hello,world!";
    }

    public int max(int a,int b){
    return a>b ? a : b; // 三元运算符
    }

    // 数组下标越界:Arrayindexoutofbounds
    public void readFile(String file) throws IOException{

    }
    }
  • 方法的调用

    • 静态方法

    • 非静态方法

    • 形参和实参
    • 值传递和引用传递

    • this关键字

3.对象的创建分析

  • 类是一种抽象的数据类型它是对某一类事物整体描述/定义但是并不能代表某一个具体的事物。
  • 使用new关键字创建对象。
  • 使用new关键字创建的时候,除了分配内存空间之外,还会给刨建好的对象进行默认的初始化以及对类中构造器的调用。
  • 类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下俩个特点:
    • 1.必须和类的名字相同;
    • 2.必须没有返回类型也不能写void。
  • 构造器:
    • 1.和类名初问
    • 2.没有返回值
  • 作用:
    • 1.new本质在调用构造方法;
    • 2.初始化对象的值。
  • 注意:定义有参构造之后,如果想使用无参构造,显示的定义一个无参构造。

1622718352404

4.面向对象三大特性

封装:属性私有,get/set

  • 程序设计要追求高内聚低耦合。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。
  • 封装(数据的隐藏):通常,应禁止直接访问一个对象中数据的实际表示,而应该通过操作接口来访问,这称为信息隐藏。

  • 封装的作用:
    • 提高了代码的安全性,保护数据;
    • 隐藏代码的实现细则;
    • 统一接口;
    • 系统可维护增加了。

继承:object类、super、方法重写

  • 继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
  • extands的意思是“扩展”。子类是父类的扩展。
  • JAVA中类只有单继承,没有多继承!
  • 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖、组合、聚合等。
  • 继承关系的俩个类,一个为子类(派生类),一个为父类(基类)。子类继承父类使用关键字 extends来表示。
  • 子类和父类之间从意义上讲应该具有”is a”的关系。


  • Super概述

  • 私有的东西无法被继承!!!

super注意点

  1. super调用父类的构造方法,必须在构造方法的第一个

  2. super必须只能出现在子类的方法或者构造方法中!

  3. super和this不能同时调用构造方法!

VSthis

  • 代表的对象不同:
    • this:本身调用者这个对象;
    • super:代表父类对象的应用;
  • 前提
    • this:没有继承也可以使用;
    • super:只能在继承条件才可以使用;
  • 构造方法
    • this():本类的构造;
    • super():父类的构造。

  • 方法的重写:

  • 重写:需要有继承关系,子类重写父类的方法!

  1. 方法名必须相同;
  2. 参数列表列表必须相同;
  3. 修饰符:范围可以扩大但不能缩小: public>Protected>Default>private
  4. 抛出的异常:范围,可以被缩小,但不能扩大;ClassNotFoundException–> Exception(大)
  • 重写,子类的方法和父类必要一致;方法体不同!
  • 为什么需要重写:父类的功能,子类不一定需要,或者不一定满足!

多态:

  • 即同一方法可以根据发送对象的不同而采用多种不同的行为方式。

  • 一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多。

  • 多态存在的条件:

    • 有继承关系;
    • 子类重写父类方法;
    • 父类引用指向子类对象。
  • 多态注意事项:

    1. 多态是方法的多态,属性没有多态;
    2. 父类和子类,有联系,类型转换异常!ClassCastException!
    3. 存在条件:继承条件,方法需要重写!父类引用指向子类对象!
      1. static 方法,属于类,它不属于实例
      2. final 常量;
      3. private 方法;

instanceof:判断一个对象是什么类型。

static关键字

1622839303772

1622839400252

1622839591329

1622839694925

1622840028314

5.抽象类和接口

抽象类

  • abstract修饰符可以用来修饰方法也可以修饰类如果修饰方法那么该方法就是抽象方法如果修饰类那么该类就是抽象类。
  • 抽象类中可以没有抽象方法但是有抽象方法的类一定要声明为抽象类。
  • 抽象类,不能使用new关键字来创建对象它是用来让子类继承的。
  • 抽象方法只有方法的声明没有方法的实现它是用来让子类实现的。
  • 子类继承抽象类那么就必须要实现抽象类没有实现的抽象方法否则该子类也要声明为抽象类。

1622840648753

接口

  • 普通类:只有具体实现;
  • 抽象类:具体实现和规范(抽象方法)都有!
  • 接口:只有规范!
  • 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…则必须能…”的思想。如果你是天使,则必须能飞。如果你是汽车,则必须能跑。如果你好人,则必须干掉坏人;如果你是坏人,则必须欺负好人。
  • 接口的本质是契约,就像我们人间的法律一样。制定好后大家都遵守。
  • OO的精髓,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都只针对具备了抽象能力的语言(比如c++、java、c#等),就是因为设计模式所硏究的,实际上就是如何合理的去抽象。
  • ==声明类的关键字是 class,声明接口的关键字是 interface==。

1622841402410

6.内部类及OOP实战

  • 内部类就是在一个类的内部在定义一个类,比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类了。
    1. 成员内部类
    2. 静态内部类
    3. 局部内部类
    4. 匿名内部类

1622842212114

异常

1.什么是异常

    实际工作中,遇到的情况不可能是非常完美的。比如:你写的某个模块,用户输入不一定符合你的要求、你的程序要打开某个文件,这个文件可能不存在或者文件格式不对,你要读取数据库的数据,数据可能是空的等。我们的程序再跑着,内存或硬盘可能满了。等等。

    软件程序在运行过程中,非常可能遇到刚刚提到的这些异常问题,我们叫异常,英文是:Exception,意思是例外。这些,例外情况,或者叫异常,怎么让我们写的程序做出合理的处理。而不至于程序崩溃。

    异常指程序运行中出现的不期而至的各种状况如:文件找不到、网络连接失败、非法参数等。异常发生在程序运行期间它影响了正常的程序执行流程。

要理解Java异常处理是如何工作的,需要掌握以下三种类型的异常:

  • 检查性异常:最具代表的检查性异常是用户错误或问题引起的异常,这是程序员无法预见的例如要打开一个不存在文件时,一个异常就发生了,这些异常在编译时不能被简单地忽略。
  • 运行时异常:运行时异常是可能被程序员避免的异常。与检查性异常相反,运行时异常可以在编译时被忽略。
  • 错误==ERROR==:错误不是异常,而是脱离程序员控制的冋题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了,它们在编译也检查不到的。

2.异常体系结构

  • Java把异常当作对象来处理,并定义一个基类 java. lang.Throwable作为所有异常的超类。
  • 在 Java API中已经定义了许多异常类,这些异常类分为两大类,错误Error和异常 Exception。

Error

  • Error类对象由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。
  • Java虚拟机运行错误( Virtual Machine Error),当JVM不再有继续执行操作所需的内存资源时,将出现 ==OutofMemory Error==。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。
  • 还有发生在虛拟机试图执行应用时,如类定义错误( NoClass Deffound error)、链接错误( Linkage Error)。这些错误是不可查的,因为它们在应用程序的控制和处理能力之外,而且绝大多数是程序运行时不允许出现的状况。

Exception

  • 在 Exception分支中有一个重要的子类 Runtime Exception(运行时异常)
    • ArraylndexOutOfBoundsException(数组下标越界)
    • NullPointerException(空指针异常)
    • ArithmeticException(算术异常)
    • Missing Resource Exception(丢失资源)
    • ClassNotFound Exception(找不到类)等异常,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。
  • 这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生;
  • Error和 Exception的区别:Error通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时,Java虛拟机(JVM)一般会选择终止线程;Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常。

3.Java异常处理机制与处理异常

  • 抛出异常
  • 捕获异常
  • 异常处理五个关键字:
    • try、catch、 finally、throw、throws

image-20240921235657855

4.自定义异常

  • 使用Java内置的异常类可以描述在编程时岀现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需继承 Exception类即可。
  • 在程序中使用自定义异常类,大体可分为以下几个步骤:
    1. 创建自定义异常类。
    2. 在方法中通过 throw关键字抛出异常对象。
    3. 如果在当前抛出异常的方法中处理异常,可以使用try- catch语句捕获并处理;否则在方法的声明处通过 throws关键字指明要抛岀给方法调用者的异常,继续进行下一步操作。
    4. 在出现异常方法的调用者中捕获并处理异常。

image-20240921235753388

5.总结

  • 处理运行时异常时,采用逻辑去合理规避同时辅助 try-catch ;
  • 处理在多重 catch块后面,可以加一个 catch( Exception)来处理可能会被遗漏的异常;
  • 对于不确定的代码,也可以加上try- catch,处理潜在的异常;
  • 尽量去处理异常,切忌只是简单地调用 printStackTrace0去打印输出;
  • 具体如何处理异常,要根据不同的业务需求和异常类型去决定;
  • 尽量添加 finally!语句块去释放占用的资源。