黑马程序员Java零基础视频教程_上部(P81-P128)学习笔记

1. 面向对象

面向对象介绍

  • 面向:拿、找
  • 对象:能干活的东西
  • 面向对象编程:拿东西过来做对应的事情

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.1 设计对象并使用

1.1.1 类与对象

在这里插入图片描述

  1. 类(设计图) :是对象共同特征的描述;
  2. 对象:是真实存在的具体东西。

在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
public class 类名{
1、成员变量(代表属性,一般是名词)
2、成员方法(代表行为,一般是动词)
3、构造器: (后面学习)
4、代码块 (后面学习)
5、内部类 (后面学习)
}
运行项目并下载源码java运行1234567
public class Phone {
//属性
String brand;
double price;

//行为
public void call(){
System.out.println("手机打电话");
}
public void playGame(){
System.out.println("玩游戏");
}
}

public class Main {
public static void main(String[] args) {
Phone P = new Phone();
P.brand = "iphone";
P.price = 9999.99;
System.out.println(P.brand);
System.out.println(P.price);

P.call();
P.playGame();

}
}

在这里插入图片描述
定义类的补充注意事项
●用来描述一类事物的类,专业叫做: Javabean类
在Javabean类中,是不写main方法的。

●在以前,编写main方法的类,叫做测试类
我们可以在测试类中创建javabean类的对象并进行赋值调用。

在这里插入图片描述
类名首字母建议大写,需要见名知意,驼峰模式。
一个Java文件中可以定义多个class类,且只能一个类是public修饰,而且public修饰的类名必须成为代码文件名。
实际开发中建议还是一一个文件定义一个class类。

成员变量的完整定义格式是:修饰符 数据类型 变量名称 = 初始化值 ;一般无需指定初始化值,存在默认值。

在这里插入图片描述
按住鼠标滚轮批量修改,按住ait也可以

1.2 封装

面向对象三大特征:封装、继承、多态

封装告诉我们如何正确设计对象的属性和方法
对象代表什么,就得封装对应的数据,并提供数据对应的行为
人画,人关
在这里插入图片描述
谁的行为就设计谁的方法与属性。

封装的好处
●对象代表什么,就得封装对应的数据,并提供数据对应的行为
●降低我们的学习成本,可以少学、少记,或者说压根不用学,不用记对象有哪些方法,有需要时去找就行

在这里插入图片描述
private关键字
●是一个权限修饰符
●可以修饰成员 (成员变量和成员方法)
●被private修饰 的成员只能在本类中才能访问

在这里插入图片描述
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class girlFriend {
private int age;
public void setAge(int a){
if((a>=18)&&(a<=50))
{
age = a;
}else {
System.out.println("错误");
}
}
public int getAge(){
return age;
}
}
运行项目并下载源码java运行1234567891011121314
public class Main {
public static void main(String[] args) {
girlFriend gr = new girlFriend();
gr.setAge(1);
System.out.println(gr.getAge());
}
}
运行项目并下载源码java运行1234567
  1. private关键字 是一一个权限修饰符
  2. 可以修饰成员 (成员变量和成员方法)
  3. 被private修饰 的成员只能在本类中才能访问
  4. 针对private修饰的成 员变量,如果需要被其他类使用,提供相应的操作
  5. 提供“setXxx(参数)”方法,用于给成员变量赋值,方法用public修饰
  6. 提供“getXxx()”方法,用于获取成员变量的值,方法用public修饰

1.3 this关键字

在这里插入图片描述
在这里插入图片描述
就近原则:所以打印局部变量的值。
如何解决呢?
在这里插入图片描述

1
2
3
4
5
6
7
8
9
public class girlFriend {
private int age;
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}

(1)this修饰的变量用于指代成员变量。
    方法的形参如果与成员变量同名,不带this修饰的变量指的是形参,而不是成员变量;
    方法的形参没用与成员变量同名,不带this修饰的变量指的是成员变量。
**(2)this代表所在类的对象引用。**方法被哪个对象调用,this就代表哪个对象。

  1. 封装概述:封装是面向对象三大特征之一(封装、继承、多态),是面向对象编程语言对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界是无法直接操作的。
  2. 封装原则:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问成员变量private,提供对应的getXxx() / setXxx()方法。
  3. 封装优点:通过方法来控制成员变量的操作,提高了代码的安全性。把代码用方法进行封装,提高了代码的复用性。

1.4 构造方法

构造方法也叫作构造器、构造函数。
作用:在创建对象的时候给成员变量进行初始化的。

1
2
3
4
public class 类名{
修饰符 类名(参数){
}
}

在这里插入图片描述

注意事项:
(1)构造方法的创建:如果没有定义构造方法,系统将给出一个默认的无参数构造方法;如果定义了构造方法,系统将不再提供默认的构造方法。
(2)构造方法的重载:如果自定义了带参构造方法,还要使用无参数构造方法,就必须再写一个无参数构造方法。
(3)推荐的使用方式:无论是否使用,都手工书写无参数构造方法。

在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class girlFriend {
private int age;
private String name;
//构造方法
//如呆我们自己没有写任何的构造方法
//那么虚拟机给我们加一个空参构造方法
public girlFriend()
{
System.out.println("无参构造方法");
}

public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
}

写了构造函数之后
带参构造

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
public class girlFriend {
private int age;
private String name;
//构造方法
//如呆我们自己没有写任何的构造方法
//那么虚拟机给我们加一个空参构造方法

public girlFriend(int age,String name)
{
this.age =age;
this.name =name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
}

public class Main {
public static void main(String[] args) {
girlFriend gr = new girlFriend(18,"xx");

System.out.println(gr.getAge());
System.out.println(gr.getName());
}
}

一般有参与无参的都写上,

1.5 标准JavaBean

(1)成员变量:使用private修饰
(2)构造方法:提供一个无参构造方法、提供一个带多个参数的构造方法。
(3)成员方法:提供每一个成员变量对应的setXxx() / getXxx();提供一个显示对象信息的show()。
(4)创建对象并为其成员变量赋值的两种方式:无参构造方法创建对象后使用setXxx()赋值;使用带参构造方法直接创建带有属性值的对象。

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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
public class User {
private String username;
private String passward;
private String email;
private String gender;
private int age;

//空参
public User(){

}
//带全部参数的构造方法
public User(String username,String passward,String email,String gender,int age)
{
this.username = username;
this.passward = passward;
this.email = email;
this.gender = gender;
this.age =age;
}
//get 与 set
public void setUsername(String username){
this.username = username;
}
public String getUsername()
{
return this.username;
}
//快捷键
//alt+insert

}

public class User {
private String username;
private String passward;
private String email;
private String gender;
private int age;
//快捷键
//alt+insert
//alt+Fn+insert

public User(String username, String passward, String email, String gender, int age) {
this.username = username;
this.passward = passward;
this.email = email;
this.gender = gender;
this.age = age;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassward() {
return passward;
}

public void setPassward(String passward) {
this.passward = passward;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getGender() {
return gender;
}

public void setGender(String gender) {
this.gender = gender;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

public class User {
private String username;
private String passward;
private String email;
private String gender;
private int age;

public User() {
}

public User(String username, String passward, String email, String gender, int age) {
this.username = username;
this.passward = passward;
this.email = email;
this.gender = gender;
this.age = age;
}

/**
* 获取
* @return username
*/
public String getUsername() {
return username;
}

/**
* 设置
* @param username
*/
public void setUsername(String username) {
this.username = username;
}

/**
* 获取
* @return passward
*/
public String getPassward() {
return passward;
}

/**
* 设置
* @param passward
*/
public void setPassward(String passward) {
this.passward = passward;
}

/**
* 获取
* @return email
*/
public String getEmail() {
return email;
}

/**
* 设置
* @param email
*/
public void setEmail(String email) {
this.email = email;
}

/**
* 获取
* @return gender
*/
public String getGender() {
return gender;
}

/**
* 设置
* @param gender
*/
public void setGender(String gender) {
this.gender = gender;
}

/**
* 获取
* @return age
*/
public int getAge() {
return age;
}

/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}

public String toString() {
return "User{username = " + username + ", passward = " + passward + ", email = " + email + ", gender = " + gender + ", age = " + age + "}";
}

//插件 PTG 使用魔法、File、Setting、插件、PTG 下载


}

1.6 对象内存图

在这里插入图片描述

当方法被调用的时候,进栈执行

1. 加载class文件
在这里插入图片描述
在这里插入图片描述
2. 申明局部变量
在这里插入图片描述
3. 在堆内存中开辟一个空间
在这里插入图片描述
4. 默认初始化
img
5. 显示初始化
6. 构造方法初始化
7. 将堆内存中的地址值赋值给左边的局部变量
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

1.7 补充知识:成员变量、局部变量区别

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2. 面向对象综合训练

2.1 文字版格斗游戏

格斗游戏,每个游戏角色的姓名,血量,都不相同,在选定人物的时候( new对象的时候),这些信息
就应该被确定下来。

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
import java.util.Random;
public class Main {
public static void main(String[] args) {
User play_1 = new User("C++",100);
User play_2 = new User("Java",101);
while(true)
{
Random a = new Random();
boolean suiji = a.nextBoolean();
if(suiji==false) play_1.attack(play_2);
else play_2.attack(play_1);
if(play_1.getBlood()==0||play_2.getBlood()==0)break;
}
System.out.println("Game Over");
}
}
import java.util.Random;

public class User {
private String name;
private int blood;

public User(String name, int blood) {
this.name = name;
this.blood = blood;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getBlood() {
return blood;
}

public void setBlood(int blood) {
this.blood = blood;
}
//gongji
public void attack(User player)
{
Random r = new Random();
int blood_one = r.nextInt(1,11);
System.out.println(this.name+" 攻击了 "+player.name);
System.out.println(player.name+"掉了 "+blood_one+" 滴血");
if(player.blood>=blood_one) player.blood = player.blood - blood_one;
else player.blood = 0;
if(player.blood==0) System.out.println(player.name+"死了");
else System.out.println(player.name+" 还有 "+player.blood+" 滴血");

}
}

下面是输出内容:

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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
Java 攻击了 C++
C++掉了 7 滴血
C++ 还有 93 滴血
C++ 攻击了 Java
Java掉了 2 滴血
Java 还有 99 滴血
Java 攻击了 C++
C++掉了 7 滴血
C++ 还有 86 滴血
Java 攻击了 C++
C++掉了 2 滴血
C++ 还有 84 滴血
Java 攻击了 C++
C++掉了 5 滴血
C++ 还有 79 滴血
Java 攻击了 C++
C++掉了 6 滴血
C++ 还有 73 滴血
Java 攻击了 C++
C++掉了 7 滴血
C++ 还有 66 滴血
Java 攻击了 C++
C++掉了 2 滴血
C++ 还有 64 滴血
Java 攻击了 C++
C++掉了 4 滴血
C++ 还有 60 滴血
Java 攻击了 C++
C++掉了 3 滴血
C++ 还有 57 滴血
Java 攻击了 C++
C++掉了 3 滴血
C++ 还有 54 滴血
C++ 攻击了 Java
Java掉了 4 滴血
Java 还有 95 滴血
Java 攻击了 C++
C++掉了 5 滴血
C++ 还有 49 滴血
C++ 攻击了 Java
Java掉了 1 滴血
Java 还有 94 滴血
C++ 攻击了 Java
Java掉了 1 滴血
Java 还有 93 滴血
C++ 攻击了 Java
Java掉了 4 滴血
Java 还有 89 滴血
Java 攻击了 C++
C++掉了 8 滴血
C++ 还有 41 滴血
Java 攻击了 C++
C++掉了 3 滴血
C++ 还有 38 滴血
C++ 攻击了 Java
Java掉了 3 滴血
Java 还有 86 滴血
Java 攻击了 C++
C++掉了 7 滴血
C++ 还有 31 滴血
C++ 攻击了 Java
Java掉了 6 滴血
Java 还有 80 滴血
Java 攻击了 C++
C++掉了 8 滴血
C++ 还有 23 滴血
C++ 攻击了 Java
Java掉了 2 滴血
Java 还有 78 滴血
C++ 攻击了 Java
Java掉了 2 滴血
Java 还有 76 滴血
C++ 攻击了 Java
Java掉了 10 滴血
Java 还有 66 滴血
Java 攻击了 C++
C++掉了 2 滴血
C++ 还有 21 滴血
Java 攻击了 C++
C++掉了 5 滴血
C++ 还有 16 滴血
C++ 攻击了 Java
Java掉了 8 滴血
Java 还有 58 滴血
C++ 攻击了 Java
Java掉了 7 滴血
Java 还有 51 滴血
C++ 攻击了 Java
Java掉了 5 滴血
Java 还有 46 滴血
Java 攻击了 C++
C++掉了 9 滴血
C++ 还有 7 滴血
Java 攻击了 C++
C++掉了 2 滴血
C++ 还有 5 滴血
C++ 攻击了 Java
Java掉了 10 滴血
Java 还有 36 滴血
Java 攻击了 C++
C++掉了 8 滴血
C++死了
Game Over

2.2 两个对象数组练习

定义数组存储3个商品对象。
商品的属性:商品的id,名字,价格,库存。
创建三个商品对象,并把商品对象存入到数组当中。

Javabean类:

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
import java.util.Random;

public class User {
private String id;
private String name;
private double price;
private int count;


public User() {
}

public User(String id, String name, double price, int count) {
this.id = id;
this.name = name;
this.price = price;
this.count = count;
}

public String getId() {
return id;
}


public void setId(String id) {
this.id = id;
}


public String getName() {
return name;
}


public void setName(String name) {
this.name = name;
}

public double getPrice() {
return price;
}


public void setPrice(double price) {
this.price = price;
}


public int getCount() {
return count;
}

public void setCount(int count) {
this.count = count;
}

public String toString() {
return "User{id = " + id + ", name = " + name + ", price = " + price + ", count = " + count + "}";
}
}

测试类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Main {
public static void main(String[] args) {
User [] goods = new User[3];
User good1 = new User("1","小憨包",7.99,8);
User good2 = new User("2","九转大肠",21,9);
User good3 = new User("3","飞翔",10,7);
goods[0] = good1;
goods[1] = good2;
goods[2] = good3;
for (int i = 0; i < goods.length; i++) {
System.out.println(goods[i].toString());
}
}
}

输出:

1
2
3
User{id = 1, name = 小憨包, price = 7.99, count = 8}
User{id = 2, name = 九转大肠, price = 21.0, count = 9}
User{id = 3, name = 飞翔, price = 10.0, count = 7}

自己键盘输入——测试类:

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
import org.w3c.dom.ls.LSInput;

import java.util.Random;
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
User [] goods = new User[1];
User good1 = new User("1","小憨包",7.99,8);
goods[0] = good1;

for (int i = 0; i < goods.length; i++) {
System.out.println(goods[i].toString());
}
Scanner a = new Scanner(System.in);
System.out.println("请输入id");
String id = a.next();
good1.setId(id);
System.out.println("请输入name");
String name = a.next();
good1.setName(name);
System.out.println("请输入price");
double price = a.nextDouble();
good1.setPrice(price);
System.out.println("请输入count");
int count = a.nextInt();
good1.setCount(count);

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

}

输出:

1
2
3
4
5
6
7
8
9
10
11
12
13
User{id = 1, name = 小憨包, price = 7.99, count = 8}
请输入id
2
请输入name
老八
请输入price
4.97
请输入count
365
User{id = 2, name = 老八, price = 4.97, count = 365}

Process finished with exit code 0

2.3 对象数组练习——判断统计

定义数组存储4个女朋友的对象
女朋友的属性:姓名、年龄、性别、爱好
要求1:计算出四女朋友的平均年龄
要求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
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import java.util.Random;

public class User {
private String name;
private String hobby;
private double heigth;
private int age;


public User() {
}

public User(String name, String hobby, double heigth, int age) {
this.name = name;
this.hobby = hobby;
this.heigth = heigth;
this.age = age;
}

/**
* 获取
* @return name
*/
public String getName() {
return name;
}

/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}

/**
* 获取
* @return hobby
*/
public String getHobby() {
return hobby;
}

/**
* 设置
* @param hobby
*/
public void setHobby(String hobby) {
this.hobby = hobby;
}

/**
* 获取
* @return heigth
*/
public double getHeigth() {
return heigth;
}

/**
* 设置
* @param heigth
*/
public void setHeigth(double heigth) {
this.heigth = heigth;
}

/**
* 获取
* @return age
*/
public int getAge() {
return age;
}

/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}

public String toString() {
return "User{name = " + name + ", hobby = " + hobby + ", heigth = " + heigth + ", age = " + age + "}";
}
}

import org.w3c.dom.ls.LSInput;

import java.util.Random;
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
User [] girls = new User[3];
User g1 = new User("小红","噶腰子",170.6,40);
User g2 = new User("小蓝","去花钱",130,21);
User g3 = new User("小绿","找老王",200.8,31);
girls[0] = g1;
girls[1] = g2;
girls[2] = g3;
double h = 0;
for (int i = 0; i < girls.length; i++) {
girls[i].toString();
h = h+girls[i].getAge();
}
System.out.println("平均年纪:"+h/(girls.length));

for (int i = 0; i < girls.length; i++)
{
if(girls[i].getAge()>(h/(girls.length)))
{
System.out.println("高:"+girls[i].getName());
}
}
}
}

平均年纪:30.666666666666668
高:小红
高:小绿

3. 字符串

3.1 API

API:应用程序编程接口
在这里插入图片描述
Java API :指的就是JDK中提供的各种功能的Java类
这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用即可。
将来还会学习其他知识,还会有很多的API。
在这里插入图片描述
在这里插入图片描述

帮助文档的使用
JAVA帮助文档:
链接:https://pan.baidu.com/s/17kKejic9P4rG5zcIg5jEtA
提取码:11l0

API使用练习
需求:按照帮助文档的使用步骤学习Scanner 类的使用,并实现键盘录入一个字符串,最后输出在控制台

3.2 String

在这里插入图片描述
在这里插入图片描述

  • String
  • StringBuilder
  • StringJoiner
  • StringBuffer
  • Pattern
  • Matcher

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

3.2.1 创建String对象的两种方式

在这里插入图片描述
代码例子:

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
import org.w3c.dom.ls.LSInput;

import java.util.Random;
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
//1.使用直接赋值的方式获取一个字符串对象
String s1 = "abc";
System. out. println(s1);//abc
//2.使用new的方式来获取一个字符串对象
//空参构造:可以获取一个空白的字符串对象
String s2 = new String( );
System.out.println("@" + s2 + "!");//@!
//传递一个字符串,根据传递的字符串内容再创建一个心得字符串对象
String s3= new String("abcc");
System.out.println(s3);

//传递一个字符数组,根据字符数组的内容再创建一个 新的字符串对象

//需求:我要修改字符串的内容。abc Qbc
//abc --> {'a','b','c'}-->{'Q','b','c'} -->'Qbc'
//传递一个字节数组,根据字节数组的内容再创建一个新的字符串对象

char[] chs = {'a','b','c','d'};
String s4 = new String(chs);
System. out . println(s4);//abcd



//应用场景:以后在网络当中传输的数据其实都是字节信息
//我们一般要把字节信息进行转换,转成字符串

byte[] bytes = {97, 98,99, 100};
String s5 = new String(bytes);
System. out . println(s5);



}
}

直接赋值的方式存在StringTable(串池)中,注意: String’ Table(串池)在JDK7版本开始从方法区中挪到了堆内存
在这里插入图片描述
在工作中,String类是我们使用频率非常高的一种对象类型。JVM为了提升性能和减少内存开销,避免字符串的重复创建,其维护了一块特殊的内存空间,这就是我们今天要讨论的核心,即字符串池(String Pool)。字符串池由String类私有的维护。

我们知道,在Java中有两种创建字符串对象的方式:

  • 采用字面值的方式赋值
  • 采用new关键字新建一个字符串对象。

这两种方式在性能和内存占用方面存在着差别。

方式一:采用字面值的方式赋值,例如:
在这里插入图片描述

采用字面值的方式创建一个字符串时,JVM首先会去字符串池中查找是否存在”aaa”这个对象,如果不存在,则在字符串池中创建”aaa”这个对象,然后将池中”aaa”这个对象的引用地址返回给字符串常量str,这样str会指向池中”aaa”这个字符串对象;如果存在,则不创建任何对象,直接将池中”aaa”这个对象的地址返回,赋给字符串常量。

在本例中,执行:str == str2 ,会得到以下结果:

在这里插入图片描述

这是因为,创建字符串对象str2时,字符串池中已经存在”aaa”这个对象,直接把对象”aaa”的引用地址返回给str2,这样str2指向了池中”aaa”这个对象,也就是说str和str2指向了同一个对象,因此语句System.out.println(str == str2)输出:true。

方式二:采用new关键字新建一个字符串对象,例如:

在这里插入图片描述

采用new关键字新建一个字符串对象时,JVM首先在字符串池中查找有没有”aaa”这个字符串对象,如果有,则不在池中再去创建”aaa”这个对象了,直接在堆中创建一个”aaa”字符串对象,然后将堆中的这个”aaa”对象的地址返回赋给引用str3,这样,str3就指向了堆中创建的这个”aaa”字符串对象;如果没有,则首先在字符串池中创建一个”aaa”字符串对象,然后再在堆中创建一个”aaa”字符串对象,然后将堆中这个”aaa”字符串对象的地址返回赋给str3引用,这样,str3指向了堆中创建的这个”aaa”字符串对象。

在这个例子中,执行:str3 == str4,得到以下结果:

在这里插入图片描述

因为,采用new关键字创建对象时,每次new出来的都是一个新的对象,也即是说引用str3和str4指向的是两个不同的对象,因此语句System.out.println(str3 == str4)输出:false。

字符串池的实现有一个前提条件:
String对象是不可变的。因为这样可以保证多个引用可以同时指向字符串池中的同一个对象。如果字符串是可变的,那么一个引用操作改变了对象的值,对其他引用会有影响,这样显然是不合理的。

字符串池的优缺点:字符串池的优点就是避免了相同内容的字符串的创建,节省了内存,省去了创建相同字符串的时间,同时提升了性能;另一方面,字符串池的缺点就是牺牲了JVM在常量池中遍历对象所需要的时间,不过其时间成本相比而言比较低。

intern方法使用:一个初始为空的字符串池,它由类String独自维护。当调用 intern方法时,如果池已经包含一个等于此String对象的字符串(用equals(oject)方法确定),则返回池中的字符串。否则,将此String对象添加到池中,并返回此String对象的引用。 对于任意两个字符串s和t,当且仅当s.equals(t)为true时,s.intern() == t.intern()才为true。所有字面值字符串和字符串赋值常量表达式都使用 intern方法进行操作。

在这里插入图片描述

输出:
在这里插入图片描述

这个例子说明了6点:

  • 同一个包下同一个类中的字符串常量的引用指向同一个字符串对象;
  • 同一个包下不同的类中的字符串常量的引用指向同一个字符串对象;
  • 不同的包下不同的类中的字符串常量的引用仍然指向同一个字符串对象;
  • 由常量表达式计算出的字符串是在编译时进行计算,然后被当作常量;
  • 在运行时通过连接计算出的字符串是新创建的,因此是不同的;
  • 通过计算生成的字符串显示调用intern方法后产生的结果与原来存在的同样内容的字符串常量是一样的。

3.2.2 Java的常用方法(比较)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
第二种方式是忽略大小写,常用于验证码

1
2
3
4
5
6
7
8
9
10
11
public class Main {
public static void main(String[] args) {

String s1 = "abc";
String s2 = new String("abc");
String s3 = "ABc";
if(s1.equals(s2)) System.out.println("s1==s2");
if(s1.equalsIgnoreCase(s3)) System.out.println("huluedaxiaoxie s1 == s3");

}
}

键盘录入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Main {
public static void main(String[] args) {

Scanner sc = new Scanner(System.in);
System.out.println("请输入abc");
String s1 = sc.next();
String s2 = "abc";
if(s1==s2) System.out.println("s1==s2"); //不相等
if(s1.equals(s2)) System.out.println("s1.equals(s2)");//相等
//结论:
//以后只要想比较字符串的内容,就必须要用String里面的方法

}
}

3.2.3 用户登录案例

需求:已知正确的用户名和密码,请用程序实现模拟用户登录。 总共给三次机会,登录之后,给出相应的提示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import org.w3c.dom.ls.LSInput;

import java.util.Random;
import java.util.Scanner;

public class Main {
public static void main(String[] args) {

//定义已经有的变量记录正确的用户名和密码
String [] right_Username = {"zhangsan","lisi","wangwu"};
String [] right_Password = {"123","456","789"};

//键盘输入
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名");
String input_Username = sc.next();
boolean flag = false;
//判断用户名是否存在
for (int i = 0; i < right_Username.length; i++) {
if(right_Username[i].equals(input_Username)){
System.out.println("用户名存在,请输入相关密码");
flag = true;
break;
}
}
int opp = 3;
if(flag == true)
{
while (opp>0)
{

String input_Password = sc.next();
boolean passwordFlag = false;

for (int i = 0; i < right_Password.length; i++) {
if(right_Password[i].equals(input_Password)){
System.out.println("密码输入正确");
passwordFlag = true;
break;
}
}
if(passwordFlag==false)
{
System.out.println("输入错误");
opp--;
System.out.println("你还有"+opp+"次机会");
}
if (passwordFlag == true)break;
}
}

else {
System.out.println("是否新建用户");

}


}
}

3.2.4 遍历字符串

字符串

  1. public char charAt(int index)根据索引返回字符
  2. 字符串的长度:字符串对象.length()
1
2
3
4
5
6
7
8
9
public class Main {
public static void main(String[] args) {
String s1 = "abcdefg";
for(int i = 0; i < s1.length(); i++){
System.out.println(s1.charAt(i));
}
}
}

数组

  1. 数组的长度:数组名.length
1
2
3
4
5
6
7
8
public class Main {
public static void main(String[] args) {
char[] s1 = new char[]{'a','b','c','d','e','f','g'};
for(int i = 0; i < s1.length; i++){
System.out.println(s1[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
30
31
32
33
34
35
36
37
38
39
40
import org.w3c.dom.ls.LSInput;

import java.util.Random;
import java.util.Scanner;

public class Main {
public static void main(String[] args) {
//1.
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串");
String str = sc.next();
//2.统计---计数器思想
//定义三个计数器
int bigCount = 0;
int smallCount = 0;
int numberCount = 0;
for (int i = 0; i < str.length(); i++) {
//i依次表示字符串中的每一个索引
char c = str.charAt(i) ;
if(c >= 'a' && c <= 'z')
{
//char类型的变量在参与计算的时候自动类型提升为int查询ascii码表
smallCount++;
}
else if(c >= 'A' && c <= 'Z'){
bigCount++;
}
else if(c >='0'&& c <= '9'){
numberCount++;
}

}
//输出
System.out.println("小写字母有: " + smallCount + " 个");
System.out.println("大写字母有: " + bigCount +" 个");
System.out.println("数字字母有: " + numberCount +" 个");


}
}

3.2.5 拼接字符串

定义一个方法,把int数组中的数据按照指定的格式拼接成一一个字符串返回, 调用该方法,并在控制台输出结果。
例如:数组为int[] arr={1,2,3}; 执行方法后的输出结果为: [1,2, 3]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Main {
public static void main(String[] args) {
int [] arr = {1,2,3};
System.out.println(arrToString(arr));
}
public static String arrToString(int[] arr){
if(arr == null){
return "";
}
if(arr.length == 0){
return "[]";
}
String result = "[";
//当代码执行到这里表示什么?
//表示数组不是nu1l,也不是长度为8的
for(int i= 0;i<arr.length;i++){
//i索引arr[i]元素
result = result + arr[i];
if(i!=arr.length-1)result +=", ";
}
result += "]";
return result;
}

}

3.2.6 金额转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.Scanner;

public class Main {
public static void main(String[] args) {

String[] s = {"零","壹","贰","叁","肆","伍","陆","柒","捌","玖"};
String[] n = {"元","拾","佰","仟","万","拾","佰","仟","亿","拾","佰","仟","万"};
Scanner sc = new Scanner(System.in);
System.out.println("请输入要转换的整数金额");
String result = new String();
String input_price = sc.next();
for (int i = 0; i < input_price.length(); i++) {
int num = input_price.charAt(i)-'0';
result += s[num];
result =result+" "+n[input_price.length()-i-1]+" ";
}

System.out.println(result);
//位数在多就报错
//2343453464567
//贰 万 叁 仟 肆 佰 叁 拾 肆 亿 伍 仟 叁 佰 肆 拾 陆 万 肆 仟 伍 佰 陆 拾 柒 元
}

}

3.2.7 手机号屏蔽

●String substring(int beginIndex, int endIndex)截取
注意点:包头不包尾,包左不包右 只有返回值才是截取的小串

●String substring(int beginIndex)截取到末尾

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Main {
public static void main(String[] args) {

//1.获取一个手机号码
String phoneNumber = "13112349468" ;
//2.截取手机号码前面三位
String start = phoneNumber.substring(0, 3);
//3.截取手机号码后面四位
String end = phoneNumber.substring(7);
//4.拼接
String result = start + "****"+ end;
//5.打印
System. out . println(result);

}

3.2.8 身份证号信息查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import org.w3c.dom.ls.LSInput;

import java.util.Random;
import java.util.Scanner;

public class Main {
public static void main(String[] args) {

String id = "321281202001011234";
//2.获取出生年月日
String year = id. substring(6, 10);
String month = id. substring(10,12);
String day = id.substring(12, 14);
System. out. println("人物信息为: ");
System. out . println("出生年月日:"+ year +"年"+ month + "月"+ day +"日");
int gender = id.charAt(16)-'0';
if(gender%2==0) System.out.println("性别:女");
else System.out.println("性别:男");


}

}

3.2.9 敏感词替换

在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
public class Main {
public static void main(String[] args) {

//1.犹取到说的话
String talk = "你玩的真好,以后不要再玩了,TMD";
//2.把里面的敏感词TMD替换为***
String result = talk.replace( "TMD","***");
//3.打印结果
System. out . println(result);
}
}

3.3 StringBuilder

在这里插入图片描述
StringBuilder概述
StringBuilder可以看成是一个容器,创建之后里面的内容是可变的
作用:提高字符串的操作效率

3.3.1 StringBuilder构造方法

在这里插入图片描述

3.3.2 StringBuilder常用方法

![在这里插入图片描述](https://img-blog.csdnimg.cn/4d54e366221041b287177fd19886fc7e.png

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
import java.lang.StringBuilder;
public class Main {
public static void main(String[] args) {
//1.创建对象
StringBuilder sb = new StringBuilder();
//打印
//普及:
//因为StringBuilder是Java已经写好的类
//java在底层对他做了一些特殊处理。
//打印对象不是地址值而是属性值。
System. out .println(sb);

sb.append(2);
sb.append(1.1);
System. out .println(sb);

sb.reverse();
System.out.println(sb);

System.out.println(sb.length());

String s = sb.toString();
System.out.println(s);
}
}

链式编程

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
import java.lang.StringBuilder;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
//链式编程:
//当我们在调用一个方法的时候,不需要用变量接收他的结果,可以继续调用其他方法
int len = getString().substring(1).replace("A", "Q").length();
System.out.println(len);
}

public static String getString() {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串");
String str = sc.next();
return str;


}
}

import java.lang.StringBuilder;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入字符串,判断它是不是对称的");
String str = sc.next();

StringBuilder sb = new StringBuilder(str);
sb.reverse();
String str1 = sb.toString();
if(str1.equals(str))
System.out.println("str == str1");


}
}

import java.lang.StringBuilder;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入字符串,判断它是不是对称的");
String str = sc.next();

String str1 = new StringBuilder().append(str).reverse().toString();
if(str1.equals(str))
System.out.println("str == str1");
}
}

在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import java.lang.StringBuilder;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int [] arr={1,23,4,5,6};
System.out.println(arrToSting(arr));
}
public static String arrToSting(int[] arr)
{
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < arr.length; i++) {
if(i==arr.length-1) sb.append(arr[i]).append("]");
else sb.append(arr[i]).append(",");
}
return sb.toString();
}
}

3.4 StringJoiner

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.4.1 StringBuilder构造方法

在这里插入图片描述
在这里插入图片描述

3.4.2 StringBuilder成员方法

在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
public class Main {
public static void main(String[] args) {
// StringJoiner sj = new StringJoiner("_++_");
// sj.add("aaa").add("xxx").add("www");
// System.out.println(sj.toString());

StringJoiner sj = new StringJoiner("_++_","{","}");
sj.add("aaa").add("xxx").add("www");
System.out.println(sj.toString());
}
}

在这里插入图片描述

3.5 字符串的原理

  1. 扩展底层原理1:字符串存储的内存原理

    1
    2
    直接赋值会复用字符串常量池中的
    new出来不会复用, 而是开辟一个新的空间
  2. 扩展底层原理2:==号比较的到底是什么?

    1
    2
    基本数据类型比较数据值
    引用数据类型比较地址值
  3. 扩展底层原理3:字符串拼接的底层原理
    在这里插入图片描述
    在这里插入图片描述

在这里插入图片描述

结论: 如果很多字符串变量拼接,不要直接+。在底层会创建多个对象,浪费时间,浪费性能。
在这里插入图片描述

字符串原理小结

  1. 扩展底层原理3:字符串拼接的底层原理

    1
    2
    ●如果没有变量参与,都是字符串直接相加,编译之后就是拼接之后的结果,会复用串池中的字符串。
    ●如果有变量参与,每一行拼接的代码,都会在内存中创建新的字符串,浪费内存。
  2. 扩展底层原理4: StringBuilder提 高效率原理图

    1
    ●所有要拼接的内容都会往StringBuilder中放,不会创建很多无用的空间,节约内存

在这里插入图片描述

  • 扩展底层原理5: StringBuilder源码分析

    1
    2
    3
    4
    ●默认创建一个长度为16的字节数组
    ●添加的内容长度小于16, 直接存
    ●添加的内容大于16会扩容(原来的容量*2+2)
    ●如果扩容之后还不够,以实际长度为准

在这里插入图片描述
在这里插入图片描述

3.6 字符串综合练习

3.6.1 罗马数字的两种写法

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
import java.util.Scanner;
import java.util.StringJoiner;

public class Main {
public static void main(String[] args) {
/*键盘录入一个字符串,
要求1:长度为小于等于9
要求2:只能是数字
将内容变成罗马数字
下面是阿拉伯数字跟罗马数字的对比关系:
I -1、II-2、III-3、 IV-4、V-5、VI-6、VII-7、VIII-8、IX-9
注意点:
罗马数字里面是没有e的
如果键盘录入的数字包含0,可以变成""(长度为0的字符串)*/
Scanner sc =new Scanner(System.in);
String [] s_arr = {" ","I","II","III","IV","V","VI","VII","VIII","IX"};
StringBuilder sb = new StringBuilder();
while (true){
System.out.println("请输入长度为小于等于9的数字");
String s = sc.next();
boolean flag = checkStr(s);
if (flag) {

for (int i = 0; i < s.length(); i++) {
sb.append(s_arr[s.charAt(i)-'0']).append(" ");
}
break;
} else {
System.out.println("请重新输入");
continue;
}
}


System.out.println(sb.toString());

}
public static boolean checkStr(String str){//123456
//要求1:长度为小于等于9
if(str.length() > 9){
return false;
}
//要求2:只能是数字
for (int i = 0; i < str.length(); i++) {
char c = str. charAt(i);//0~9
if(c < '0' || c>'9'){
return false;
}
}
//只有当字符串里面所有的字符全都判断完毕了,我才能认为当前的字符串是符合规则
return true ;
}

}

在这里插入图片描述

3.6.2 调整字符串的内容并比较

调整字符串
给定两个字符串, A和B。
A的旋转操作就是将A最左边的字符移动到最右边。
例如,若A= ‘abcde’,在移动一次之后结果就是’bcdea’
如果在若干次调整操作之后,A能变成B,那么返回True。
如果不能匹配成功,则返回false

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
import java.util.Scanner;
import java.util.StringJoiner;

public class Main {
public static void main(String[] args) {
String a = "123456789";
String b = "678912345";
if (a.length()==b.length())
{
for (int i = 0; i < a.length(); i++) {
a = xuanzhuan(a);
if(a.equals(b)) {
System.out.println(a);
System.out.println(b);
System.out.println("可以转换");
break;
}
System.out.println(a);
System.out.println(b);
}

}
else System.out.println("不可以转换");
}
public static String xuanzhuan (String str)
{
if(str.length()>=1)
{
StringBuilder sb = new StringBuilder();
sb.append(str.substring(1)).append(str.substring(0,1));
return sb.toString();
}
else return str;
}

}

4. ArrayList

4.1 集合的基本使用

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.util.Scanner;
import java.util.StringJoiner;
import java.util.ArrayList;

public class Main {
public static void main(String[] args) {
//1.创建集合的对象
//泛型:限定集合中存储数据的类型

//ArrayList<String> list = new ArrayList<String>();
//JDK7
ArrayList<String> list = new ArrayList<>();
//此时我们创建的是ArrayList的对象,而ArrayList是java已经写好的一一个类
//这个类在底层做了一些处理
//打印对象不是地址值,而是集合中存储数据内容
//在展示的时候会拿[]把所有的数据进行包装

System.out.println(list);//[]
}
}

4.1.1 集合的成员方法

在这里插入图片描述

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
import java.util.Scanner;
import java.util.StringJoiner;
import java.util.ArrayList;

public class Main {
public static void main(String[] args) {

ArrayList<String> list = new ArrayList<>();
System.out.println("这是空的时候:"+'\t'+list);//

list.add("123");
list.add("124");
list.add(1,"134");
System.out.println("这是在1索引添加134:"+'\t'+list);//

list.add("2");
list.add("3");
list.add("3");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
list.add("7");
list.add("8");
System.out.println("添加好多:"+'\t'+list);//

list.remove(3);
System.out.println("remove索引3:"+'\t'+list);
list.remove("3");
System.out.println("remove '3':"+'\t'+list);
list.set(1,"asdasfsd");
System.out.println("set 1索引:"+'\t'+list);
System.out.println(list.get(2));
System.out.println(list.size());

// 这是空的时候: []
// 这是在1索引添加134: [123, 134, 124]
// 添加好多: [123, 134, 124, 2, 3, 3, 3, 4, 5, 6, 7, 8]
// remove索引3: [123, 134, 124, 3, 3, 3, 4, 5, 6, 7, 8]
// remove '3': [123, 134, 124, 3, 3, 4, 5, 6, 7, 8]
// set 1索引: [123, asdasfsd, 124, 3, 3, 4, 5, 6, 7, 8]
// 124
// 10

}


}

4.1.2 集合的遍历方式

需求:定义一个集合,添加字符串,并进行遍历 遍历格式参照: [元素1, 元素2,元素3]。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import java.util.Scanner;
import java.util.StringJoiner;
import java.util.ArrayList;

public class Main {
public static void main(String[] args) {

ArrayList<String> list = new ArrayList<>();

list.add("123");
list.add("124");
list.add(1, "134");

System.out.print("[");
for (int i = 0; i < list.size(); i++) {
if (i == list.size() - 1) {
System.out.print(list.get(i));
} else {
System.out.print(list.get(i) + ",");
}


}
System.out.println("]");
}

}
import java.util.Scanner;
import java.util.StringJoiner;
import java.util.ArrayList;

public class Main {
public static void main(String[] args) {

ArrayList<String> list = new ArrayList<>();

list.add("123");
list.add("124");
list.add(1, "134");

StringJoiner sj = new StringJoiner(",","[","]");
for (int i = 0; i < list.size(); i++) {
sj.add(list.get(i));

}
System.out.println(sj.toString());

}

}

4.1.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
import java.util.Scanner;
import java.util.StringJoiner;
import java.util.ArrayList;

public class Main {
public static void main(String[] args) {

ArrayList<Integer> list = new ArrayList<>();

//jdk5以后int Integer之间是可以互相转化的
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);

System.out.print("[");
for (int i = 0; i < list.size(); i++) {
if (i == list.size() - 1) {
System.out.print(list.get(i));
} else {
System.out.print(list.get(i) + ",");
}
}
System.out.println("]");
}
}

4.1.4 综合练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Scanner;
import java.util.StringJoiner;
import java.util.ArrayList;

public class Main {
public static void main(String[] args) {

ArrayList<User> stu = new ArrayList<>();
User stu1 = new User("zhangsan",17);
User stu2 = new User("lisi",15);
User stu3 = new User("wangwu",12);
stu.add(stu1);
stu.add(stu2);
stu.add(stu3);

for (int i = 0; i < stu.size(); i++) {
System.out.println("姓名:"+stu.get(i).getName()+'\t'+"年龄:"+stu.get(i).getAge());
}

}

}

4.1.5 学生管理系统

Student.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
47
48
49
50
51
52
53
54
55
56
package studentManager;
/*
学生类
*/
public class Student {
//学号
private String sid;
//姓名
private String name;
//年龄
private String age;
//居住地
private String address;

//构造函数
public Student(){}
public Student(String sid, String name, String age, String address){
this.sid = sid;
this.name = name;
this.age = age;
this.address = address;
}

//Alt + insert 可以快速生成这些东西
public String getSid() {
return sid;
}

public void setSid(String sid) {
this.sid = sid;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getAge() {
return age;
}

public void setAge(String age) {
this.age = age;
}

public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}
}

StudentManager.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
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
package studentManager;

import java.util.ArrayList;
import java.util.Scanner;

public class StudentManager {
public static void main(String[] args) {
//创建集合对象,用于存储学生数据
ArrayList<Student> array = new ArrayList<Student>();

while(true) {
//用输出语句完成主界面
System.out.println("------欢迎来到学生管理系统------");
System.out.println("1.添加学生");
System.out.println("2.删除学生");
System.out.println("3.修改学生");
System.out.println("4.查看所有学生");
System.out.println("5.退出");
System.out.println("请输入你的选择:");

//用Scanner录入信息
Scanner sc = new Scanner(System.in);
String line = sc.nextLine();

//用Switch语句完成选择
switch(line){
case "1":
//System.out.println("添加学生");
addStudent(array);
break;
case "2":
//System.out.println("删除学生");
delectStudent(array);
break;
case "3":
//System.out.println("修改学生");
updateStudent(array);
break;
case "4":
//System.out.println("查看所有学生");
findAllStudent(array);
break;
case "5":
System.out.println("谢谢使用");
//break;
System.exit(0); //JVM退出,即Java虚拟机退出
}
}
}

//添加学生信息
public static void addStudent(ArrayList<Student> array){
Scanner sc = new Scanner(System.in);
String sid; //这里需要全局
while(true) {
System.out.println("请输入学生学号:");
sid = sc.nextLine();

boolean flag = isUsed(array, sid);
if (flag) {
System.out.println("你输入的学号已经被使用!请重新输入:");
}else{
break;
}
}

System.out.println("请输入学生姓名:");
String name = sc.nextLine();
System.out.println("请输入学生年龄:");
String age = sc.nextLine();
System.out.println("请输入学生居住地:");
String address = sc.nextLine();

//创建学生对象
Student s = new Student();
s.setSid(sid);
s.setName(name);
s.setAge(age);
s.setAddress(address);

//添加到学生集合中
array.add(s);

//
System.out.println("添加学生成功!");
}
//判断学号是否被使用
public static boolean isUsed(ArrayList<Student> array, String sid){
boolean flag = false;
for(int i=0; i<array.size(); i++){
Student s = array.get(i);
if(s.getSid().equals(sid)){
flag = true;
break;
}
}
return flag;
}
//查看学生信息
public static void findAllStudent(ArrayList<Student> array){
//判断集合中是否有数据
if(array.size()==0){
System.out.println("无信息,请先添加信息再查询!");
return;
}

//显示表头信息
// \t:tab键的意思
System.out.println("学号\t姓名\t年龄\t\t居住地");

//显示
for (int i=0; i< array.size(); i++){
Student s = array.get(i);
System.out.println(s.getSid() + "\t" + s.getName() + "\t" + s.getAge() + "岁\t" + s.getAddress());
}
}
//删除学生信息
public static void delectStudent(ArrayList<Student> array){
Scanner sc = new Scanner(System.in);

System.out.println("请输入你要删除的学生的学号:");
String sid = sc.nextLine();

int index = -1;

//遍历
for(int i=0; i< array.size(); i++){
Student s = array.get(i);
if (s.getSid().equals(sid)){
index = i;
array.remove(i);
break;
}
}
if (index==-1){
System.out.println("该信息不存在!");
}
else{
System.out.println("删除学生成功!");
}
}
//修改学生信息
public static void updateStudent(ArrayList<Student> array){
Scanner sc = new Scanner(System.in);

System.out.println("请输入你要修改的学生的学号:");
String sid = sc.nextLine();

//键盘录入要修改的学生信息
System.out.println("请输入学生新姓名:");
String name = sc.nextLine();
System.out.println("请输入学生新年龄:");
String age = sc.nextLine();
System.out.println("请输入学生新居住地:");
String address = sc.nextLine();

Student s = new Student();
s.setSid(sid);
s.setName(name);
s.setName(age);
s.setAddress(address);

//遍历信息,进行修改
for(int i=0; i< array.size(); i++){
Student student = array.get(i);
if(student.getSid().equals(sid)){
array.set(i,s);
break;
}
}

//提示修改成功
System.out.println("修改信息成功!");
}
}

5. 面向对象进阶

5.1 static

5.1.1 静态成员变量

在这里插入图片描述

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
import java.util.Random;

public class User {
private String name;
private int age;

public static String teacher;

public User() {
}

public User(String name, int age) {
this.name = name;
this.age = age;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}


import java.util.Scanner;
import java.util.StringJoiner;
import java.util.ArrayList;

public class Main {
public static void main(String[] args) {

User u1 = new User();
u1.setName("a");
u1.setAge(1);
u1.teacher = "aaa";
User u2 = new User();
u2.setName("a");
u2.setAge(1);
u2.teacher = "bbb";
System.out.println(u1.teacher);
System.out.println(u2.teacher);

}

}

static表示静态,是Java中的一个修饰符,可以修饰成员方法,成员变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Main {
public static void main(String[] args) {

User u1 = new User();
u1.setName("a");
u1.setAge(1);
User.teacher = "ccc";
User u2 = new User();
u2.setName("a");
u2.setAge(1);

System.out.println(u1.teacher);
System.out.println(u2.teacher);
}

}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

5.1.2 静态成员方法

在这里插入图片描述

5.1.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
import java.util.StringJoiner;

public class ArrayUtil {
private ArrayUtil(){}
public static String printArr(int[] arr)
{
StringJoiner sj = new StringJoiner(",","[","]");
for (int i = 0; i < arr.length; i++) {
sj = sj.add(Integer.toString(arr[i]));
}
return sj.toString();
}
public static double getAerage(int[] arr)
{
int score = 0;
for (int i = 0; i < arr.length; i++) {
score +=arr[i];
}
return (score*1.0)/arr.length;
}
}

public class Main {
public static void main(String[] args) {

int [] arr = {99,75,98,21,45};
System.out.println(ArrayUtil.printArr(arr));
System.out.println(ArrayUtil.getAerage(arr));


}

}

在这里插入图片描述
只要没有对象,非静态就没有办法调用
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

5.2 继承

在这里插入图片描述

5.2.1 什么是继承?继承的好处

在这里插入图片描述
在这里插入图片描述
什么时候用继承?

当类与类之间,存在相同(共性)的内容,并满足子类是父类中的一种,就可以考虑使用继承,来优化代码

在这里插入图片描述

1
子类可以得到父类的属性和行为,子类可以使用。

5.2.2 继承的特点

继承的特点

  1. Java只支持单继承
  2. 不支持多继承
  3. 支持多层继承

每一个类都直接或者间接的继承于Object

Animal.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
package com.itheima;

public class Animal {
private String name;

public Animal() {
}

public Animal(String name) {
this.name = name;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public void eat(){
System.out.println("我在吃东西");
}
}

Cat.java

1
2
3
4
5
6
7
8
9
package com.itheima;

public class Cat extends Animal {
public void zhualaoshu()
{
System.out.println("我在抓老鼠");
}

}

test.java

1
2
3
4
5
6
7
8
9
10
11
package com.itheima;

public class Test {
public static void main(String[] args) {
Cat li = new Cat();
li.setName("aa");
li.eat();
li.zhualaoshu();

}
}

5.2.3 子类到底能继承父类中的哪些内容? (内存图/内存分析工具)

构造方法
在这里插入图片描述

在这里插入图片描述
成员变量
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
成员方法
在这里插入图片描述
在这里插入图片描述

5.2.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
package com.itheima;

public class Test {
public static void main(String[] args) {
Zi z = new Zi();
z.zishow();
}
}
class Fu
{
String name = "Fu";
}
class Zi extends Fu{
String name = "Zi";
public void zishow(){
String name = "ZiShow";
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
}

ZiShow
Zi
Fu

在这里插入图片描述

5.2.5 继承中:成员方法的访问特点

通过子类对象访问一个方法,顺序如下:

子类成员范围找
父类成员范围找
如果都没用就报错(不考虑父亲的父亲…)

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 Demo5;

public class Fu {
public void show() {
System.out.println("Fu中的show方法被调用");
}
}

package Demo5;

public class Zi extends Fu {
public void method() {
System.out.println("Zi中的method方法被调用");
}
public void show() {
super.show();
System.out.println("Zi中的show方法被调用");
} //就近原则
}

package Demo5;

public class Demo {
public static void main(String[] args) {
//创建对象,调用方法
Zi z = new Zi();
z.method();
z.show();
}
}

在这里插入图片描述

5.2.6 继承中:构造方法的特点

在这里插入图片描述
在这里插入图片描述
为什么?

●子类在初始化的时候,有可能会使用到父类中的数据,如果父类没有完成初始化,子类将无法使用父类的数据。
●子类初始化之前,
一定要调用父类构造方法先完成父类数据空间的初始化。

怎么调用父类构造方法的?

●子类构造方法的第一行语句默认都是: super(),不写也存在,且必须在第一行。
●如果想调用父类有参构造, 必须手动写super进行调用。

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

1.继承中构造方法的访问特点是什么?
●子类不能继承父类的构造方法,但是可以通过super调用

●子类构造方法的第一行, 有一个默认的super();

●默认先访问父类中无参的构造方法,再执行自己。

●如果想要方法文父类有参构造,必须手动书写。

5.2.7 重写

当父类的方法不能满足子类现在的需求时,需要进行方法重写

书写格式
在继承体系中,子类出现了和父类中一-模一样的方法声明,我们就称子类这个方法是重写的方法。

在这里插入图片描述
在这里插入图片描述

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 com.itheima;

public class Test {
public static void main(String[] args) {
Zi z = new Zi();
z.zishow();
}
}
abstract class Fu
{
String name = "Fu";
public void fushow(){
String name = "FuShow";
}

public abstract void zishow();
}
class Zi extends Fu{
String name = "Zi";
@Override
public void zishow(){
String name = "ZiShow";
System.out.println(name);
System.out.println(this.name);
System.out.println(super.name);
}
}

方法重写注意事项和要求

  1. 重写方法的名称、形参列表必须与父类中的一致。
  2. 子类重写父类方法时,访问权限子类必须大于等于父类(暂时了解 :空着不写< protected < public)
  3. 子类重写父类方法时,返回值类型子类必须小于等于父类
  4. 建议:重写的方法尽量和父类保持一致。
  5. 私有方法不能被重写。
  6. 子类不能重写父类的静态方法,如果重写会报错的。
  7. 只有被添加到虚方法表中的方法才能被重写
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
package com.itheima;

public class Dog {
public void eat()
{
System.out.println("吃gongliang");
}
public void drink()
{
System.out.println("喝水");
}
public void kanjia()
{
System.out.println("我在看家");
}
}
package com.itheima;

public class Hashiqi extends Dog{
@Override
public void eat() {
System.out.println("吃rou");
}
public void caijia()
{
System.out.println("我在拆家");
}
}

package com.itheima;

public class Test {
public static void main(String[] args) {
Hashiqi hh = new Hashiqi();
hh.caijia();
hh.eat();
}
}

5.2.8 this与super

在这里插入图片描述
在这里插入图片描述
Test.java

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

public class Test {
public static void main(String[] args) {
Manager m = new Manager("001","张三",8000.99,700);
Cook c = new Cook("002","李四",2000.99);
System.out.println("Manger:"+m.getId()+" "+m.getName()+" "+m.getWage()+" "+m.getBouns());
m.work();
m.eat();
System.out.println("Cook:"+c.getId()+" "+c.getName()+" "+c.getWage());
c.work();
c.eat();
}
}

Employee.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
package jiCheng;

public class Employee {
private String id;
private String name;
private double wage;

public Employee() {
}

public Employee(String id, String name, double wage) {
this.id = id;
this.name = name;
this.wage = wage;
}

public String getId() {
return id;
}

public void setId(String id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public double getWage() {
return wage;
}

public void setWage(double wage) {
this.wage = wage;
}
public void work(){
System.out.println("员工正在工作");
}
public void eat(){
System.out.println("员工正在炫饭");
}
}

Manger.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
package jiCheng;

public class Manager extends Employee{
private double bouns;

public Manager() {
}

public Manager(String id, String name, double wage, double bouns) {
super(id, name, wage);
this.bouns = bouns;
}

public double getBouns() {
return bouns;
}

public void setBouns(double bouns) {
this.bouns = bouns;
}

@Override
public void work(){
System.out.println("管理");
}
}

Cook.java

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

public class Cook extends Employee{
public Cook() {
}

public Cook(String id, String name, double wage) {
super(id, name, wage);
}
@Override
public void work(){
System.out.println("正在炒菜");
}
}