4.1继承

1.头:日期、所学内容出处

黑马程序员Python教程_600集Python从入门到精通教程(懂中文就能学会)_哔哩哔哩_bilibili

2.今天所学内容摘要**

继承

image-20220401151957747

image-20220401152052168

image-20220401152120684

image-20220401152132497

理解继承代码

Creature ------- person---------Student

1
2
3
4
5
6
7
package day13.java2;

public class Creature {
public void breath(){
System.out.println("gggggggg");
}
}
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 day13.java2;

public class Person extends Creature {
String name;
private int age;
public Person(){

}

public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void eat(){
System.out.println("要吃饭");
}
public void sleep(){
System.out.println("要睡觉");
}

public void setAge(int age) {
this.age = age;
}
public int getAge(){
return age;
}
}
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 day13.java2;

public class Student extends Person{
String major;

public Student() {

}

public Student(String name, int age, String major) {
this.name = name;
this.setAge(age);
this.major = major;
}
// public void eat(){
// System.out.println("要吃饭");
// }
// public void sleep(){
// System.out.println("要睡觉");
// }
public void study(){
System.out.println("要学习");
}
}

测试

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

public class ExtendsTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.setAge(28);
p1.name = "汪大东";
p1.eat();

Student student = new Student();
student.setAge(18);
System.out.println(student.getAge());
student.name = "金宝三";
student.major = "电工";
student.eat();
student.study();

student.breath();
Creature creature = new Creature();

}
}

继承圆和圆柱

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

public class Circle {
private double radius;
public Circle(){
this.radius = 1.0;
}

public double getRadius() {
return radius;
}

public void setRadius(double radius) {
this.radius = radius;
}
public double findArea(){
return Math.PI * radius*radius;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package day13.java4;

public class Cylinder extends Circle{
private double length;

public Cylinder() {
this.length =1.0;
}

public double getLength() {
return length;
}

public void setLength(double length) {
this.length = length;
}
public double findVolume(){
//调用 父类的方法
return findArea()*length;
}

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

public class CylinderTest {
public static void main(String[] args) {
Cylinder cylinder = new Cylinder();
cylinder.setRadius(2.1);
cylinder.setLength(3.4);
double volume = cylinder.findVolume();
System.out.println("半径是:" + cylinder.getRadius());
System.out.println("圆柱的体积是:" + String.format("%.2f",volume));
double area = cylinder.findArea();
System.out.println("圆柱的底面积是:" + String.format("%.2f",area));
}
}

重写

返回值是父类的子类 子类的权限要大于父类

重写就是将父类的方法,同名同参数的修改

image-20220401164551789

image-20220401164911699

重写练习题

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 day13.java5;


public class Person {
String name;
private int age;
public Person(){

}

public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void eat(){
System.out.println("要吃饭");
}
public void walk(int distance){
System.out.println("走路走了" + distance +"公里");
}

public void setAge(int age) {
this.age = age;
}
public int getAge(){
return age;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package day13.java5;

public class Student extends Person {
String major;
public Student() {

}
public Student(String major) {
this.major = major;
}
public void majors(){
System.out.println("专业是" + major);
}
public void eat(){
System.out.println("学生吃饭10分钟");
}

}

测试

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

public class KidsTest {
public static void main(String[] args) {
Kids someKid = new Kids(13);
someKid.printAge();
//设置属性
someKid.setSalary(0);
someKid.setSex(1);

someKid.employed();
someKid.manOrWoman();
}
}

四种访问权限

private和public 常用

image-20220401182416540

3、遇到的问题描述(可以附上截图)+解决⽅案**

Person是我student的父类,调用方法时候,说没找到,看了一会,发现extends后面的Person的java2里面的不是一个包,名字一样。 Student在java5里面 父类Person 在java里,写继承的时候,import是java2中的perso。

img

img

**4.扩展学习部分

总结

今天学习了方法的重写,了解了方法的重写和重构的区别,还有继承,基本和python中一模一样,学起来也相对简单,今天只有下午的学习时间,没有去做项目,做了下练习,把昨天的项目二巩固了一下,学习状态不错,晚自习自己试着敲了一下项目二。今天的学习状态满意了。

4.2super 多态

1.头:日期、所学内容出处

黑马程序员Python教程_600集Python从入门到精通教程(懂中文就能学会)_哔哩哔哩_bilibili

2.今天所学内容摘要**

super的使用

重写父类的方法

重写父类的变量

在子类的构造方法中

super和this差不多,this指该类 super是父类

image-20220401193102413

image-20220402085200335

super练习

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 day14.superTest;

public class Person {
String name;
int age;
int id = 411024; // 身份证
public Person(){
System.out.println("Person我还是在的");
}

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

public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void eat(){
System.out.println("人要吃饭");
}
public void walk(){
System.out.println("人走路");
}
}

子类

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 day14.superTest;


public class Student extends Person {
String major;
int id = 1002; //学号
// 默认调用了父类空参的构造器
public Student(){

}

public Student(String major) {
this.major = major;
}

public Student(String name, int age, String major, int id) {
super(name, age);
this.major = major;
this.id = id;
}

@Override
public void eat() {
System.out.println("学生要吃营养餐");
}

public void study(){
super.eat();
System.out.println("学生学习知识");
}
public void show(){
System.out.println("name = " + this.name + " age = " + age + " id = " + super.id);
System.out.println("name = " + this.name + " age = " + age + " id = " + id);
System.out.println("name = " + this.name + " age = " + age + " id = " + this.id);
}

}

测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package day14.superTest;

public class superTest {
public static void main(String[] args) {
Student student = new Student("物联网");
student.name = "汪大东";
student.show();

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

student.study();
student.eat();
System.out.println("****************************************");
Student student1 = new Student("汪大东",28,"终极一班",3);
student1.show();
}
}

image-20220402105403954

多态

编译看左边,运行看右边

image-20220402105122306

image-20220402110826354

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

public class Man extends Person{
boolean isSmoking;
public void earnMoney(){
System.out.println("男人负责养家");
}
public void eat(){
System.out.println("男人吃得多");
}
public void walk(){
System.out.println("人走路 霸气侧漏");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
package day14.java2;

public class Person {
String name;
int age;

public void eat(){
System.out.println("人吃饭");
}
public void walk(){
System.out.println("人走路");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
package day14.java2;

public class Women extends Person{
boolean isBeauty;
public void goShopping(){
System.out.println("女人喜欢购物");

public void eat(){
System.out.println("女人吃得少减肥");
}
public void walk(){
System.out.println("女人走路拽");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package day14.java2;

public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.eat();
Man man = new Man();
man.eat();
man.age = 25;
man.earnMoney();
//***************************
//对象的多态性: 父类的引用指向子类的对象
System.out.println("****************");
Person p2 = new Man();
//多态的使用:当调用子父类同名同参数的方法时,实际执行的是子类重写的方法 -- 虚拟方法调用
p2.eat();
p2.walk();
// p2.earnMoney(); 子类和父类的方法都有才可以调用
}
}

3、遇到的问题描述(可以附上截图)+解决⽅案**

**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
28
29
30
package day14;

import java.util.Scanner;

/**
* @author: CC
* @date: 2022/4/2 20:29
* @description:
*/
public class subject {
// 题目:求1+2!+3!+…+20!的和
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int cc = input.nextInt();
int sum =0;
for (int i = 1; i <= cc;i++){
long Sum = factorialSum(i);
sum += Sum;
}
System.out.println(sum);
}
//判断阶乘
public static long factorialSum(int num){
if (num == 1){
return 1;
}
return factorialSum(num-1)*num;
}

}

总结

今天学习了多态和super的方法的使用等,理解了java面向对象继承的基本方法,今天学了一下午,主要是需要理解方法的使用和调用和概念才是重要的,代码比较简单,敲的出来,也理解。今天学习状态不错。

4.6 向下转型 和多态性

1.头:日期、所学内容出处

黑马程序员Python教程_600集Python从入门到精通教程(懂中文就能学会)_哔哩哔哩_bilibili

2.今天所学内容摘要**

向下转型和instanceof的使用

向下转型的理解

CSDN:

https://blog.csdn.net/weixin_28680865/article/details/114051478?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164984614616782184649911%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164984614616782184649911&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-4-114051478.142

image-20220405190044531

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 day14.java2;

public class PersonTest {
public static void main(String[] args) {
Person p1 = new Person();
p1.eat();
Man man = new Man();
man.eat();
man.age = 25;
man.earnMoney();
//***************************
//对象的多态性: 父类的引用指向子类的对象
System.out.println("****************");
Person p2 = new Man();
//多态的使用:当调用子父类同名同参数的方法时,实际执行的是子类重写的方法 -- 虚拟方法调用
p2.eat();
p2.walk();
p2.name = "Tom";
// p2.earnMoney(); 子类和父类的方法都有才可以调用
//向下转型:强制类型转换
//如何才能调用子类特有的属性和方法
Man m1 = (Man)p2;
m1.earnMoney();
m1.age = 18;
m1.isSmoking = true;
m1.show();

//使用强转时候,可能出现ClassCastException的异常
// Women w1 = (Women) p2;
// w1.goShopping();
/*
instanceof关键字的使用

a instanceof A 判断对象a是否是类A的实例。如果是,返回true 如果不是 返回false。

*/
if (p2 instanceof Women){
Women w1 = (Women) p2;
w1.goShopping();
System.out.println("Women");
}
if (p2 instanceof Man){
Man w2 = (Man) p2;
w2.earnMoney();
System.out.println("Man");
}
}
}

向下转型的问题

image-20220405191149668

调用方法和属性练习

image-20220405191939912

image-20220405192040386

object

image-20220405195318555

回顾==的使用

image-20220406180659487

equals的使用

使用需要重写

image-20220406183243142

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 day15.equal;

public class MyDateTest {
public static void main(String[] args) {
MyDate myDate1 = new MyDate(14,3,1976);
MyDate myDate2 = new MyDate(14,3,1976);
if (myDate1.equals(myDate2)){
System.out.println("myDate1 is equal to myDate2");
}else{
System.out.println("myDate1 is not equal to myDate2");
}
if (myDate1 == myDate2){
System.out.println("myDate1 == myDate2");
}else{
System.out.println("myDate1 != myDate2");
}
}
}


class MyDate{
private int day;
private int month;
private int year;
public MyDate(){

}
public MyDate(int day, int month, int year) {
this.day = day;
this.month = month;
this.year = year;
}

public boolean equals(Object o){
if (this == o) {
return true;
}
if (o instanceof MyDate){
MyDate myDate = (MyDate) o;
return this.day == myDate.day && this.month == myDate.month && this.year == myDate.year;
}
return 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
37
package day15.equal;

import day15.equal.Customer;

public class EqualsTest {
public static void main(String[] args) {
int i = 10;
int j = 10;
double d = 10.0;
System.out.println(i == j);
System.out.println(j == d);
char c = 10;
System.out.println(i == c);
char c1 = 'A';
char c2 = 65;
System.out.println(c1 == c2);
String c3 = new String("ada");
System.out.println(c3);


//引用类型
Customer customer1 = new Customer("Tom",21);
Customer customer2 = new Customer("Tom",21);
System.out.println(customer1 == customer2);
String cust1 = new String("ada");
String cust2 = new String("ada");
System.out.println(cust1== cust2);

System.out.println("************************");
System.out.println(customer1.equals(customer2)); //false------true
System.out.println(cust1.equals(cust2)); // 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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package day15.equal;

import java.util.Objects;

public class Customer {
private String name;
private int age;
public Customer(){

}

public Customer(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;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Customer customer = (Customer) o;
return age == customer.age && Objects.equals(name, customer.name);
}

@Override
public int hashCode() {
return Objects.hash(name, age);
}
}

tostring

使用时候也会重写

IDEA会自动帮你重写,父类Object 的toString 出来的是所有的属性

image-20220406193139785

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 day15.Test;
public class GeometricObject {
protected String color;
protected double weight;
protected GeometricObject(){
this.color = "white";
this.weight = 1.0;
}

public GeometricObject(String color, double weight) {
this.color = color;
this.weight = weight;
}

public String getColor() {
return color;
}

public void setColor(String color) {
this.color = color;
}

public double getWeight() {
return weight;
}

public void setWeight(double weight) {
this.weight = weight;
}
}
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
package day15.Test;

import day14.java2.Man;

import java.util.Objects;

public class Circle extends GeometricObject{
private double radius;
public Circle(){
super();
this.radius = 1.0;
}

public Circle(double radius) {
this.radius = radius;
}

public Circle(double radius,String color,double weight ) {
super(color, weight);
this.radius = radius;
}

public double getRadius() {
return radius;
}

public void setRadius(double radius) {
this.radius = radius;
}
public double findArea(){
return Math.PI * radius *radius;
}
public boolean equals(Object obj){
if (obj == this){
return true;
}

if (obj instanceof Circle){
Circle circle = (Circle) obj;
return circle.findArea() == this.findArea();
}
return false;
}

@Override
public String toString() {
return "圆的面积:" + findArea();
}
}

Test

1
2
3
4
5
6
7
8
9
10
11
12
13
package day15.Test;

public class CircleTest {
public static void main(String[] args) {
Circle circle1 = new Circle(2.3);
Circle circle2 = new Circle(2.3, "white",2.0);
System.out.println("颜色是否相等 :" + circle1.getColor().equals(circle2.getColor()));

System.out.println("面积是否相等: " + circle1.equals(circle2));
System.out.println(circle1);
System.out.println(circle2.toString());
}
}

3、遇到的问题描述(可以附上截图)+解决⽅案**

暂无

**4.扩展学习部分

final finally finalize 的区别

  • final用于声明属性,方法和类,分别表示属性不可交变,方法不可覆盖,类不可继承。
  • finally是异常处理语句结构的一部分,表示总是执行。
  • finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,供垃圾收集时的其他资源回收,例如关闭文件等。

final:java中的关键字,修饰符。
A).如果一个类被声明为final,就意味着它不能再派生出新的子类,不能作为父类被继承。因此,一个类不能同时被声明为abstract抽象类的和final的类。
B).如果将变量或者方法声明为final,可以保证它们在使用中不被改变.
  1)被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。
  2)被声明final的方法只能使用,不能重载。
finally:java的一种异常处理机制。

finally是对Java异常处理模型的最佳补充。finally结构使代码总会执行,而不管无异常发生。使用finally可以维护对象的内部状态,并可以清理非内存资源。特别是在关闭数据库连接这方面,如果程序员把数据库连接的close()方法放到finally中,就会大大降低程序出错的几率。

finalize:Java中的一个方法名。
Java技术使用finalize()方法在垃圾收集器将对象从内存中清除出去前,做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没被引用时对这个对象调用的。它是在Object类中定义的,因此所的类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其他清理工作。finalize()方法是在垃圾收集器删除对象之前对这个对象调用的。

总结

今天学习学习难度一般,学习难点在多态的练习和向下转型,重写equals和toString方法比较容易。今天只掌握了80%,学习步骤:先看视频,向下转型是有点难度的,又去看了博客,敲了几遍代码,再去理解。今天只学了晚自习,所以今天敲了7个代码左右吧。学习状态良好,晚自习安静,静的下心来打代码。

4.7单元测试 包装类

1.头:日期、所学内容出处

黑马程序员Python教程_600集Python从入门到精通教程(懂中文就能学会)_哔哩哔哩_bilibili

2.今天所学内容摘要**

单元测试

@Test方便自己的测试,不需要再创建一个main测试方法

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

import org.junit.Test;
public class JUnitTest {
int num = 10;
@Test
public void textEquals(){
System.out.println("AAAA");
System.out.println(num);
}
}

基本数据类型转换为包装类

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

import org.junit.Test;

/**
* @ClassName
* WrapperTest
* @Description TODO
* @Author CC
* @DATE 2022/4/7 19:06
* @Version 1.0
*/

public class WrapperTest {
@Test
public void test1(){
int num = 10;
// System.out.println(num.toString());
Integer integer = new Integer(num);
System.out.println(integer.toString());

Integer integer2 = new Integer("123");
System.out.println(integer2.toString());

// Integer integer3 = new Integer("132abc");
// System.out.println(integer3.toString());

Float f1 = new Float(12.3f);
Float f2 = new Float("12.3f");
System.out.println(f1);
System.out.println(f2);


}
}

自动装箱自动拆箱

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

import org.junit.Test;

/**
* @ClassName
* WrapperTest
* @Description TODO
* @Author CC
* @DATE 2022/4/7 19:06
* @Version 1.0
*/

public class WrapperTest {
//基本数据 -----包装类
@Test
public void test1(){
int num = 10;
// System.out.println(num.toString());
Integer integer = new Integer(num);
System.out.println(integer.toString());

Integer integer2 = new Integer("123");
System.out.println(integer2.toString());

// Integer integer3 = new Integer("132abc");
// System.out.println(integer3.toString());

Float f1 = new Float(12.3f);
Float f2 = new Float("12.3f");
System.out.println(f1);
System.out.println(f2);

Boolean b1 = new Boolean(true);
Boolean b2 = new Boolean("true");
Boolean b3 = new Boolean("true123");//false 不报错
System.out.println(b1);
System.out.println(b2);
System.out.println(b3);

System.out.println("***************");
Order order = new Order();
System.out.println(order.isFemale);
System.out.println(order.isMale);
}
//包装类 -------- 基本数据类型
@Test
public void text2(){
Integer in1 = new Integer(123);
int i1 = in1.intValue();
System.out.println(i1 + 85);
}
@Test
public void text3(){
// int num1 = 30;
// method(num1);

//自动装箱
int num2 = 10;
Integer in2 = num2;
boolean b1 = true;
Boolean b2 = b1;


//拆箱
System.out.println(in2.toString());
int num3 = in2;
}

public void method(Object obj){
System.out.println(obj);
}
}
class Order {
boolean isMale;
Boolean isFemale;
}

基本类和包装类对String转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//基本类型和引用类型转换为String
@Test
public void text4(){

int num1 = 10;
//方式一连接运算
String str1 = num1 + "";
System.out.println(str1);
//方式二 调用String的valueOf
float f1 = 12.3f;
String str2 = String.valueOf(f1);
System.out.println(str2);

Double d1 = 12.4;
String str3 = String.valueOf(d1);
System.out.println(str3);
}

3、遇到的问题描述(可以附上截图)+解决⽅案**

转什么类型里面要是什么结构的,Integer 里面要是数字才可以转换。我""里面是一个字符型.

img

**4.扩展学习部分

image-20220407195309108

总结

今天只学了一个晚自习的时间学习难点在包装类之前的转换写法,后面发现有自动的方法 就简单理解很多,会使用了单元测试 就不用每次写一个main的主程序去测试代码了,很方便。今天掌握了90%,学习步骤:先看视频,,敲了几遍代码,再去理解。今天敲了5个代码左右吧,基本类型 包装类 String转换都会了。今天的学习任务比较轻松。

4.8面向对象下

1.头:日期、所学内容出处

黑马程序员Python教程_600集Python从入门到精通教程(懂中文就能学会)_哔哩哔哩_bilibili

2.今天所学内容摘要**

静态static

静态 类.方法调用方法

image-20220408150319709

image-20220408150303257

image-20220408155345136

静态属性和静态方法的基本使用

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
public class staticTest {
public static void main(String[] args) {
Chinese.nation = "中国人";

Chinese chinese1 = new Chinese();
chinese1.name = "汪大东";
chinese1.age = 28;

Chinese chinese2 = new Chinese();
chinese2.name = "金宝三";
chinese2.age = 34;

Chinese chinese3 = new Chinese();
chinese3.name = "林丹";
chinese3.age = 32;

Chinese.show();

}

}
class Chinese{
String name;
int age;
static String nation;
public void eat(){
System.out.println("我要吃饭");
}
public static void show(){
System.out.println("我是一个中国人!");
//不能调用非静态结构
// eat();
// name = "Tom";
System.out.println(Chinese.nation);
walk();
System.out.println("nation : "+ nation);
}
public static void walk(){
System.out.println("走路");
}
public void info(){
System.out.println("name = " + name + " age = " + age);
}
}

静态的使用场景

image-20220408160045147

练习

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

/**
* @ClassName circleTest
* @Description TODO
* @Author CC
* @DATE 2022/4/8 16:09
* @Version 1.0
*/

public class circleTest {
public static void main(String[] args) {
Circle c1 = new Circle();
Circle c2 = new Circle();
Circle c3 = new Circle(2.0);
System.out.println("c1 的 id 是 " + c1.getId());
System.out.println("c2 的 id 是 " + c2.getId());
System.out.println("c3 的 id 是 " + c3.getId());
System.out.println("c3 的面积是 : " +c3.findArea());
System.out.println("创建圆的个数" + Circle.getTotal());
}
}
class Circle{
private double radius;
private int id;
public Circle(){
id = ++init;
total++;
}

public Circle(double radius) {
this();
this.radius = radius;
}

private static int total; //记录圆的个数
private static int init = 1000; //static声明的属性被所有对象共有

public String findArea(){
return String.format("%.2f",Math.PI * radius * radius);
}

public int getId() {
return id;
}

public static int getTotal() {
return total;
}
}

静态练习

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
public class AccountTest {
public static void main(String[] args) {
Account account1 = new Account();
Account account2 = new Account("qwerty",2000);
account2.setBalance(500);
account2.setBalance(0.1);
Account.setInterestRate(0.035);
account2.setId(1119);
account2.setPassword("sjh0802");
System.out.println(account1);
System.out.println(account2);
System.out.println(account2.show());

}
}
class Account{
private int id; //账号
private String password = "000000"; //密码
private double balance; //账户余额

private static double interestRate; //利率
public static double minMoney = 1.0; // 最小余额
public static int init = 1001; // 自动生成id
public String show(){
return "账户 : "+ getId() + " 账户余额 : "+ getBalance() + " 利率 : " + getInterestRate();
}
public Account(){
this.id = init++;
}
public Account(String password,int balance){
this();
this.password = password;
this.balance = balance;
}

public int getId() {
return id;
}

public double getBalance() {
return balance;
}

public static double getInterestRate() {
return interestRate;
}

public void setId(int id) {
this.id = id;
System.out.println("修改账户为" + id);
}

public void setPassword(String password) {
this.password = password;
System.out.println("修改密码");

}

public static void setInterestRate(double interestRate) {
Account.interestRate = interestRate;
}

public void setBalance(double balance) {
if (balance >= minMoney) {
this.balance += balance;
System.out.println("存钱成功");
}
else {
System.out.println("最小余额是: "+ minMoney + "---------请重新输入!");
}
}

@Override
public String toString() {
return "Account{" +
"id=" + id +
", password='" + password + '\'' +
", balance=" + balance +
'}';
}
}

类变量 静态变量内存解析

静态属性共用,对象修改会变

image-20220408151153196

3、遇到的问题描述(可以附上截图)+解决⽅案**

暂无

**4.扩展学习部分

成绩计算

Vector变化数组使用 包装类

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
public class ScoreTest {
public static void main(String[] args) {
//最大值
int maxNum = 0;
//1.实例化Scanner 键盘获取成绩
Scanner scanner = new Scanner(System.in);

//2.实例化Vector对象 相当于长度可变的数组 Vector v = new vector();
Vector<Integer> v = new Vector<>();

//3.循环的方式 给Vector中添加数据
while (true) {
System.out.println("请输入学生的成绩 (负数结束)");
int score = scanner.nextInt();
if (score < 0) {
System.out.println("结束输入.............");
break;
}
//3.2当输入负数跳出循环
else if (score > 100) {
System.out.println("输入数据非法重新输入");
} else {
//3.1添加操作 v.addElement(Object obj)
v.addElement(score);
//4.获取成绩最大值
if (score >= maxNum) {
maxNum = score;
}
}
}
//5.遍历Vector 得到每个学生的成绩,并与最大成绩比较,得到每个学生的等级。
for (int i = 0;i < v.size();i++){
Object object = v.elementAt(i);
int score1 = (int) object;
String level;
if (maxNum-10 <= score1){
level = "A";
}else if (maxNum-20 <= score1){
level = "B";
}else if (maxNum-30 <= score1){
level = "C";
}else {
level = "D";
}
System.out.println("Student " + (i+1) + " score is " + score1 + ", level : " + level);
}
}
}

总结

今天主要是开始了面向对象下的内容,学习了静态。今天是学的一下午的时间,将所有静态的知识看完了,还是蛮容易理解的,静态变量内存搞懂,静态这方面就没什么问题了,学习状态还不错。

4.10单例设计模式

1.头:日期、所学内容出处

黑马程序员Python教程_600集Python从入门到精通教程(懂中文就能学会)_哔哩哔哩_bilibili

2.今天所学内容摘要**

单例设计模式

image-20220409110845965

优点

image-20220409120534141

懒汉式VS饿汉式

image-20220409120157206

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class SingletonTest {
public static void main(String[] args) {
Bank bank1 = Bank.getInstance();
Bank bank2 = Bank.getInstance();
System.out.println(bank1 == bank2);
}
}
//饿汉式
class Bank{
//1.私有化构造器
private Bank(){

}
//2.创建类的对象
//要求此对象也必须是静态的
private static Bank instance = new Bank();

//3.提供公共的方法,返回类的对象
public static Bank getInstance(){
return instance;
}
}

懒汉式

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 SingletonTest2 {
public static void main(String[] args) {
Order order1 = Order.getInstance();
Order order2 = Order.getInstance();
System.out.println(order1 == order2);
}
}
class Order {
//1.私有化类的构造器
private Order(){

}
//声明当前类的对象 没有初始化
private static Order instance = null;

//声明 返回当前类的方法
public static Order getInstance(){
if (instance == null){
instance = new Order();
}
return instance;
}
}

代码块

“不太常用”

image-20220409130209685

代码块优先级高

先于构造器

由父及子,静态先行

image-20220409133905281

属性赋值

image-20220409134328636

final方法

比较简单

被final修饰的类不可以被继承;
被final修饰的方法不可以被重写;
被final修饰的变量不可以改变,是常量

image-20220410192243094

abstract抽象类的使用

自己理解的抽象类 修饰类和方法和结构

但是不能实例化,所以需要子类继承它,然后子类必须要重写父类抽象类的方法,否则就会报错。

image-20220410193622984

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
public class AbstractTest {
public static void main(String[] args) {
Student student1 = new Student();
Student student2 = new Student("王小明",28);
}
}
abstract class Creature{
public abstract void breath();
}

abstract class Person extends Creature{
String name;
int age;
public Person(){

}

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

}
public void eat(){
System.out.println("吃饭");
}

public void walk(){
System.out.println("走路");
}
public abstract void hello();
}

class Student extends Person{
public Student(){

}

public Student(String name, int age) {
super(name, age);
}
public void eat(){
System.out.println("学生要吃有营养的");
}

@Override
public void hello() {
System.out.println("你好啊");
}

@Override
public void breath() {
System.out.println("学生应该呼吸新鲜空气");
}
}

多态的应用:抽象类

image-20220410230723936

3、遇到的问题描述(可以附上截图)+解决⽅案**

暂无

**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
public class PayrollSystem {
public static void main(String[] args) {
//方式一
// Scanner input = new Scanner(System.in);
// System.out.println("请输入当前月份: ");
// int month2 = input.nextInt();

//方式二 输入月份
Calendar calendar = Calendar.getInstance();
int month = calendar.get(Calendar.MONTH);
System.out.println("这个月是"+(month+1) +"月");
Employee[] employees = new Employee[3];
employees[0] = new SalariedEmployee("汪大东",1001,new MyDate(1991,8,2),10000);
employees[1] = new HourlyEmployee("金宝三",1002,new MyDate(1988,11,19),24,240);
employees[2] = new HourlyEmployee("辜战",1003,new MyDate(2002,4,22),30,240);
for (Employee employee : employees) {
System.out.println(employee);
double money = employee.earning();
//month+1才是当月
if ((month + 1) == employee.getBirthday().getMonth()) {
System.out.println(employee.getName()+"生日快乐! 奖励100元");
money += 100;
}
System.out.println("工资是" + money);
}
}
}

运行结果

image-20220411090537334

总结

周天早上在图书馆学习的,晚自习在工作室,今天学习的内容比较多,单例 代码块 final abstract这些java的使用,学习状态不错,边看视频,边敲代码,对于代码块和final不太常用的东西,敲两边理解了就过了,重要的都敲了6 7 遍的代码,实践出真章,在abstract中在最后一个比较大的练习,才理解真正的用法,和适用场景,真的就是编程学习是在敲代码中成长的。

4.11结构 成员内部

1.头:日期、所学内容出处

黑马程序员Python教程_600集Python从入门到精通教程(懂中文就能学会)_哔哩哔哩_bilibili

2.今天所学内容摘要**

接口

image-20220411094009819

image-20220411093858342

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
public class InterfaceTest {
public static void main(String[] args) {
System.out.println(Flyable.MAX_SPEED);
System.out.println(Flyable.min_speed);
// min_speed += 2; //静态
}
}
interface Flyable{
//全局常量
//接口默认全局常量 static final
public static final int MAX_SPEED = 7900; //第一宇宙速度
int min_speed = 1;

public abstract void fly();
//省略了 public abstract
void stop();

//接口不能定义构造器 接口不可以实例化
// public Flyable(){
// }
}
interface attackAble{
void attack();
}

class plane implements Flyable{

public plane() {
}

@Override
public void fly() {
System.out.println("飞机起飞");
System.out.println(MAX_SPEED);
}

@Override
public void stop() {
System.out.println("驾驶员减速停机");
System.out.println(min_speed);
}
}
abstract class boeing implements Flyable{
@Override
public void fly() {
System.out.println("波音747飞的快");
}

}

class Bullet extends plane implements CC,Flyable,attackAble{

@Override
public void fly() {

}

@Override
public void stop() {

}

@Override
public void attack() {

}

@Override
public void method1() {

}

@Override
public void method2() {

}
}
// ***************************************
interface AA{
void method1();

}
interface BB{
void method2();

}
interface CC extends AA,BB{

}

接口的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
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
public class USBTest {
public static void main(String[] args) {
computer computer = new computer();
//1.创建了非匿名实现类的非匿名对象
Flash flash = new Flash();
computer.transferData(flash);
System.out.println();
System.out.println("******************");
//2.创建了非匿名实现类的匿名对象
computer.transferData(new Flash());
System.out.println();
System.out.println("******************");
//3.创建了匿名实现类的非匿名对象
USB phone = new USB() {
@Override
public void start() {
System.out.println("手机工作");
}

@Override
public void stop() {
System.out.println("手机结束工作");
}
};
computer.transferData(phone);
System.out.println();
System.out.println("******************");
//4.创建了匿名实现类的匿名对象
computer.transferData(new USB(){
@Override
public void start() {
System.out.println("mp3工作");
}

@Override
public void stop() {
System.out.println("mp3结束工作");
}
});
}
}
class computer{
public void transferData(USB usb){
usb.start();
System.out.println("传输中--------------");
usb.stop();
}
}
interface USB{
//常量:定义了长宽最大最小的传输速度等

void start();
void stop();
}
class Flash implements USB{

@Override
public void start() {
System.out.println("U盘开始工作");
}
@Override
public void stop() {
System.out.println("U盘结束工作");
}
}
class Printer implements USB{
@Override
public void start() {
System.out.println("打印机开始工作");
}
@Override
public void stop() {
System.out.println("打印机停止工作");
}
}

运行结果
image-20220413192220484

接口练习

比较对象大小

1
2
3
4
5
package day18.java4;

public interface CompareObject {
int compareTo(Object o); //若返回值是0 代表相等 若正数 代表当前对象大 负数代表当前对象小
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class comparableCircleTest {
public static void main(String[] args) {
comparableCircle comparableCircle1 = new comparableCircle(1.9);
comparableCircle comparableCircle2 = new comparableCircle(8.2);
comparableCircle comparableCircle3 = new comparableCircle(8.2);
int num = comparableCircle1.compareTo(comparableCircle2);
if (num == 0){
System.out.println("一样大");
}else if (num > 0){
System.out.println("前面大");
}else
System.out.println("后面大");
//******************************
int num1 = comparableCircle3.compareTo(comparableCircle2);
if (num1 == 0){
System.out.println("一样大");
}else if (num1 > 0){
System.out.println("前面大");
}else
System.out.println("后面大");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class comparableCircle extends Circle implements CompareObject{
public comparableCircle() {
}

public comparableCircle(double radius) {
super(radius);
}

@Override
public int compareTo(Object o) {
if (this == o){
return 0;
}
if (o instanceof comparableCircle){
comparableCircle obj = (comparableCircle) o;
return Double.compare(this.getRadius(), obj.getRadius());
}else {
return 12138;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Circle {
private double radius;
public Circle(){}

public Circle(double radius) {
this.radius = radius;
}

public double getRadius() {
return radius;
}

public void setRadius(double radius) {
this.radius = radius;
}
}

java8.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
35
36
37
38
39
40
41
42
43
44
package day18.java4;

/**
* @ClassName SubClassTest
* @Description TODO
* @Author CC
* @DATE 2022/4/11 18:59
* @Version 1.0
*/

public class SubClassTest {
public static void main(String[] args) {
SubClass s = new SubClass();
// s.method1();
//1.接口的静态方法 只能接口来调用
CompareA.method1();
//通过实现类的对象可以调用接口中的默认方法
//2.如果实现类重写了接口中的默认方法,调用时,任然钓鱼用的是重写以后的方法。
s.method2();
// 3.如果子类或实现类继承的父类和实现的接口中声明了同名同参数的方法
//那么子类在没有重写此方法的情况下,默认调用的是父类中的同名同参数的方法 -->类优先原则
// 4.如果实习类实现了多个接口 而这多个接口中定义了同名同参数的默认方法
//如果实现了没有重写此方法的情况下,报错--接口冲突
// 我们必须在实现类重写此方法

s.method3();
}
}
class SubClass extends SuperClass implements CompareA,CompareB{
public void method2(){
System.out.println("subclass 上海");
}
public void method3(){
System.out.println("subclass 深圳");
}
//5.在子类中调用接口中重写过的方法
public void myMethod(){
method3(); //调用自己的方法
super.method3();//调用父类的方法
//调用接口中的默认方法
CompareA.super.method3();
CompareB.super.method3();
}
}

内部类

image-20220411195232603

3、遇到的问题描述(可以附上截图)+解决⽅案**

暂无

**4.扩展学习部分

static final abstract总结

static 通过对象调用静态方法

一句话概述:final修饰的东西不能被修改,不能被继承。

一句话概述:抽象类的目的就是为了让其子类实现它本身的方法!

抽象的使用前提 : 继承性

https://blog.csdn.net/xieyunc/article/details/102643543?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164972197816780271911803%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164972197816780271911803&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-102643543.142

总结

今天学习了一个上午的时间,将java面对象的最后一些内容-----接口 通关了,知道了接口的使用,并做了几个小练习,还是比较容易理解的,java中的接口主要是弥补java只有单继承的局限性的,还是很适用的,今天的学习状态不错,学的内容也很充实。

4.12 异常处理

1.头:日期、所学内容出处

黑马程序员Python教程_600集Python从入门到精通教程(懂中文就能学会)_哔哩哔哩_bilibili

2.今天所学内容摘要**

异常

Exception比较重要

image-20220412085726084

常见的异常

image-20220412091454828

常见的异常

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
public class ExceptionTest {
//编译时报错

@Test
public void test7(){
// File file = new File("hello.txt");
// FileInputStream fileInputStream = new FileInputStream(file);
// int data = fileInputStream.read();
// while (data != -1){
// System.out.println((char) data);
// data = fileInputStream.read();
// }
// fileInputStream.close();
}
//**************************
//下面是运行时报错
//ArithmeticException
@Test
public void test6(){
int a = 10;
int b = 0;
System.out.println(a/b);
}

//InputMismatchException 输入不匹配
@Test
public void test5(){
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
System.out.println(num);
}

//NullPointerException
@Test
public void test4(){

String str = "123s";
Integer.parseInt(str);
}

//ClassCastException
@Test
public void test3(){
Object obj = new Date();
String str = (String) obj;
}

//ArrayIndexOutOfBoundsException
@Test
public void test2(){
int[] arr = new int[3];
System.out.println(arr[3]);
}

//NullPointerException
@Test
public void test1(){
int[] arr = null;
System.out.println(arr[3]);
}
}

异常的处理

分为抓和抛

image-20220412100852150

try - catch - finally的使用

注意:编译时候异常 try就是改成运行时异常

image-20220412101029282

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
public class ExceptionTest1 {
@Test
public void test2(){
try {
File file = new File("hello.txt");
FileInputStream fileInputStream = new FileInputStream(file);
int data = fileInputStream.read();
while (data != -1) {
System.out.println((char) data);
data = fileInputStream.read();
}
fileInputStream.close();
} catch (IOException e){
e.printStackTrace();
}
}
@Test
public void test1(){

String str = "123s";
int num = 0;
try {
num = Integer.parseInt(str);
}catch (NumberFormatException e){
System.out.println("出现数值转换异常了 不要着急.....");
System.out.println(e.getMessage());
// e.printStackTrace();
}catch (NullPointerException e){
System.out.println("出现空指针异常了 不要着急.......");
}catch (Exception e){
System.out.println("出现异常了");
}
finally {
System.out.println("finally哪里都U我");
}
System.out.println(num);


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

}

}
说明

image-20220412104234672

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class FinallyTest3 {
public static void main(String[] args) {
FileInputStream fileInputStream = null;
try {
File file = new File("D:\\CC\\IDEA\\src\\day19\\java2\\hello.txt");
fileInputStream = new FileInputStream(file);
int data = fileInputStream.read();
while (data != -1) {
System.out.print((char) data);
data = fileInputStream.read();
}
} catch (IOException e){
e.printStackTrace();
}finally {
try {
if (fileInputStream != null){
fileInputStream.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}

体会

image-20220412132923317

throws

image-20220412135620351

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
package day19.java3;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

public class ExceptionTest2 {
public static void main(String[] args) {
try {
method2();
}catch (FileNotFoundException e){
e.getCause();
}catch (IOException e){
e.printStackTrace();
}
}
public static void method3(){
try {
method2();
} catch (IOException e) {
e.printStackTrace();
}
}

public static void method2() throws IOException {
method1();
}


public static void method1() throws FileNotFoundException,IOException {
File file = new File("hello1.txt");
FileInputStream fileInputStream = new FileInputStream(file);
int data = fileInputStream.read();
while (data != -1) {
System.out.print((char) data);
data = fileInputStream.read();
}
fileInputStream.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
29
30
31
32
33
34
35
package day19.java3;

public class StudentTest {
public static void main(String[] args) {
Student student = new Student();
try {
student.regist(-1001);
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println(student);
}
}
class Student{
private int id;

public Student() {

}

public void regist(int id) throws Exception {
if (id > 1000){
this.id = id;
}else {
throw new Exception("您输入的数据非法啦(要大于1000)" );
}
}

@Override
public String toString() {
return "Student{" +
"id=" + id +
'}';
}
}

运行结果

image-20220412143804563

3、遇到的问题描述(可以附上截图)+解决⽅案**

创建了文件,但是还是一直报错,改了很多次还是报错,在main里面也试过也报错
上csdn有人说要绝对路径 就加上了 "D:\CC\IDEA\src\day19\java2\hello"运行才成功
后面又尝试将txt直接放到IDEA下面也成功了,应该是src里面的文件是需要写绝对路径的,放IDEA写相对路径就OK

img

img

image-20220412133133116

综合练习

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
package day19.java4;

import java.util.InputMismatchException;
import java.util.Scanner;
public class EcmDef {
public static void main(String[] args) {
try {
// Scanner input = new Scanner(System.in);
// int i = input.nextInt();
// int j = input.nextInt();
int i = Integer.parseInt(args[0]);
int j = Integer.parseInt(args[1]);
int num = ecm(i,j);
System.out.println(num);
}catch (NumberFormatException e){
System.out.println("类型不一致");
}catch (ArrayIndexOutOfBoundsException e){
System.out.println("缺少命令行参数");
}catch (ArithmeticException e){
System.out.println("不能输入非0数");
}catch (EcDef e) {
System.out.println(e.getMessage());
}
}
public static int ecm(int i , int j) throws EcDef {
if (i < 0 || j < 0){
throw new EcDef("您输入的值有负数");
}
return i / j;
}


public static class EcDef extends Exception {
public EcDef() {
}

public EcDef(String message) {
super(message);
}
}
}

**4.扩展学习部分

IDEA给main中args赋值

image-20220412153500828

https://blog.csdn.net/Ye_mulin/article/details/104561301?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164974865416782094898594%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164974865416782094898594&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-3-104561301.142

自动处理异常

ALT + enter

文件打印

应该是通过ascii码打印的

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.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class FinallyTest3 {
public static void main(String[] args) {
FileInputStream fileInputStream = null;
try {
File file = new File("D:\\CC\\IDEA\\src\\day19\\java2\\hello.txt");
fileInputStream = new FileInputStream(file);
int data = fileInputStream.read();
while (data != -1) {
System.out.print((char) data);
data = fileInputStream.read();
}
} catch (IOException e){
e.printStackTrace();
}finally {
try {
if (fileInputStream != null){
fileInputStream.close();
}
}catch (IOException e){
e.printStackTrace();
}
}
}
}

方法重写的规则

子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型

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 day19.java3;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;

/**
* @ClassName OverrideTest
* @Description TODO
* @Author CC
* @DATE 2022/4/12 14:10
* @Version 1.0
*/

public class OverrideTest {
public static void main(String[] args) {
OverrideTest overrideTest = new OverrideTest();
overrideTest.display(new SubClass());
}

public void display(SuperClass s){
try {
s.method();
} catch (IOException e) {
e.printStackTrace();
}
}

}
class SuperClass{
public void method() throws IOException{

}
}
class SubClass extends SuperClass{
public void method() throws FileNotFoundException{

}
}

总结

根据视频的进度马上到java高级了,所以今天有干劲,把异常学习完了,基础部分也结束了,先复习了这段时间的学习内容,结束了java的面向对象,看博客理解关键字的区别和适用场景等,然后再进入异常的学习,多敲代码,异常好理解,代码熟练就好了,python中也有异常处理的方法,学java的时候也是顺水推舟,比较容易理解,今天也彻底明白了为什么java是面向对象的语言,所有的都逃不开面向对象,看源代码都是面向对象,继承什么的,今天学习状态不错,代码敲的比较多。

4.13 对接口和抽象类的理解

1.头:日期、所学内容出处

黑马程序员Python教程_600集Python从入门到精通教程(懂中文就能学会)_哔哩哔哩_bilibili

2.今天所学内容摘要**

抽象类(abstract )

子类继承必须要重写该方法

1、定义抽象类和抽象方法使用的关键字是“abstract"

2、抽象类被叫做一个不完整的类因为它有自己的构造方法,但是却不能直接实例化对象,他的抽象方法没有方法体。

3、如果子类不是一个抽象类那么必须覆写父类的所有抽象方法

接口(interface

从这个两个网站加入自己的理解

https://blog.csdn.net/wei_zhi/article/details/52738471

https://blog.csdn.net/sun_shine56/article/details/86621481?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164984761616782248510008%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164984761616782248510008&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-86621481.142

有时必须从几个类中派生出一个子类,继承它们所有的属性和方法。但是,Java不支持多重继承。有了接口,就可以得到多重继承的效果。

接口是抽象方法 和常量值的定义的集合。

从本质上讲,接口只包含常量和方法的定义,而没有变量和方法的实现。

由于接口里面存在抽象方法,所以接口对象不能直接使用关键字new进行实例化。接口的使用原则如下:
(1)接口必须要有子类,但此时一个子类可以使用implements关键字实现多个接口;
(2)接口的子类(如果不是抽象类),那么必须要覆写接口中的全部抽象方法;
(3)接口的对象可以利用子类对象的向上转型进行实例化。

在Java中,一个抽象类只能继承一个抽象类,但一个接口却可以使用extends关键字同时继承多个接口(但接口不能继承抽象类)。

范例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
interface A{
public void funA();
}
interface B{
public void funB();
}
//C接口同时继承了A和B两个接口
interface C extends A,B{//使用的是extends
public void funC();
}
class X implements C{
@Override
public void funA() {
}
@Override
public void funB() {
}
@Override
public void funC() {
}

}

由此可见,从继承关系来说接口的限制比抽象类少:
(1)一个抽象类只能继承一个抽象父类,而接口可以继承多个接口;
(2)一个子类只能继承一个抽象类,却可以实现多个接口(在Java中,接口的主要功能是解决单继承局限问题)

接口的特点:

1.用 interface 来定义。

2.接口中的所有成员变量都默认是由public static final修饰的。

3.接口中的所有方法都默认是由public abstract修饰的。

4.接口没有构造方法。构造方法用于创建对象

5.实现接口的类中必须提供接口中所有方法的具体实现内容。

6.多个无关的类可以实现同一个接口

7.一个类可以实现多个无关的接口

8.与继承关系类似,接口与实现类之间存在多态性

9.接口也可以继承另一个接口,使用extends关键字。

10.实现接口的类中必须提供接口中所有方法的具体实现内容。

11.多个无关的类可以实现同一个接口

12.一个类可以实现多个无关的接口

13.与继承关系类似,接口与实现类之间存在多态性

3、遇到的问题描述(可以附上截图)+解决⽅案**

暂无

**4.扩展学习部分

抽象类和接口的异同

image-20220413192337165

面试题:

1、抽象类中可以没有抽象方法吗?

答:可以的

2、如抽象类没有抽象方法,那么可以直接实例化对象吗?

答:不可以,因为没有抽象方法它依然是-一个抽象类

3、抽象类的方法必须被子类覆写吗?

答:不一定,如果子类是一个普通类则必须全部覆写,如果子类是一个抽象类则不强制要求全部覆写父类的抽象方法。

5、抽象类中的抽象方法的abstract关键字可以被省略吗?

答:不可以(但是在后面的接口中可以省略)

总结

今天只学了晚自习,这星期学习的内容量有点大,所以想自己抽个空把内容梳理一下,今天把比较容易搞混的,抽象类和接口这两个比较难理解和以后比较常用的两个重点复习了一下,结合博客和自己的理解,将内容梳理了一下,然后看了一下项目三的软件架构和实例演示,今天主要是当这段时间的缓冲,明天把项目三完成,进入java的第二阶段。

4.15 对接口和抽象类的理解

1.头:日期、所学内容出处

黑马程序员Python教程_600集Python从入门到精通教程(懂中文就能学会)_哔哩哔哩_bilibili

2.今天所学内容摘要**

做了项目三的基本类

image-20220418093242079

3、遇到的问题描述(可以附上截图)+解决⽅案**

暂无

**4.扩展学习部分

image-20220418093329135

动物类

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

public class Test {
public static void main(String[] args) {
Cat cat = new Cat("橘黄色",3);
cat.Myself();
Dog dog = new Dog("黑色",5);
dog.Myself();

}

}
abstract class Animal{
private final String hair;
private final int age;

public Animal(String hair, int age) {
this.hair = hair;
this.age = age;
}

public String getHair() {
return hair;
}

public int getAge() {
return age;
}

//自我介绍
abstract void Myself();

}
class Cat extends Animal{


public Cat(String hair, int age) {
super(hair, age);
}

@Override
void Myself() {
System.out.println("我是猫,我的毛发是" + getHair() + " 我今年" + getAge()+ "岁");
}
}

class Dog extends Animal{


public Dog(String hair, int age) {
super(hair, age);
}

@Override
void Myself() {
System.out.println("我是狗,我的毛发是" + getHair() + " 我今年" + getAge() + "岁");
}
}

形状

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

import java.util.Scanner;
public class Test1 {
public static void main(String[] args) {
System.out.println("1:球型 2:正方形 3.长方形 4.圆柱形");
Scanner input = new Scanner(System.in);
while (true) {
System.out.println("请输入你要计算的图形类型:");
int count = input.nextInt();
if (count == 1) {
//创建一个球类
Sphere sphere = new Sphere();
sphere.input();
System.out.println(sphere.display());
} else if (count == 2) {
//创建一个正方体
Square square = new Square();
square.input();
System.out.println(square.display());
} else if (count == 3) {
//创建一个长方体
Cuboid cuboid = new Cuboid();
cuboid.input();
System.out.println(cuboid.display());
} else if (count == 4) {
//创建一个圆柱体
Circle circle = new Circle();
circle.input();
System.out.println(circle.display());
} else {
System.out.println("输入错误,重新输入");

}
}
}
}
//形状抽象类
abstract class shape{
abstract void input();
abstract String display();
abstract double area();
abstract double volume();
}
//球类
class Sphere extends shape{
private double radius;

@Override
void input() {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入球的半径");
radius = scanner.nextDouble();
}

@Override
String display() {
return "球形" + "的表面积是:" + area() + ",体积是:" + volume();
}

@Override
double area() {
return 4*Math.PI*radius*radius;

}

@Override
double volume() {
return 4*Math.PI*radius*radius*radius/3;
}
}

//正方类
class Square extends shape{
private double sideLength;

@Override
void input() {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入正方形的边长");
sideLength = scanner.nextDouble();

}

@Override
String display() {
return "正方形"+ "的表面积是:" + area() + ",体积是:" + volume();
}

@Override
double area() {
return sideLength*sideLength * 6;

}

@Override
double volume() {
return area()*sideLength;
}
}
//长方体类
class Cuboid extends shape{
private double width; //宽
private double length; //长度
private double highly; //高度


@Override
void input() {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入长方形的长度");
length = scanner.nextDouble();
System.out.print("请输入长方形的宽度");
width = scanner.nextDouble();
System.out.print("请输入长方形的高度");
highly = scanner.nextDouble();

}

@Override
String display() {
return "长方形"+ "的表面积是:" + area() + ",体积是:" + volume();
}

@Override
double area() {
return length*width *2 + length * highly*2 + highly * width * 2;
}

@Override
double volume() {
return length * width * highly;
}
}
//圆柱类
class Circle extends shape{
private double radius;
private double highly;

@Override
void input() {
Scanner scanner = new Scanner(System.in);
System.out.print("请输入圆柱的半径");
radius = scanner.nextDouble();
System.out.print("请输入圆柱的高度");
highly = scanner.nextDouble();


}

@Override
String display() {
return "圆柱体"+ "的表面积是:" + area() + ",体积是:" + volume();
}

@Override
double area() {
return 2*Math.PI*radius*radius + 2 * Math.PI * radius * highly;

}

@Override
double volume() {
return Math.PI *radius *radius *highly;
}
}

运行结果

image-20220418095222014

车类

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

/**
* @ClassName Test3
* @Description TODO
* @Author CC
* @DATE 2022/4/15 17:13
* @Version 1.0
*/

public class Test3 {
public static void main(String[] args) {
Car car = new Car("奔驰","黑色",4,5000,5);
car.run();
car.showCar();
Truck truck = new Truck("本田","红色",8,300000,200000);
truck.run();
truck.showTruck();


}
}
class Vehicles{
private String brand; // 商标
private String color; // 颜色
private int wheelsNum; // 轮子个数
private double wheelsWight; // 轮子重量

public Vehicles(String brand, String color, int wheelsNum, double wheelsWight) {
this.brand = brand;
this.color = color;
this.wheelsNum = wheelsNum;
this.wheelsWight = wheelsWight;
}
public void run(){
System.out.println("我已经开动啦");
}
public void showInfo(){
System.out.println(this);
}

@Override
public String toString() {
return
"brand='" + brand + '\'' +
", color='" + color + '\'' +
", wheelsNum=" + wheelsNum +
", wheelsWight=" + wheelsWight;
}
}
class Car extends Vehicles{
private int seats; // 座位个数
public Car(String brand, String color, int wheelsNum, double wheelsWight,int seats) {
super(brand, color, wheelsNum, wheelsWight);
this.seats = seats;
}
public void showCar(){
System.out.println(this);
}

@Override
public String toString() {
return "Car{ " +super.toString() +
"seats=" + seats +
'}';
}
}

class Truck extends Vehicles{
private int load; // 载重

public Truck(String brand, String color, int wheelsNum, double wheelsWight,int load) {
super(brand, color, wheelsNum, wheelsWight);
this.load = load;
}
public void showTruck(){
System.out.println(this);
}

@Override
public String toString() {
return "Truck{" + super.toString() +
"load=" + load +
'}';
}
}

image-20220418094052455

总结

下午学习了40分钟左右,由赖琳同学和王静老师讲接口和抽象类,王静老师提问问题,一些问题专业名词,在java中不一样,一下子回答不上来,知道作用就知道是什么了,老师问了些陷阱的问题,对多态对抽象类,也告诉我们演讲应该怎么演讲,出了一些抽象类的题目,告知我们代码能力的重要性。这样讨论下来,知道了未来的学习步骤,变得系统化高效。

4.18 - 4.19项目三完成

1.头:日期、所学内容出处

https://www.bilibili.com/video/BV1Kb411W75N?p=405

2.标题

项目三开发团队调度软件

IDEA的基本使用

3.所学内容概述

项目三

IDEA

考察的东西很多(基础向):多态、封装、继承等都有体现、以及基本语法和数组的使用,异常处理等知识点。

image-20220420123909423

4、根据概述分章节描述

内容分为4个包,domain基本是程序中的信息,service中是信息数组,view中一个工具类,一个主程序main。

domain的包比较简单,基本利用抽象类,重写方法就行。service中就用到的对象数组和多态比较多,调用其他类中的对象信息,比较麻烦,容易搞混,主程序main也比较简单基本用是switch就好。根据选择调用不同的对象的方法就好。

5.章节内容 难点

章节内容(节标题,重点),难点(比较难理解的内容和较容易出错部分,关键代码或关键配置,BUG截图+解决方案)

章节内容

重点:项目三的完成

IDEA的基本使用

难点

对团队添加成员的操作

用到了强转和多次的异常处理equals的用法等

类创造的对象 对象的继承点 调用的属性容易搞混,单词不太熟悉,来回翻看,英语单词很重要。

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
    public void addMember(Employee e) throws TeamException {

// 成员已经满了 无法添加
if (total >= MAX_MEMBER){
throw new TeamException("成员已满,无法添加");
}

// 该成员不是开放人员 无法添加
if (!(e instanceof programmer)){
throw new TeamException("该成员不是开放人员,无法添加");
}

// 该员工已经在本开发团队
if (isExist(e)){
throw new TeamException("该员工已经在本开发团队");
}


// 该员工已经是某团队成员
programmer p = (programmer) e;

if ("BUSY".equals(p.getStatus().getNAME())) {
throw new TeamException("该员工已经是某团队的成员");
}// 该员工正在休假

if ("VOCATION".equals(p.getStatus().getNAME())){
throw new TeamException("该员工正在休假");
}

//获取团队中已经有的程序员 设计师 架构师 的数量
int programmerNum = 0,designerNum = 0,architectNum = 0;

//架构师
for (programmer teams : team){
if (teams instanceof Architect){
architectNum++;
}
else if (teams instanceof Designer){
designerNum++;
}else if(teams != null){
programmerNum++;
}

}

// 团队至多只能有一名架构师
// 团队至多只能有两名设计师
// 团队至多只能有三名程序员
if (p instanceof Architect){
if (architectNum >= 1){
throw new TeamException("团队至多只能有一名架构师");
}
}
else if (p instanceof Designer){
if (designerNum >= 2){
throw new TeamException("团队至多只能有两名设计师");
}
}else {
if (programmerNum >= 3){
throw new TeamException("团队至多只能有三名程序员");
}
}

// 属性修改赋值

p.setStatus(Status.BUSY); //工作状态
p.setMemberId(counter++); //团队ID

//将e添加在现有的team中
team[total++] = p;
}

遇到的BUG

自己写添加用户成员这里的时候,一直报错,看报错的异常,添加失败,寻找源头,addMember中有一个isExist这里的问题,和老师的代码对应,发现是自己的对对象数组的遍历有些许不一样,修改后成功了,我想原因是在团队成员中从来没有对象的时候,遍历的时候是空指针,所有会报错,没有正常的处理方式.

img

img

6.扩展学习部分

7.总结

重点是哪些知识比较重要,难点是你在学习过程中觉得比较繁琐,掌握起来有一点。

今天早上把项目三复习巩固了一下,试着自己敲出来,结果还是有点难度的,有些调用类的时候,尤其是在添加成员和查看团队成员的时候,搞不清楚,不太好掌握,考察的东西很多(基础向):多态、封装、继承等都有体现、以及基本语法和数组的使用,异常处理等知识点,明天可以再尝试一下,下午学习了系统学习了IDEA使用,一直再用IDEA随便过过就好了。

4.21 多线程

1.头:日期、所学内容出处

https://www.bilibili.com/video/BV1Kb411W75N?p=405

2.标题

多线程

3.所学内容概述

多线程-章节概述_程序进程线程的概念
多线程-单核与多核CPU的任务执行_并行与并发
多线程-多线程的优点等
多线程-创建多线程方式一:继承Thread类
多线程-创建过程中两个问题的说明
多线程-继承方式的课后练习
多线程-线程的常用方法

4、根据概述分章节描述

程序进程线程的概念

image-20220421135821845

优点:和所有语言一样

image-20220422081331907

多线程中的常用方法

image-20220421171515081

代码演示

过程中出现了点小问题,isAlive方法刚开始在start前面,执行出来是false 放到 start后面就是正常的true线程存在

isAlive() 方法的作用是判断当前的线程是否处于活动状态。什么是活动状态呢?活动状态就是线程已经启动且尚未终止。线程处于正在运行或准备开始运行的状态,就认为线程是“存活”的。

5.章节内容 难点

章节内容(节标题,重点),难点(比较难理解的内容和较容易出错部分,关键代码或关键配置,BUG截图+解决方案)

重点

10常用方法的使用

难点 代码

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
public class ThreadMethodTest {
public static void main(String[] args) throws InterruptedException {
HelloThread1 h1 = new HelloThread1("hello1");
// h1.setName("Hello1");
System.out.println(h1.isAlive());

h1.start();
System.out.println(h1.isAlive());

Thread.currentThread().setName("主线程");
for (int i = 0;i < 100;i++){
if (i % 2 != 0){
Thread.sleep(1);
System.out.println(Thread.currentThread().getName() + " :  " + i);
}
// if (i == 20){
// try {
// h1.join();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }

}


}
}

class HelloThread1 extends Thread{
public HelloThread1(String name) {
super(name);
}

@Override
public void run() {
for (int i = 0;i < 100;i++){
if (i % 2 == 0){
try {
sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " :  " + i);
}
// if (i % 20 == 0){
// yield();
// }
}
}

}

BUG(失误)

过程中出现了点小问题,isAlive方法刚开始在start前面,执行出来是false 放到 start后面就是正常的true线程存在

isAlice方法在实行线程时候和没执行结果不同

isAlive() 方法的作用是判断当前的线程是否处于活动状态。什么是活动状态呢?活动状态就是线程已经启动且尚未终止。线程处于正在运行或准备开始运行的状态,就认为线程是“存活”的。

image-20220422081450814

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

/**
* @ClassName subjectTest
* @Description TODO
* @Author CC
* @DATE 2022/4/22 8:18
* @Version 1.0
*/

public class subjectTest {
public static void main(String[] args) {
test1 test1 = new test1("偶线程");
test2 test2 = new test2("奇线程");
test1.start();
test2.start();


}

}

class test1 extends Thread{
public test1(String name) {
super(name);
}

@Override
public void run() {
for (int i = 0; i < 101;i++){
if(i % 2 ==0){
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.getName() + " : " + i);
}
}
}
}
class test2 extends Thread{
public test2(String name) {
super(name);
}

@Override
public void run() {
for (int i = 0; i < 101;i++){
if (i % 2 != 0) {
try {
sleep(1500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.getName() + " : " + i);
}
}
}
}

image-20220422083648354

CSDN搜到的方法

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
public class subjectTest2 {
public static void main(String[] args) {
SSS sss = new SSS();
sss.turning();

}
}

class SSS{
private int count = 0;
private final Object lock = new Object();

public void turning() {
Thread even = new Thread(() -> {
while (count < 100) {
synchronized (lock) {
// 只处理偶数
if ((count & 1) == 0) {
System.out.println(Thread.currentThread().getName() + ": " + count++);
}
}
}
}, "偶数");
Thread odd = new Thread(() -> {
while (count < 100) {
synchronized (lock) {
// 只处理奇数
if ((count & 1) == 1) {
System.out.println(Thread.currentThread().getName() + ": " + count++);
}
}
}
}, "奇数");
even.start();
odd.start();
}

}

image-20220422084258274

是利用一个输出的时候判断一下当前需要输出的数是不是自己要负责打印的值,如果是就输出,不是就直接释放锁。

因为自己还没学到,等到学完锁,再回来写一次

7.总结

重点是理解多线程的好处,以及原理,难点暂时没有很难,理解多线程,前段时间,学了python中的多线程,大差不大,就是代码不太一样,用一些方法的时候是需要加上try 来处理异常的。多线程也是java高级的第一部分,需要熟练掌握,知道多进程的使用和场景,就知道以后开发,应该都是多任务执行,大大提高了效率,一些自己想实现的程序,利用多线程,是可以做到的。

4.25多线程 线程安全问题

1.头:日期、所学内容出处

https://www.bilibili.com/video/BV1Kb411W75N?p=405

2.标题

P431 429.尚硅谷_多线程-理解线程的安全问题
P432 430.尚硅谷_多线程-线程安全问题的举例和解决措施
P433 431.尚硅谷_多线程-同步代码块处理实现Runnable的线程安全问题
P434 432.尚硅谷_多线程-同步代码块处理继承Thread类的线程安全问题
P435 433.尚硅谷_多线程-同步方法处理实现Runnable的线程安全问题
P436 434.尚硅谷_多线程-同步方法处理继承Thread类的线程安全问题
P437 435.尚硅谷_多线程-线程安全的单例模式之懒汉式
P438 436.尚硅谷_多线程-死锁的问题
P439 437.尚硅谷_多线程-Lock锁方式解决线程安全问题
P440 438.尚硅谷_多线程-同步机制的课后练习
P441 439.尚硅谷_多线程-线程通信的例题

3.所学内容概述

多线程线程安全问题以及处理方法

lock解决死锁问题

完成线程间通讯

4、根据概述分章节描述

解决方法

image-20220425093807313

Runnable接口线程安全问题 解决方法 可用this

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 ThreadTest1 {
public static void main(String[] args) {
MyThread m1 = new MyThread();
Thread t1 = new Thread(m1);
Thread t2 = new Thread(m1);
Thread t3 = new Thread(m1);
t1.setName("电脑一");
t2.setName("电脑二");
t3.setName("电脑三");
t1.start();
t2.start();
t3.start();

}
}

class MyThread implements Runnable{
private int ticket = 100;
@Override
public void run() {
while(true){
synchronized (this) {
if (ticket > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " : 卖票 : 票号为 " + ticket);
ticket--;
}else {
break;
}
}
}
}
}

继承线程安全问题 同步代码块

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
public class windowsTest {
public static void main(String[] args) {
windows w1 = new windows();
windows w2 = new windows();
windows w3 = new windows();
w1.setName("电脑一");
w2.setName("电脑二");
w3.setName("电脑三");
w1.start();
w2.start();
w3.start();
}
}


class windows extends Thread{
private static int ticket = 10000;
private static Object object = new Object();


@Override
public void run() {
while(true) {
// synchronized (object) {
synchronized (windows.class) {
if (ticket > 0) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(getName() + " : 卖票 : 票号为 " + ticket);
ticket--;
} else {
break;
}
}
}
}
}

同步方法解决继承线程安全问题

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
public class windowsTest {
public static void main(String[] args) {
windows w1 = new windows();
windows w2 = new windows();
windows w3 = new windows();
w1.setName("电脑一");
w2.setName("电脑二");
w3.setName("电脑三");
w1.start();
w2.start();
w3.start();
}
}


class windows extends Thread{
private static int ticket = 100;


@Override
public void run() {
while(true) {
// synchronized (object) {
show();
}
}
private static synchronized void show(){
if (ticket > 0) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " : 卖票 : 票号为 " + ticket);
ticket--;
}
}
}

同步方法解决接口问题

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 ThreadTest1 {
public static void main(String[] args) {
MyThread m1 = new MyThread();
Thread t1 = new Thread(m1,"电脑一");
Thread t2 = new Thread(m1);
Thread t3 = new Thread(m1);
t2.setName("电脑二");
t3.setName("电脑三");
t1.start();
t2.start();
t3.start();

}
}

class MyThread implements Runnable{
private int ticket = 100;
@Override
public void run() {
while(true){
show();
}
}
private synchronized void show(){
if (ticket > 0) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " : 卖票 : 票号为 " + ticket);
ticket--;
}
}
}

线程同步 锁

image-20220425231622951

1
2
 private ReentrantLock lock = new ReentrantLock(true);
//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
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
class Account{
private double balance;
private ReentrantLock lock = new ReentrantLock(true);


public Account(double balance) {
this.balance = balance;
}
// 存钱
public void deposit(double amt){
try {
lock.lock();
if (amt > 0){
balance += amt;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() +"存钱成功 账户余额 : " + balance);
}
}finally {
lock.unlock();
}


}
}

class Customer extends Thread{
private final Account account;

public Customer(Account account) {
this.account = account;
}

@Override
public void run() {
for (int i = 0; i < 3; i++) {
account.deposit(1000);
}
}
}


public class AccountTest {
public static void main(String[] args) {
Account account = new Account(0);
Customer c1 = new Customer(account);
Customer c2 = new Customer(account);
c1.setName("甲");
c2.setName("乙");
c1.start();
c2.start();
}

}

线程通讯

image-20220425231746643

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
public class waitTest {
public static void main(String[] args) {
wait wait = new wait();
Thread t1 = new Thread(wait,"奇线程");
Thread t2 = new Thread(wait,"偶线程");
t2.start();
t1.start();



}
}
class wait implements Runnable{
private static int num = 100;

@Override
public void run() {
while (true) {
synchronized (this) {
notify();
if (num > 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+ " : " + num);
num--;
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
break;
}

}
}

}
}

5.章节内容 难点

章节内容(节标题,重点),难点(比较难理解的内容和较容易出错部分,关键代码或关键配置,BUG截图+解决方案)

章节内容

总结在一个案例中

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
class Clerk{
private int product = 0;

public synchronized void produceProduct() { //生产
if (product < 20){
product++;
System.out.println(Thread.currentThread().getName() + " 开始生产第 " + product + "个产品");
notify();
}else {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

public synchronized void printProduct() { //消费
if (product > 0){
int num = new Random().nextInt(19)+1;
if (product > num){
product -= num;
System.out.println(Thread.currentThread().getName() + " 消费了 " + num + "个产品");
notify();
}else {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}

class Consumer extends Thread{ //消费者
private Clerk clerk;

public Consumer(Clerk clerk) {
this.clerk = clerk;
}

@Override
public void run() {
System.out.println(getName() + " : 开始消费产品........");
while (true){
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
clerk.printProduct();
}
}
}

class Producer extends Thread{ // 生产者
private Clerk clerk;

public Producer(Clerk clerk) {
this.clerk = clerk;
}

@Override
public void run() {
System.out.println(getName() + " : 开始生产产品........");
while (true){
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
clerk.produceProduct();
}
}
}

public class ProductTest {
public static void main(String[] args) {
Clerk clerk = new Clerk();
Consumer p1 = new Consumer(clerk);
p1.setName("消费者[11]");
Producer p2 = new Producer(clerk);
p2.setName("生产者[1]");
p1.start();
p2.start();

}
}

6.扩展学习部分

synchronized和Lock的异同

image-20220425103544527

开发中Lock > 同步代码块 > 同步方法

Lock奇偶交替

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 java.util.concurrent.locks.ReentrantLock;


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

Lock lock = new Lock();
Thread lock1 = new Thread(lock,"奇线程");
Thread lock2 = new Thread(lock,"偶线程");
lock1.start();
lock2.start();

}
}
class Lock implements Runnable{
private int num = 100;
private ReentrantLock lock = new ReentrantLock(true);

@Override
public void run() {
while (true) {
try {
lock.lock();
if (num > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " : " + num);
num--;
} else {
break;
}
}finally {
lock.unlock();
}

}
}
}

wait notify交替

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
/**
* @ClassName waitTest
* @Description TODO
* @Author CC
* @DATE 2022/4/25 14:41
* @Version 1.0
*/

public class waitTest {
public static void main(String[] args) {
wait wait = new wait();
Thread t1 = new Thread(wait,"奇线程");
Thread t2 = new Thread(wait,"偶线程");
t2.start();
t1.start();



}
}
class wait implements Runnable{
private static int num = 100;

@Override
public void run() {
while (true) {
synchronized (this) {
notify();
if (num > 0){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+ " : " + num);
num--;
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
break;
}

}
}

}
}

7.总结

今天写了11个的代码,今天的多线程安全问题是很重要的,必要彻底弄懂 ,难点在于寻找存在安全性的代码行,加入 synchronized和lock等方法解决,在做了最后一个综合性很强的练习后,有很大的提升,基本可以解决简单的安全问题了。CSDN的文章,有些能讲述的很明白。

4.26 线程池 常用类

1.头:日期、所学内容出处

https://www.bilibili.com/video/BV1Kb411W75N?p=405

2.标题

P444 442.尚硅谷_多线程-创建多线程的方式三:实现Callable接口
P445 443.尚硅谷_多线程-使用线程池的好处
P446 444.尚硅谷_多线程-创建多线程的方式四:使用线程池
P447 445.尚硅谷_常用类-每天一考
P448 446.尚硅谷_常用类-复习:生命周期与同步机制
P449 447.尚硅谷_常用类-复习:线程通信和新的线程创建方式等
P450 448.尚硅谷_常用类-Java常用类的概述
P451 449.尚硅谷_常用类-String类的概述
P452 450.尚硅谷_常用类-理解String的不可变性
P453 451.尚硅谷_常用类-String不同实例化方式的对比
P454 452.尚硅谷_常用类-String不同拼接操作的对比
P455 453.尚硅谷_常用类-String的一道面试题
P456 454.尚硅谷_常用类-JVM中涉及字符串的内存结构
P457 455.尚硅谷_常用类-String的常用方法1
P458 456.尚硅谷_常用类-String的常用方法2
P459 457.尚硅谷_常用类-String的常用方法3
P460 458.尚硅谷_常用类-回顾String与基本数据类型包装类的转换
P461 459.尚硅谷_常用类-String与char[]之间的转换
P462 460.尚硅谷_常用类-String与byte[]之间的转换
P463 461.尚硅谷_常用类-解决一个拼接问题
P464 462.尚硅谷_常用类-面试中String算法考查的说明
P465 463.尚硅谷_常用类-StringBuffer和StringBuilder的介绍
P466 464.尚硅谷_常用类-StringBuffer的源码分析
P467 465.尚硅谷_常用类-StringBuffer中的常用方法
P468 466.尚硅谷_常用类-String、StringBuffer、StringBuilder效率对比
P469 467.尚硅谷_常用类-System类中获取时间戳的方法
P470 468.尚硅谷_常用类-Java中两个Date类的使用

3.所学内容概述

使用用更加强大的Callable接口创建多线程

利用线程池创建线程,并明白其优点。

复习线程内容 String类的使用

StringBuffer、StringBuilder的进阶方法

Data类的使用

4、根据概述分章节描述

callable的好处

image-20220426094503725

callable接口的创建线程

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
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
* @ClassName CallableTest
* @Description TODO
* @Author CC
* @DATE 2022/4/26 8:36
* @Version 1.0
*/

public class CallableTest {
public static void main(String[] args) throws Exception {
person p1 = new person();
FutureTask futureTask = new FutureTask(p1);
new Thread(futureTask).start();
try {
Object o = futureTask.get();
System.out.println("总和 : "+o);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}

}


}
class person implements Callable {


@Override
public Object call() throws Exception {
int sum =0;
for (int i = 0; i < 100; i++) {
if (i % 2 ==0){
System.out.println(i);
sum += i;
}

}
return sum;
}
}

线程池的好处

1、线程池的优势与结构
(1)降低系统资源消耗,通过重用已存在的线程,降低线程创建和销毁造成的消耗;

(2)提高系统响应速度,当有任务到达时,通过复用已存在的线程,任务可以不需要等待新线程的创建便能立即执行;

(3)提高线程的可管理性。方便线程并发数的管控。如果线程无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,可能也会导致内存占用过多而产生OOM。

(4)提供更强大的功能,延时定时线程池。

image-20220426094339909

创建线程池

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

/**
* @ClassName poolTest
* @Description TODO
* @Author CC
* @DATE 2022/4/26 9:00
* @Version 1.0
*/

class runPoll implements Runnable{
@Override
public void run() {
System.out.println("runPoll-----------------");

int sum =0;
for (int i = 0; i < 100; i++) {
if (i % 2 ==0){
System.out.println(i);
sum += i;
}
}
System.out.println(sum);
}
}
class callPool implements Callable {


@Override
public Object call() throws Exception {
System.out.println("callPoll-----------------");
int sum =0;
for (int i = 0; i < 100; i++) {
if (i % 2 ==0){
System.out.println(i);
sum += i;
}

}
return sum;
}
}
public class poolTest {
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(10);
System.out.println(service.getClass());
ThreadPoolExecutor service1 = (ThreadPoolExecutor) service; //强转 父类用子类方法
service1.setCorePoolSize(16);
// service1.setKeepAliveTime();

service.execute(new runPoll()); //Runnable
callPool callPool = new callPool();

service.submit(callPool); //callable pool

service.shutdown();
}
}

String常用方法

image-20220426103843405

示例

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

import org.junit.Test;

/**
* @ClassName StringMethodTest
* @Description TODO
* @Author CC
* @DATE 2022/4/26 10:40
* @Version 1.0
*/

public class StringMethodTest {
@Test
public void test1(){
String s1 = "helloWorld";
System.out.println(s1.length()); // 10 字符串长度
System.out.println(s1.charAt(0)); // h //返回索引处字符
System.out.println(s1.charAt(s1.length()-1)); //d
System.out.println(s1.isEmpty());
String s2 = "";
System.out.println(s2.isEmpty()); //判断是否为空字符
String s3 = s1.toUpperCase();
System.out.println(s3);
System.out.println(s1.toLowerCase()); //全部小写
System.out.println(s1.toUpperCase()); //全部大写
String s4 = " he llo world ";
System.out.println(s4);
System.out.println(s4.trim()); //去除出前后空格
}

@Test
public void test2(){
// boolean equals(String s) 是否完全相同
// boolean equalsIgnoreCase(String s) 忽略大小写进行比较
// boolean startsWith(String s) 判断字符串是否以某字符串开头
// boolean endsWith(String s) 判断字符串是否以某字符串结尾
// int compareTo(String s) 比较大小,返回正数(大于)、负数(小于)、0(相等)

String s1 = "abc";
String s2 = "abe";
System.out.println(s1.compareTo(s2));
String s3 = "无敌暴龙神之飞之呼吸";
System.out.println(s3.substring(3)); //从 3 开始截取新字符串
System.out.println(s3.substring(0, 2)); //切片 左闭右开
String s4 = "hello|world|java";
for (String s : s4.split("\\|")) {
System.out.print(s);
}
System.out.println();
System.out.println(s4.replace('|', ','));//创建新的 |替换 ,
System.out.println(s4);


}
}

常用方法二

image-20220426105716108

常用方法三

image-20220426110725502

java常用类

https://blog.csdn.net/u013343114/article/details/112599438?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165093765816781432998816%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165093765816781432998816&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-112599438.142^

String 和 char[ ]转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Test
public void test4(){
String str1 = "abc1234"; // a321cb4
for (char c : str1.toCharArray()) {
System.out.println(c);
}
char[] arr = new char[]{'h','e','l','l','o'};
String str2 = new String(arr);
System.out.println(str2);
String str3 = "abc1234"; // a321cb4
char[] chars = str3.toCharArray();
for (int i = 1, j = 5; i < j; i++, j--) {
char temp = chars[j];
chars[j] = chars[i];
chars[i] = temp;
}
System.out.println(chars);
}

String 和 byte[ ]的相互转换

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
@Test
public void test5() throws UnsupportedEncodingException {
String str1 = "abc123我爱中国";
//编码
byte[] bytes = str1.getBytes();
System.out.println(Arrays.toString(bytes));


byte[] gbks = str1.getBytes("gbk");
System.out.println(Arrays.toString(gbks));

//解码
System.out.println("--------------------");
String s = new String(bytes);
System.out.println(s);//默认UTF-8

String gbk = new String(gbks);
System.out.println(gbk);

String gbk1 = new String(gbks,"gbk");
System.out.println(gbk1);

final String s4 = "hello";
String s6 = "helloworld";
String s7 = s4 + "world";
System.out.println(s7 == s6);
}

5.章节内容 难点

章节内容(节标题,重点),难点(比较难理解的内容和较容易出错部分,关键代码或关键配置,BUG截图+解决方案)

String拼接 内存解析

image-20220426102458518

image-20220426103529621

1
2
3
4
String s1 = new String("1234");
String s2 = new String("1234");
System.out.println(s1 == s2); // true
System.out.println(s1.equals(s2)); // false

注意如果变量加final就是常量了,在常量池中

1
2
3
4
final String s4 = "hello";
String s6 = "helloworld";
String s7 = s4 + "world";
System.out.println(s7 == s6);//true

String Buffer常用方法

image-20220426144158658

三者效率对比

image-20220426144411138

两个Date类的使用

image-20220426151233672

image-20220426151351714

6.扩展学习部分

数组反转

1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void test3(){
//字符串反转
String s1 = "小白兔爱吃大白菜";
System.out.println(s1.length());
StringBuilder s2 = new StringBuilder();

for (int i = s1.length()-1; i >= 0; i--) {
s2.append(s1.charAt(i));
}
System.out.println(s2);
}

数据局部反转

1
2
3
4
5
6
7
8
String str3 = "abc1234"; // a321cb4
char[] chars = str3.toCharArray();
for (int i = 1, j = 5; i < j; i++, j--) {
char temp = chars[j];
chars[j] = chars[i];
chars[i] = temp;
}
System.out.println(chars);

7.总结

重点是哪些知识比较重要,难点是你在学习过程中觉得比较繁琐,掌握起来有一点

线程池的创建应该是很重要的,感觉也不简单,老师只是粗略的过了一遍,自己又去CSDN看了,有很多创建方法,想掌握也是有难度的,今天的学习劲头很好,一下看了40级,6个多小时的视频,博客和视频结合的方法,是很能增加自己的进度,String Buffe的方法和python的列表差不多,有删除 添加 查找 替换 ,String因为是一个final的类所以无法修改。这是源代码告知的。

4.28比较器

1.头:日期、所学内容出处

https://www.bilibili.com/video/BV1Kb411W75N?p=405

2.标题

比较器(重要) 常用其他类

3.所学内容概述

P485 483.尚硅谷_常用类-LocalDate、LocalTime、LocalDateTime的使用
P486 484.尚硅谷_常用类-Instant类的使用
P487 485.尚硅谷_常用类-DateTimeFormatter的使用
P488 486.尚硅谷_常用类-其它日期时间相关API的使用
P489 487.尚硅谷_常用类-IDEA的使用:导入Module
P490 488.尚硅谷_常用类-Java比较器概述
P491 489.尚硅谷_常用类-Comparable自然排序举例
P492 490.尚硅谷_常用类-自定义类实现Comparable自然排序
P493 491.尚硅谷_常用类-使用Comparator实现定制排序
P494 492.尚硅谷_常用类-System、Math、BigInteger、BigDecimal的使用

4、根据概述分章节描述

System类

image-20220428194835482

Math类

image-20220428194643960

BigInteger类

image-20220428194739441

BigDecimal类

image-20220428194800368

5.章节内容 难点

章节内容(节标题,重点),难点(比较难理解的内容和较容易出错部分,关键代码或关键配置,BUG截图+解决方案)

比较器

博客

https://blog.csdn.net/qq_43518425/article/details/113148547?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165114186516781818766465%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=165114186516781818766465&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-113148547.142

1.比较器使用背景

1
2
3
4
Java中的对象,正常情况下,只能进行比较:==  或  != 。不能使用 > 或 < 的
但是在开发场景中,我们需要对多个对象进行排序,言外之意,就需要比较对象的大小。
如何实现?使用两个接口中的任何一个:Comparable 或 Comparator

2.自然排序:使用Comparable接口

1
2
3
4
5
6
7
8
1.像String、包装类等实现了Comparable接口,重写了compareTo(obj)方法,给出了比较两个对象大小的方式。
2.像String、包装类重写compareTo()方法以后,进行了从小到大的排列
3. 重写compareTo(obj)的规则:
如果当前对象this大于形参对象obj,则返回正整数,
如果当前对象this小于形参对象obj,则返回负整数,
如果当前对象this等于形参对象obj,则返回零。
4. 对于自定义类来说,如果需要排序,我们可以让自定义类实现Comparable接口,重写compareTo(obj)方法。在compareTo(obj)方法中指明如何排序

3.定制排序:使用Comparator接口

  1. 3. 说明
       1.背景:
       当元素的类型没实现java.lang.Comparable接口而又不方便修改代码,或者实现了java.lang.Comparable接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象来排序
    
    2.重写compare(Object o1,Object o2)方法,比较o1和o2的大小:
    如果方法返回正整数,则表示o1大于o2;
    如果返回0,表示相等;
    返回负整数,表示o1小于o2。
    
    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



    ```java
    package day26;

    import org.junit.Test;

    import java.util.Arrays;
    import java.util.Comparator;

    /**
    * @ClassName CompareTest
    * @Description TODO
    * @Author CC
    * @DATE 2022/4/28 18:34
    * @Version 1.0
    */

    public class CompareTest {
    @Test
    public void test1(){
    String[] arr = new String[]{"AA","CC","GG","MM","DD","JJ"};
    Arrays.sort(arr);
    System.out.println(Arrays.toString(arr));
    }
    @Test
    public void test2(){
    Good[] arr = new Good[5];
    arr[0] = new Good("mi",15);
    arr[1] = new Good("dell",24);
    arr[2] = new Good("ROG",36);
    arr[3] = new Good("huawei",46);
    arr[4] = new Good("mic",46);
    Arrays.sort(arr);
    System.out.println(Arrays.toString(arr));
    }
    @Test
    public void test3(){
    Good[] arr = new Good[5];
    arr[0] = new Good("mi",15);
    arr[1] = new Good("dell",24);
    arr[2] = new Good("ROG",36);
    arr[3] = new Good("huawei",46);
    arr[4] = new Good("mic",46);
    // 价格从高到低 名词从低到高
    Arrays.sort(arr, new Comparator() {
    @Override
    public int compare(Object o1, Object o2) {
    if (o1 instanceof Good && o2 instanceof Good){
    Good g1 = (Good) o1;
    Good g2 = (Good) o2;
    //价格从高到低
    if (g1.getName().equals(g2.getName())){
    return -Double.compare(g1.getAge(),g2.getAge());
    }else {
    //名字从低到高
    return g1.getName().compareTo(g2.getName());
    }
    }
    throw new RuntimeException("传入数据类型不一样");
    }
    });
    System.out.println(Arrays.toString(arr));


    }



    @Test
    public void test4(){
    String[] arr = new String[]{"AA","CC","GG","MM","DD","JJ"};

    Arrays.sort(arr, new Comparator() {
    @Override
    public int compare(Object o1, Object o2) {
    if (o1 instanceof String && o2 instanceof String){
    String s1 = (String) o1;
    String s2 = (String) o2;
    return -s1.compareTo(s2);

    }
    throw new RuntimeException("传入数据类型不一样");
    }
    });

    System.out.println(Arrays.toString(arr));
    }
    }
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
package day26;

/**
* @ClassName Good
* @Description TODO
* @Author CC
* @DATE 2022/4/28 18:41
* @Version 1.0
*/

public class Good implements Comparable{
private String name;
private int age;
public Good(){

}
public Good(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;
}

@Override
public String toString() {
return "Good{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}

@Override
public int compareTo(Object o) {
if (o instanceof Good) {
Good goods = (Good)o;
return Double.compare(this.age, goods.age);
}
throw new RuntimeException("传入数据类型不一样");
}
}

BUG

equals是比较属性的,这里想加条件语句,用equals判断是否相等,但是报错了,提示不可以用int。
CSDN搜到这样一句话:equals方法是针对引用类型比较的,基本数据类型没有equals方法

img

6.扩展学习部分

暂无

7.总结

重点是哪些知识比较重要,难点是你在学习过程中觉得比较繁琐,掌握起来有一点

今天的学习任务比较简单,重点在比较器,其次是其他类,其他类不是很重要,比较器中的comparator可以自定义排序,功能十分强大,可以安装什么数据排序,再按照什么排序。comparable是要有实现类,通过重写compare方法来实现,comparator的功能比较强大。今天学习时间较短,没有扩展学习部分。

4.29枚举类 注解 集合

1.头:日期、所学内容出处

https://www.bilibili.com/video/BV1Kb411W75N?p=405

2.标题

枚举类的学习任务

3.所学内容概述

P495 493.尚硅谷_枚举类与注解-每天一考
P496 494.尚硅谷_枚举类与注解-复习:日期时间API
P497 495.尚硅谷_枚举类与注解-复习:Java比较器等
P498 496.尚硅谷_枚举类与注解-枚举类的理解
P499 497.尚硅谷_枚举类与注解-自定义枚举类
P500 498.尚硅谷_枚举类与注解-使用enum关键字定义枚举类
P501 499.尚硅谷_枚举类与注解-Enum类中的常用方法
P502 500.尚硅谷_枚举类与注解-使用enum关键字定义的枚举类实现接口
P503 501.尚硅谷_枚举类与注解-IDEA中导入Eclipse项目三修改Status为enum的定义
P504 502.尚硅谷_枚举类与注解-注解的理解
P505 503.尚硅谷_枚举类与注解-Annotation的使用示例
P506 504.尚硅谷_枚举类与注解-JDK内置的三个基本注解
P507 505.尚硅谷_枚举类与注解-如何自定义注解
P508 506.尚硅谷_枚举类与注解-jdk中4个基本的元注解的使用1
P509 507.尚硅谷_枚举类与注解-jdk中4个基本的元注解的使用2
P510 508.尚硅谷_枚举类与注解-jdk8新特性:可重复注解
P511 509.尚硅谷_枚举类与注解-jdk8新特性:类型注解
P512 510.尚硅谷_枚举类与注解-可重复注解中元注解不一致的问题解决
P513 511.尚硅谷_枚举类与注解-集合框架与项目的对比及概述
P514 512.尚硅谷_枚举类与注解-集合框架涉及到的API
P515 513.尚硅谷_枚举类与注解-Collection接口中的常用方法1

4、根据概述分章节描述

枚举类的使用

1
#定义一组常量时,强烈建议使用枚举类

image-20220429082801683

定义枚举类使用enum关键字

1
2
3
public enum Color {
RED,BLACK,YELLOW;
}

枚举类的好处

常用类

1
2
3
4
5
public class Color {
public static final String RED = "red";
public static final String BLACK = "black";
public static final String BLUE = "blue";
}
  • Color 定义的值范围 redblackblue 并没有包括 java ,编译器无法检查不在枚举中的值;
  • 定义的常量仍可与其他常量比较,但其用途并非是枚举星期值。
1
2
3
4
String color = "java";
if (Color.RED.equals(color)) {
// TODO:
}

枚举类的Color

1
2
3
4
5
6
7
8
9
10
public enum Color{
RED,BLACK,GREEN;
public static void main(String[] args) {
Color color = Color.RED;
if (Color.RED == color){
// TODO
}
}
}

String定义的常量相比,使用enum定义枚举有如下好处:

  • enum常量本身带有类型信息,即Color.RED类型是Color,编译器会自动检查出类型错误。例如,下面的语句不可能编译通过:
1
2
3
4
5
6
public static void main(String[] args) {
String color = "red";
if (Color.RED == color){ // Operator '==' cannot be applied to 'Color','java.lang.String'
// TODO
}
}
  • 不可能引用到非枚举的值,因为无法通过编译。

  • 不同类型的枚举不能互相比较或者赋值,因为类型不符。例如,不能给一个Weekday枚举类型的变量赋值为Color枚举类型的值

  • 这就使得编译器可以在编译期自动检查出所有可能的潜在错误。、

枚举类基本使用

image-20220429090942555

代码

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

/**
*@ClassName enumTest
*@Description TODO
*@Author CC
*@DATE 2022/4/29 8:36
*@Version 1.0
*/

public class enumTest {
public static void main(String[] args) {
Season summer = Season.SUMMER;
Season spring = Season.SPRING;
@SuppressWarnings("unused")
Season winter = Season.WINTER;
//toString
System.out.println(summer);
System.out.println();

//values 所有枚举值的toString
Season[] values = Season.values();
for (Season value : values) {
System.out.println(value);
}
System.out.println();
//valueOf(String objName):返回枚举类中对象名是objName的对象
Season autumn = Season.valueOf("AUTUMN");
System.out.println(autumn);
autumn.show(); //秋天的show
spring.show(); //春天的show


System.out.println(Season.class.getSuperclass());

}

}

interface Info{
void show();
}
//枚举类实现接口
enum Season implements Info{
SPRING("春天","春暖花开"){
@Override
public void show() {
System.out.println("春天在哪里");
}
},
SUMMER("夏天","夏日炎炎"){
@Override
public void show() {
System.out.println("宁静的夏天");
}
},
AUTUMN("秋天","秋高气爽"){
@Override
public void show() {
System.out.println("就让秋风带走我的思念");
}
},
WINTER("冬天","冬泳怪鸽"){
@Override
public void show() {
System.out.println("雪花飘飘");
}
};
private final String seasonName;
private final String seasonDesc;

Season(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
@SuppressWarnings("unused")

public String getSeasonName() {
return seasonName;
}
@SuppressWarnings("unused")
public String getSeasonDesc() {
return seasonDesc;
}

@Override
public String toString() {
return "Season{" +
"seasonName='" + seasonName + '\'' +
", seasonDesc='" + seasonDesc + '\'' +
'}';
}

@Override
public void show() {
System.out.println("这是一个季节");
}
}

集合

数组的缺点

image-20220429103442303

java集合分collection和Map体系

3.常用集合的分类:
Collection 接口的接口 对象的集合(单列集合)
├——-List 接口:元素按进入先后有序保存,可重复
│—————-├ LinkedList 接口实现类, 链表, 插入删除, 没有同步, 线程不安全
│—————-├ ArrayList 接口实现类, 数组, 随机访问, 没有同步, 线程不安全
│—————-└ Vector 接口实现类 数组, 同步, 线程安全
│ ———————-└ Stack 是Vector类的实现类
└——-Set 接口: 仅接收一次,不可重复,并做内部排序
├—————-└HashSet 使用hash表(数组)存储元素
│————————└ LinkedHashSet 链表维护元素的插入次序
└ —————-TreeSet 底层实现为二叉树,元素排好序 自然排序

Map 接口 键值对的集合 (双列集合)
├———Hashtable 接口实现类, 同步, 线程安全
├———HashMap 接口实现类 ,没有同步, 线程不安全-
│—————–├ LinkedHashMap 双向链表和哈希表实现
│—————–└ WeakHashMap
├ ——–TreeMap 红黑树对所有的key进行排序
└———IdentifyHashMap

Collection接口的常用方法

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

import org.junit.Test;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;

/**
* @ClassName CollectionTest
* @Description TODO
* @Author CC
* @DATE 2022/4/29 10:19
* @Version 1.0
*/

public class CollectionTest {

@Test
public void test1(){
Collection collection = new ArrayList();
// add(object e) 将e添加到集合collection中
collection.add("AA");
collection.add("BB");
collection.add(123);
collection.add(new Date());
System.out.println(collection);
System.out.println(collection.size());
Collection collection1 = new ArrayList();
collection1.add(123456);
collection1.add("CC");
// 将 collection1中的元素添加到集合中
collection.addAll(collection1);

// addAll():
System.out.println(collection.size());
System.out.println(collection);

// 判断是否为空
System.out.println(collection.isEmpty());
//清除元素
collection.clear();
System.out.println(collection.isEmpty());
}
}

image-20220429143153065

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Test
public void test2(){
Collection collection = new ArrayList();
collection.add("AA");
collection.add("BB");
collection.add(123);
collection.add(new Date());
// 集合---数组
Object[] objects = collection.toArray();
for (Object as : objects){
System.out.println(as);
}
// 数组 ---- 集合
List<String> strings = Arrays.asList(new String[]{"AA", "BB", "CC"});
System.out.println(strings);
List<int[]> ints = Arrays.asList(new int[]{123, 4566});
System.out.println(ints);
List ints1 = Arrays.asList(123, 4566);
System.out.println(ints1);
}

iterator方法

image-20220429144009619

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
@Test
public void test3(){
Collection collection = new ArrayList();

collection.add("AA");
collection.add("BB");
collection.add(123);
collection.add(new Date());

Iterator iterator = collection.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
//hasNext到最后了 要重新生成iterator
iterator = collection.iterator();

while (iterator.hasNext()){
Object o = iterator.next();
if ("AA".equals(o)){
iterator.remove();
}
}
//
iterator = collection.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}

}

List接口的使用

image-20220429151807168

List常用方法

image-20220429162840246

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
@Test
public void test4(){
ArrayList list = new ArrayList();
list.add("AA");
list.add(123);
list.add(456);
list.add("CC");
list.add(456);
list.add(new Date());
System.out.println(list);
list.add(1,"爱");
System.out.println(list);
list.set(1,"不爱");
System.out.println(list);
System.out.println(list.subList(1,5));
Iterator iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("--------------------------------");
for (Object as : list){
System.out.println(as);
}

}

5.章节内容 难点

章节内容(节标题,重点),难点(比较难理解的内容和较容易出错部分,关键代码或关键配置,BUG截图+解决方案)

注解概述

image-20220429093303639

注解重要的基本常用 https://zhuanlan.zhihu.com/p/158054068

@Override,@FunctionalInterface,@SuppressWarnings,@SafeVarargs,和@Deprecated。

它们都不会直接影响到程序的语义,只是作为注解(标识)存在 理解:类似于平常的便签纸

自定义注解

1
2
3
4
public @interface MyAnnotation {
//自定义注解
}

image-20220429095957764

元注解

image-20220429100540460

6.扩展学习部分

ArrayList,效率高 线程不安全

LinkedList, 对于频繁的插入 删除操作 使用此类效率比ArrayList高,底层使用双向链表存储

Vector 效率低 线程安全 古老实现类

三者的异同点

1
同:三个类都是实现了list接口,储存的特点相同 储存有序的,可重复的数据

7.总结

重点是哪些知识比较重要,难点是你在学习过程中觉得比较繁琐,掌握起来有一点

今天学习的东西有点多,需要消化,学习了枚举类的使用和应用,枚举类如果引用非枚举类中的值,编译器会无法通过,就使得编译器可以在编译期自动检查出所有可能的潜在错误。然后浅浅的看了一下注解,因为暂时用不到,看博客就过了,重点的集合,像是python中的list列表,是数组的优化性,功能比较强大,先学了Collection接口 然后是子接口list,添 删 补 查 都很方便。

5.2 Set和Map

1.头:日期、所学内容出处

https://www.bilibili.com/video/BV1Kb411W75N?p=405

2.标题

P535 533.尚硅谷_集合-Set接口实现类的对比
P536 534.尚硅谷_集合-Set的无序性与不可重复性的理解
P537 535.尚硅谷_集合-HashSet中元素的添加过程
P538 536.尚硅谷_集合-关于hashCode()和equals()的重写
P539 537.尚硅谷_集合-LinkedHashSet的使用
P540 538.尚硅谷_集合-TreeSet的自然排序
P541 539.尚硅谷_集合-TreeSet的定制排序
P542 540.尚硅谷_集合-每天一考
P543 541.尚硅谷_集合-复习:Collection及Collection的遍历
P544 542.尚硅谷_集合-复习:List接口
P545 543.尚硅谷_集合-复习:Set接口
P546 544.尚硅谷_集合-TreeSet的课后练习
P547 545.尚硅谷_集合-Set课后两道面试题
P548 546.尚硅谷_集合-Map接口及其多个实现类的对比
P549 547.尚硅谷_集合-Map中存储的key-value的特点

3.所学内容概述

Set接口的框架 对Set的理解

添加元素和哈希值的关系

重写equals和hashcode方法

P539 537.尚硅谷_集合-LinkedHashSet的使用

TreeSet的自然排序 和自定义排序

复习 课后练习

4、根据概述分章节描述

set接口的框架

image-20220502101815638

Set添加元素

hashSet接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Test
public void test1(){
Set set = new HashSet();
set.add(456);
set.add(123);
set.add("AA");
set.add("CC");
set.add(new Date());
set.add(129);
set.add(new User("金宝三",39));
set.add(new User("金宝三",39));

Iterator iterator = set.iterator();
System.out.println(set.size());
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}

LinkedHashSet接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Test
public void test2(){
Set set = new LinkedHashSet();
set.add(456);
set.add(123);
set.add("AA");
set.add("CC");
set.add(new Date());
set.add(129);
set.add(new User("金宝三",39));
set.add(new User("金宝三",39));

Iterator iterator = set.iterator();
System.out.println(set.size());
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}

Map接口

Map的框架

image-20220502150434741

Map的结构

image-20220502151342333

Map的使用方法

image-20220502152530191

遍历

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
@Test
public void test3(){
Map map = new HashMap();
map.put("AA",123);
map.put("BB",23);
map.put(45,62);
map.put("CC",123);
map.put("DD",123);
Set set = map.keySet();
System.out.println(set);
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("====");

Collection values = map.values();
for (Object obj : values){
System.out.println(obj);
}
//遍历所有的key-value
//entrySet();
Set entrySet = map.entrySet();
for (Object o: entrySet){
Map.Entry entry = (Map.Entry)o;
System.out.println(entry.getKey() + "------>" + entry.getValue());
}
}

TreeMap自然排序 定制排序

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
@Test
public void test4(){
TreeMap map = new TreeMap();
User u1 = new User("Tom",23);
User u2 = new User("Jerry",20);
User u3 = new User("Jack",32);
User u4 = new User("Rose",18);
User u5 = new User("Bali",20);
map.put(u1,98);
map.put(u2,123);
map.put(u4,88);
map.put(u3,98);
map.put(u5,250);
Set entrySet = map.entrySet();
for (Object o: entrySet){
Map.Entry entry = (Map.Entry)o;
System.out.println(entry.getKey() + "------>" + entry.getValue());
}
}
@Test
public void test5(){

TreeMap map = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof User && o2 instanceof User){
User u1 = (User)o1;
User u2 = (User)o2;
int compare = u1.getName().compareTo(u2.getName());
if (compare!=0){
return compare;
}else {
return Integer.compare(u1.getAge(),u2.getAge());
}
}else {
throw new RuntimeException("类型不匹配");
}
}
});


User u1 = new User("Tom",23);
User u2 = new User("Jerry",20);
User u3 = new User("Jack",32);
User u4 = new User("Rose",18);
User u5 = new User("Bali",20);
map.put(u1,98);
map.put(u2,123);
map.put(u4,88);
map.put(u3,98);
map.put(u5,250);
Set entrySet = map.entrySet();
for (Object o: entrySet){
Map.Entry entry = (Map.Entry)o;
System.out.println(entry.getKey() + "------>" + entry.getValue());
}
}

Collections工具类的常用方法

image-20220502160019291

image-20220502155954389

5.章节内容 难点

章节内容(节标题,重点),难点(比较难理解的内容和较容易出错部分,关键代码或关键配置,BUG截图+解决方案)

添加元素(难点)

image-20220502101546347

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 SetTest {
public static void main(String[] args) {

}
@Test
public void test1(){
Set set = new HashSet();
set.add(456);
set.add(123);
set.add("AA");
set.add("CC");
set.add(new Date());
set.add(129);
set.add(new User("金宝三",39));
set.add(new User("金宝三",39));

Iterator iterator = set.iterator();
System.out.println(set.size());
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
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
public class User {
private String name;
private int age;

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

@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return age == user.age && Objects.equals(name, user.name);
}
//重写hashcode和equals方法

@Override
public int hashCode() {
return Objects.hash(name, age);
}
}

运行结果

image-20220502101648772

TreeSet自然排序和定制排序

image-20220502105240689

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
public class TreeSetTest {
@Test
public void test1(){
TreeSet set = new TreeSet();
//不能添加不同类
// set.add(123);
// set.add("AA");

// set.add(123);
// set.add(456);
// set.add(-42);
// set.add(0);
// Iterator iterator = set.iterator();
// while (iterator.hasNext()){
// System.out.println(iterator.next());
// }

}
@Test
public void test2(){
TreeSet set = new TreeSet();
System.out.println("=========================");
set.add(new User("Tom",23));
set.add(new User("Jerry",37));
set.add(new User("Jack",18));
set.add(new User("Jack",39));
set.add(new User("smith",23));
set.add(new User("Carry",23));
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
@Test
public void test3(){
Comparator com = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof User && o2 instanceof User){
User u1 = (User)o1;
User u2 = (User)o2;
int compare = u1.getName().compareTo(u2.getName());
if (compare!=0){
return compare;
}else {
return Integer.compare(u1.getAge(),u2.getAge());
}
}else {
throw new RuntimeException("类型不匹配");
}
}
};
TreeSet set = new TreeSet(com);
set.add(new User("Tom",23));
set.add(new User("Jerry",37));
set.add(new User("Jack",18));
set.add(new User("Jack",39));
set.add(new User("smith",23));
set.add(new User("Carry",23));
set.add(new User("Mary",33));
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}

}

}

image-20220502105314711

6.扩展学习部分

自然排序 定制排序 Date

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
public class Employee implements Comparable{
private String name;
private int age;
private MyDate birthday;
public Employee(){

}

public Employee(String name, int age, MyDate birthday) {
this.name = name;
this.age = age;
this.birthday = birthday;
}

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

public MyDate getBirthday() {
return birthday;
}

public void setBirthday(MyDate birthday) {
this.birthday = birthday;
}

@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", age=" + age +
", birthday=" + birthday +
'}';
}

@Override
public int compareTo(Object o) {
if (o instanceof Employee){
Employee e1 = (Employee) o;
return this.name.compareTo(e1.name);
}else {
throw new RuntimeException("类型不匹配");
}
}
}
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 MyDate {
private int year;
private int month;
private int day;

public MyDate(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}

public int getYear() {
return year;
}

public int getMonth() {
return month;
}

public int getDay() {
return day;
}

public String toString(){
return year + "年" + month +"月" + day + "日";
}
}
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
public class TreeSetTest1 {
public static void main(String[] args) {
Comparator com = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Employee && o2 instanceof Employee){
Employee e1 = (Employee) o1;
Employee e2 = (Employee) o2;
int compare = Integer.compare(e1.getBirthday().getYear(),e2.getBirthday().getYear());
//先年
if (compare != 0){
return compare;
}else{
//月
int compare1 = Integer.compare(e1.getBirthday().getMonth(),e2.getBirthday().getMonth());
if (compare1 != 0){
return compare1;
}else {
//日
return Integer.compare(e1.getBirthday().getDay(),e2.getBirthday().getDay());
}
}
}else {
throw new RuntimeException("类型不匹配");
}
}
};


TreeSet set = new TreeSet(com);
set.add(new Employee("Jane",20,new MyDate(2002,11,19)));
set.add(new Employee("Jack",19,new MyDate(2003,8,2)));
set.add(new Employee("Smith",20,new MyDate(2003,3,28)));
set.add(new Employee("Tom",20,new MyDate(2002,10,1)));
set.add(new Employee("Carry",20,new MyDate(2003,3,21)));
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}

}
}

7.总结

重点是哪些知识比较重要,难点是你在学习过程中觉得比较繁琐,掌握起来有一点

今天的学习内容很多,学习难度一般,集合已经完成,主要是Set接口和Map的方法是重点,源码解析等有点难度,也没执着于理解,今天的学习相对比较简单,底层结构除外,掌握程度90%,代码敲了十几个,熟能生巧,学习步骤:两个案例,在老师敲之前截图,自己做。方法也是看博客,做完再看老师最后的代码和实现,明天将泛型攻克。

5.3 File 和 泛型

1.头:日期、所学内容出处

https://www.bilibili.com/video/BV1Kb411W75N?p=405

2.标题

P562 560.尚硅谷_泛型与File-每天一考
P563 561.尚硅谷_泛型与File-复习1:Map
P564 562.尚硅谷_泛型与File-复习2:Collections和数据结构
P565 563.尚硅谷_泛型与File-为什么要使用泛型
P566 564.尚硅谷_泛型与File-泛型与File中使用泛型举例
P567 565.尚硅谷_泛型与File-泛型与File中使用泛型的练习
P568 566.尚硅谷_泛型与File-自定义泛型类举例
P569 567.尚硅谷_泛型与File-自定义泛型类泛型接口的注意点
P570 568.尚硅谷_泛型与File-自定义泛型方法举例
P571 569.尚硅谷_泛型与File-举例泛型类和泛型方法的使用情境
P572 570.尚硅谷_泛型与File-泛型在继承方面的体现
P573 571.尚硅谷_泛型与File-通配符的使用
P574 572.尚硅谷_泛型与File-使用通配符后数据的读取和写入要求
P575 573.尚硅谷_泛型与File-有限制条件的通配符的使用
P576 574.尚硅谷_泛型与File-自定义泛型类练习
P577 575.尚硅谷_泛型与File-File类的实例化
P578 576.尚硅谷_泛型与File-File类的常用方法1
P579 577.尚硅谷_泛型与File-File类的常用方法2
P580 578.尚硅谷_泛型与File-File类的课后练习

3.所学内容概述

泛型的好处 如何使用 自定义泛型 泛型的使用情景 继承中的泛型 泛型中通配符的使用 FIle文件的方法和实例化 以及课后练习

4、根据概述分章节描述

泛型继承

image-20220503085505877

泛型通配符

如图 在showketvalue1中定义泛型为Number 但是integer 是number的子类 却无法使用, 这时候就需要用到我们的通配符

image-20220503143539036

修改以后

image-20220503143715881

此处?是类型实参,而不是类型形参 !意思就是,此处的?和Number、String、Integer一样都是一种实际的类型,可以把?看成所有类型的父类Object。是一种真实的类型。可以解决当具体类型不确定的时候,这个通配符就是 ? ;当操作类型时,不需要使用类型的具体功能时,只使用Object类中的功能。那么可以用 ? 通配符来表未知类型。

泛型的上下界

image-20220503144111160

编译会报错因为String不是Number的子类

extends相当于[-无穷,Number]

super相当于[Number,+无穷]

File的创建方式

四种

1
2
3
4
5
6
7
8
9
10
11
public void test1(){
File file = new File("hello.txt");
File file1 = new File("D:\\CC\\IDEA\\day29\\hello.txt");
System.out.println(file);
System.out.println(file1);
File file2 = new File("D:\\CC\\IDEA","day29");
System.out.println(file2.isFile());
File file3 = new File(file2,"hello.txt");
System.out.println(file3.isFile());

}

File的方法

image-20220503144348807

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
@Test
public void test1(){
File file = new File("hello.txt");
File file1 = new File("D:\\CC\\IDEA\\day29\\hello.txt");
File file2 = new File("D:\\CC\\IDEA","day29");
File file3 = new File(file2,"hi.txt");


System.out.println(file1.getAbsolutePath());
System.out.println(file1.getPath());
System.out.println(file1.getName());
System.out.println(file1.getParent());
System.out.println(file1.length());
//毫秒数
Date date = new Date(file1.lastModified());
System.out.println(date);
System.out.println("================");
System.out.println(file3.getAbsolutePath());
System.out.println(file3.getPath());
System.out.println(file3.getName());
System.out.println(file3.getParent());
System.out.println(file3.length());
//毫秒数
System.out.println(new Date(file3.lastModified()));
System.out.println("================");
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Test
public void test2(){
File file = new File("D:\\CC\\IDEA");
String[] list = file.list();
for (String s : list){
System.out.println (s);
}
System.out.println("=====");

File[] list1 = file.listFiles();
for (File f : list1){
System.out.println(f);
}
}
@Test
public void test3(){
File file1 = new File("hello.txt");
File file2 = new File("D:\\IO\\hi.txt");
System.out.println(file2.renameTo(file1));

}

File类的判断

image-20220503150808314

IO流

IO流的分类

image-20220503165255640

5.章节内容 难点

章节内容(节标题,重点),难点(比较难理解的内容和较容易出错部分,关键代码或关键配置,BUG截图+解决方案)

File的创建和删除

image-20220503151720613

1
2
3
4
5
6
7
8
9
10
11
@Test
public void test4() throws IOException {
File file = new File("hi.txt");
if (!file.exists()){//文件存在
file.createNewFile();
System.out.println("创建成功");
}else {
file.delete();
System.out.println("删除成功");
}
}

6.扩展学习部分

打印出目录下所有的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Test
public void test3(){

File file = new File("D:\\CC\\IDEA\\scr");
printSubFile(file);

}

private static void printSubFile(File file) {
File[] files = file.listFiles();
assert files != null;
for (File f : files){
if (f.isDirectory()){
printSubFile(f);
}else {
System.out.println(f);
}
}
}

运行结果

image-20220503155735768

7.总结

学习难度一般,主要是方法的使用比较枯燥,掌握了90% ,刚开始对于泛型的<?>通配符不太理解,还有继承这块,去看了博客,逐渐明白?是解决泛型无法继承的东西,在jdk1.2出来的,然后就是对文件的处理,自己早在之前就看过对文件的处理,掌握起来也比较容易,今天学习内容还是蛮多的,泛型和File的处理,然后初见IO流,做了几个练习题,代码测试的方法比较多。

5.5 IO流

1.头:日期、所学内容出处

https://www.bilibili.com/video/BV1Kb411W75N?p=405

2.标题

P581 579.尚硅谷_IO流-每天一考
P582 580.尚硅谷_IO流-复习:IO流中使用泛型
P583 581.尚硅谷_IO流-复习:自定义泛型结构与通配符
P584 582.尚硅谷_IO流-复习:File类的使用
P585 583.尚硅谷_IO流-IO流概述与流的分类
P586 584.尚硅谷_IO流-IO流的体系结构
P587 585.尚硅谷_IO流-FileReader读入数据的基本操作
P588 586.尚硅谷_IO流-FileReader中使用read(char[] cbuf)读入数据
P589 587.尚硅谷_IO流-FileWriter写出数据的操作
P590 588.尚硅谷_IO流-使用FileReader和FileWriter实现文本文件的复制
P591 589.尚硅谷_IO流-字符流不能处理图片文件的测试
P592 590.尚硅谷_IO流-使用FileInputStream不能读取文本文件的测试
P593 591.尚硅谷_IO流-使用FileInputStream和FileOutputStream读写非文本文件
P594 592.尚硅谷_IO流-使用FileInputStream和FileOutputStream复制文件的方法测试

3.所学内容概述

IO的介绍

IO字符流的写入和读取

IO字节流的写入和读取

IO字符流和字节流的适用场景

4、根据概述分章节描述

IO流的介绍

原理

image-20220505201000170

IO流的分类

image-20220505203243307

image-20220505201047511

IO的体系

image-20220505202059232

image-20220506081437053

文本文件读取

使用FileReader类 read(数组)方法读取

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
@Test
public void test1(){
//1.file类的实例化
File file = new File("hello.txt");
FileReader fileReader = null;

try {

//2.FileReader流的实例化
fileReader = new FileReader(file);
//3.读取
char[] chars = new char[5];//5个5个读取
int num;
while ((num =fileReader.read(chars)) != -1){
String str = new String(chars,0,num);
System.out.print(str);

// System.out.print(String.valueOf(chars));
}

} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileReader != null) {
try {
fileReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

文件的写入

用FileWriter 中的writer写入

FileWriter构造器后面加true是添加 默认是false 覆盖

1
2
3
4
5
6
7
8
9
10
11
12
@Test
public void test2() throws IOException {
File file = new File("hello1.txt");
FileWriter writer = new FileWriter(file,true);
writer.write("hello java\n");
writer.write("hello python\n");
writer.write("hfa\n");
writer.write("cxy\n");

writer.close();

}

注意 FileWriter和FileReader都属于字符流 无法读和写非文本文件,非文本文件需要用字节流

字节流

image-20220505201935633

文件的写入

会造成中文的乱码 详细见扩展学习部分

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
@Test
public void test1(){
FileInputStream fis = null;
try {
File file = new File("hello31.txt");
//造流
fis = new FileInputStream(file);
//读取
byte[] bytes = new byte[38];
int len;
while ((len = fis.read(bytes)) != -1){
String str = new String(bytes,0,len);
System.out.print(str);

}

} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//关闭
}

}

5.章节内容 难点

章节内容(节标题,重点),难点(比较难理解的内容和较容易出错部分,关键代码或关键配置,BUG截图+解决方案)

重点

个人理解

字符流是对于文本文件有很好的读取,字节流因为中文的占位不一样,容易读取一半造成乱码,但是普通的复制 只要将数组调的大一点就好了。

文本文件的copy用字符流

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
@Test
public void FileReaderFileWriter(){

//1.创建File类的对象,指明 读入和写出的文件

File fileRead = new File("hello.txt");
File fileWrite = new File("helloCopy.txt");

//2.创造输入流和输出流的对象
FileReader fr = null;
FileWriter fw = null;
try {
fr = new FileReader(fileRead);
fw = new FileWriter(fileWrite);

//3.数据的读入和写入操作
//读数据

char[] chars = new char[5];

int num;

while ((num = fr.read(chars)) != -1){

//写入
fw.write(chars,0,num);

}
System.out.println("Copy成功");

} catch (IOException e) {
e.printStackTrace();
} finally {

//4.关闭流资源
try {
if (fr != null && fw != null){
fr.close();
fw.close();
}

} catch (IOException e) {
e.printStackTrace();
}
}
}

非文本文件的copy字节流

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
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Scanner;

/**
* @ClassName copyInfile
* @Description TODO
* @Author CC
* @DATE 2022/5/5 19:25
* @Version 1.0
*/

public class copyInfile {
public static void main(String[] args) {
long start = System.currentTimeMillis();
Scanner scanner = new Scanner(System.in);
System.out.println("输入要复制的文件");
String s1 = scanner.next();
System.out.println("输入复制过来的文件重命名");
String s2 = scanner.next();

// String s1 = "D://CC//Videos//douyin.mp4";
// String s2 = "D://Desktop//java2.mp4";

copyPicture(s1,s2);

long end = System.currentTimeMillis();
System.out.println("复制操作花费的时间为 : " + (end - start));

}
public static void copyPicture(String Filename1,String Filename2){
FileInputStream fis = null;
FileOutputStream fos = null;

//创造文件
try {
File file = new File(Filename1);
File file1 = new File(Filename2);

//造流
fis = new FileInputStream(file); //存在的图片
fos = new FileOutputStream(file1);//复制的地方


byte[] bytes = new byte[1024];//数组储存
int len; //记长度
//读文件 写入
while ((len = fis.read(bytes)) != -1){
fos.write(bytes,0,len);//写入
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null){
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

BUG

说找不到路径,但是我文件是在同一个模块下面的,后面查CSDN 说在IDEA中在main主程序里面输入相对路径,读取的IDEA大模块包下,所以不可以,如果是在单元测试中就是读取的同一个模块,在main的下需要把文件移动到IDEA中创建文件也是在IDEA模块中,或者写绝对路径

img

6.扩展学习部分

中文的读取

假设文件file1.txt,采用字节流的话是这样读的:
a中国bc张三fe
第一次读:一个字节,正好读到’a’
第二次读:一个字节,正好读到’中’字符的一半。
第三次读:一个字节,正好读到’中’字符的另外一半。

按照 字符 的方式读取数据的,一次读取一个字符.
这种流是为了方便读取 普通文本文件 而存在的,这种流不能读取:图片、声音、视频等文件。只能读取 纯文本文件,连word文件都无法读取。

注意:
纯文本文件,不单单是.txt文件,还包括 .java、.ini、.py 。总之只要 能用记事本打开 的文件都是普通文本文件。

eg.
假设文件file1.txt,采用字符流的话是这样读的:
a中国bc张三fe
第一次读:'a’字符('a’字符在windows系统中占用1个字节。)
第二次读:'中’字符('中’字符在windows系统中占用2个字节。)

7.总结

重点是哪些知识比较重要,难点是你在学习过程中觉得比较繁琐,掌握起来有一点

今天的学习比较容易,主要是先认识IO流,然后实现对文本的读取和写入,全部掌握了,自己也可以独立完成文本文件和非文本文件的复制,这里的方法和python中的文件处理类似,所以学习比较容易,IO的类和方法比较多,还是得多加掌握,多敲代码,做了两个文件的copy 视频 图片都可以,对文件的处理还是很有兴趣的。

5.6 缓冲流和网络编程入门

1.头:日期、所学内容出处

https://www.bilibili.com/video/BV1Kb411W75N?p=405

2.标题

P595 593.尚硅谷_IO流-缓冲流(字节型)实现非文本文件的复制
P596 594.尚硅谷_IO流-缓冲流与节点流读写速度对比
P597 595.尚硅谷_IO流-缓冲流(字符型)实现文本文件的复制
P598 596.尚硅谷_IO流-缓冲流课后练习1
P599 597.尚硅谷_IO流-缓冲流课后练习2
P600 598.尚硅谷_IO流-转换流概述与InputStreamReader的使用
P601 599.尚硅谷_IO流-转换流实现文件的读入和写出
P602 600.尚硅谷_IO流-多种字符编码集的说明
P603 601.尚硅谷_IO流-标准的输入、输出流
P604 602.尚硅谷_IO流-打印流的使用
P605 603.尚硅谷_IO流-数据流的使用
P606 604.尚硅谷_IO流与网络编程-每天一考
P607 605.尚硅谷_IO流与网络编程-复习:IO流概述
P608 606.尚硅谷_IO流与网络编程-复习:节点流
P609 607.尚硅谷_IO流与网络编程-复习:缓冲流与转换流
P610 608.尚硅谷_IO流与网络编程-复习:其它几个处理流
P611 609.尚硅谷_IO流与网络编程-对象序列化机制的理解
P612 610.尚硅谷_IO流与网络编程-对象流序列化与反序列化字符串操作
P613 611.尚硅谷_IO流与网络编程-自定义类实现序列化与反序列化操作
P614 612.尚硅谷_IO流与网络编程-serialVersionUID的理解
P615 613.尚硅谷_IO流与网络编程-自定义类可序列化的其它要求
P616 614.尚硅谷_IO流与网络编程-RandomAccessFile实现数据的读写操作
P617 615.尚硅谷_IO流与网络编程-RandomAccessFile实现数据的插入
P618 616.尚硅谷_IO流与网络编程-NIO介绍及NIO2中Path、Paths、Files的介绍

3.所学内容概述

了解缓冲流 实现复制文本 和字节型和字符流比较读写速度

转换流概述和实现键盘输入输出

打印流和数据流的使用 对象的序列化理解操作

serialVersionUID的使用 自定义可序列化的要求

RandomAccessFile实现数据的读写操作 NIO理解

4、根据概述分章节描述

缓冲流

利用缓冲流能大大缩短程序的运行时间

image-20220507235313841

缓冲字节流

图片

**BufferedInputStream、BufferedOutputStream**

image-20220507230615077

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 void BufferedCopyMp4Secret(){

//造缓存流
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream("cxy1.jpg"));
bos = new BufferedOutputStream(new FileOutputStream("cxy2.jpg"));
byte[] bytes = new byte[20];
int len;
while ((len = bis.read(bytes)) != -1){

for (int i = 0; i < len;i++){
bytes[i] = (byte) (bytes[i] ^ 5);
}

bos.write(bytes,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
assert bis != null;
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
assert bos != null;
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

缓冲字节流是为高效率而设计的,真正的读写操作还是靠FileOutputStreamFileInputStream,所以其构造方法入参是这两个类的对象也就不奇怪了。

缓冲字符流

字符流适用于文本文件的读写OutputStreamWriter类其实也是借助FileOutputStream类实现的,故其构造方法是FileOutputStream的对象

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
@Test
public void BufferedCopyTxt (){
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader("hello.txt"));
bw = new BufferedWriter(new FileWriter("hello2.txt"));
//老方式一
// char[] chars = new char[1024];
// int len;
// while ((len = br.read(chars)) != -1){
// bw.write(chars,0,len);
// }
String data; //字符型 方式二
while ((data = br.readLine()) != null){
bw.write(data); //data没有换行符
bw.newLine(); //换行
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
assert br != null;
br.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
assert bw != null;
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

转换流

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class InOutStreamReaderTest {
@Test
public void test1() throws Exception {
//将UTF-8编码文件复制 并转换为gbk
InputStreamReader isr = new InputStreamReader(new FileInputStream("hello_gbk.txt"),"gbk");
OutputStreamWriter isw = new OutputStreamWriter(new FileOutputStream("hello_utf.txt"));

char[] chars = new char[20];
int len;
while ((len = isr.read(chars)) != -1){
isw.write(chars,0,len);
}

isr.close();
isw.close();


}
}

对象流

对象输出流(写)

1.ObjectOutputStream

提供了writeObject(object obj);oos将对象转换为字节后 将这组字节交给fos写入文本等于写到硬盘, 这个过程称之为“数据持久化”; oos将给定的对象pdd转为一组字节,这个过image-20220508001715638程称之为“对象序列化”;简单来讲“对象序列化”就是将对象写入文本中,称之为对象"序列化".

2.serializable接口:

objectOutputstream在对象进行序列化时有个要求:需要序列化对象所属的类。必须是实现serializable接口,实现该接口不需要重写任何方法,目的是可序化的一种标识。

每一个类序列化都要实例化接口

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
public class person implements Serializable {
public static final long serialVersionUID = 2314124125L;
private String name;
private int age;
private Acct id;

public person() {
}

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

public person(String name, int age, Acct id) {
this.name = name;
this.age = age;
this.id = id;
}

@Override
public String toString() {
return "person{" +
"name='" + name + '\'' +
", age=" + age +
", id=" + id +
'}';
}
}
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
import java.io.Serializable;

/**
* @ClassName person
* @Description TODO
* @Author CC
* @DATE 2022/5/6 14:43
* @Version 1.0
*/

public class person implements Serializable {
public static final long serialVersionUID = 2314124125L;
private String name;
private int age;
private Acct id;

public person() {
}

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

public person(String name, int age, Acct id) {
this.name = name;
this.age = age;
this.id = id;
}

@Override
public String toString() {
return "person{" +
"name='" + name + '\'' +
", age=" + age +
", id=" + id +
'}';
}
}


class Acct implements Serializable{
public static final long serialVersionUID = 2314124125L;

private double id;

public Acct() {
}

public Acct(double id) {
this.id = id;
}

@Override
public String toString() {
return "Acct{" +
"id=" + id +
'}';
}
}
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
    //
@Test
public void test1(){
//创建person对象
ObjectOutputStream oos = null;
try {
//实例化一个需要序列化的Person对象
oos = new ObjectOutputStream(new FileOutputStream("object.dat"));
oos.writeObject(new String("我是无敌的"));
oos.flush();


person p = new person("汪大东",28);
oos.writeObject(p);
oos.flush();

oos.writeObject(new person("金宝三",34,new Acct(153)));
oos.flush();

} catch (IOException e) {
e.printStackTrace();
} finally {
try {
assert oos != null;
oos.close();
} catch (IOException e) {
e.printStackTrace();
}

}
}
//反序列化
@Test
public void test2(){
ObjectInputStream ois = null;
try {
ois = new ObjectInputStream(new FileInputStream("object.dat"));
Object obj = ois.readObject();

String str = (String)obj;

person p1 = (person) ois.readObject();
person p2 = (person) ois.readObject();
System.out.println(str);
System.out.println(p1);
System.out.println(p2);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
} finally {
try {
assert ois != null;
ois.close();
} catch (IOException e) {
e.printStackTrace();
}

}
}
}

RandomAccessFilee类

既可以做输入流也看可以做输出流

image-20220508001715638

5.章节内容 难点

章节内容(节标题,重点),难点(比较难理解的内容和较容易出错部分,关键代码或关键配置,BUG截图+解决方案)

重点

IO流重点类

InputStream:InputStream是所有字节输入流的抽象基类,前面说过抽象类不能被实例化,实际上是作为模板而存在的,为所有实现类定义了处理输入流的方法。
FileInputSream:文件输入流,一个非常重要的字节输入流,用于对文件进行读取操作。
PipedInputStream:管道字节输入流,能实现多线程间的管道通信。
ByteArrayInputStream:字节数组输入流,从字节数组(byte[])中进行以字节为单位的读取,也就是将资源文件都以字节的形式存入到该类中的字节数组中去。
FilterInputStream:装饰者类,具体的装饰者继承该类,这些类都是处理类,作用是对节点类进行封装,实现一些特殊功能。
DataInputStream:数据输入流,它是用来装饰其它输入流,作用是“允许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型”。
BufferedInputStream:缓冲流,对节点流进行装饰,内部会有一个缓存区,用来存放字节,每次都是将缓存区存满然后发送,而不是一个字节或两个字节这样发送,效率更高。
ObjectInputStream:对象输入流,用来提供对基本数据或对象的持久存储。通俗点说,也就是能直接传输对象,通常应用在反序列化中。它也是一种处理流,构造器的入参是一个InputStream的实例对象。

BUG1

空指针异常,提醒在34行,反复检查代码,发现,刚开始是集合没有key值的,所以调用getValue也就是会得到一个null,将0改成null,代码就没事情了

img

BUG2

一直显示无法转换,不知道什么原因,把文件删除以后,再次创造,再获取就没异常了,不知道什么原因

img

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
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
 @Test
public void test1(){
//统计每个文字出现的次数 ,map
//缓存流
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader("hello.txt"));
//创建map集合
Map<Character,Integer> map = new LinkedHashMap<>();
int len;

while ((len = br.read()) != -1){ //读取数据

char char1 = (char) len;//转换
//放入map
if (map.get(char1) == null) {//刚开始是没有的 返回的是null
map.put(char1, 1);
}else {
map.put(char1,map.get(char1) + 1);
}
}
//把map的数据都方法哦文件count.txt中
//创建写入缓存流
bw = new BufferedWriter(new FileWriter("helloCount.txt"));
Set<Map.Entry<Character, Integer>> entrySet = map.entrySet();
for (Map.Entry<Character, Integer> entry : entrySet){
switch (entry.getKey()){
case ' ':
bw.write("空格 = " + entry.getValue());
break;
case '\t':
bw.write("tab键 = " + entry.getValue());
break;
case '\r':
bw.write("回车 = " + entry.getValue());
break;
case '\n':
bw.write("换行 = " + entry.getValue());
break;
default:
bw.write(entry.getKey() + " = " + entry.getValue());
break;
}
bw.newLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bw != null) {
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

解密 加密

在创建的时候名字换过来、 就是解密

将加密文件为输入流

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
@Test
public void BufferedCopyMp4Secret2(){
//解密

//造缓存流
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
bis = new BufferedInputStream(new FileInputStream("cxy2.jpg"));
bos = new BufferedOutputStream(new FileOutputStream("cxy4.jpg"));
byte[] bytes = new byte[20];
int len;
while ((len = bis.read(bytes)) != -1){

for (int i = 0; i < len;i++){
bytes[i] = (byte) (bytes[i] ^ 5);
}

bos.write(bytes,0,len);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
assert bis != null;
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
assert bos != null;
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

字符转换流

打印单词 大写输出

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
public class InUp {
public static void main(String[] args) {
test1();

}
public static void test1(){
BufferedReader br = null;
try {
System.out.print("请输入你要转换的单词 : ");
br = new BufferedReader(new InputStreamReader(System.in));
while (true){
String data = br.readLine();
if ("e".equalsIgnoreCase(data) || "exit".equalsIgnoreCase(data)){
System.out.println("程序结束");
break;
}
System.out.println(data.toUpperCase());

}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
assert br != null;
br.close();
} catch (IOException e) {
e.printStackTrace();
}

}

}
}

7.总结

重点是哪些知识比较重要,难点是你在学习过程中觉得比较繁琐,掌握起来有一点

学习难度较难,今天的学习内容比较多,IO流的案例大多都是copy,先学了缓冲流,能大大提高字节流的效率,这应该也是以后比较常用的流,然后转换流和对象流,转换流可以键盘输入输出,主要用于编码的修改,对象流有点难度,序列化的类中的seversionUID不太好理解,周末再看看博客。了解用处,和适用场景。今天的代码量比较多,然后出了两个不太严重的BUG,学习效率不错。

5.9 网络编程 反射

1.头:日期、所学内容出处

https://www.bilibili.com/video/BV1Kb411W75N?p=405

2.标题

P620 618.尚硅谷_IO流与网络编程-网络编程概述
P621 619.尚硅谷_IO流与网络编程-IP的理解与InetAddress类的实例化
P622 620.尚硅谷_IO流与网络编程-端口号的理解
P623 621.尚硅谷_IO流与网络编程-TCP和UDP网络通信协议的对比
P624 622.尚硅谷_IO流与网络编程-TCP网络编程例题1
P625 623.尚硅谷_IO流与网络编程-TCP网络编程例题2
P626 624.尚硅谷_IO流与网络编程-TCP网络编程例题3
P627 625.尚硅谷_IO流与网络编程-浏览器访问Tomcat服务器资源操作
P628 626.尚硅谷_IO流与网络编程-UDP网络编程举例
P629 627.尚硅谷_IO流与网络编程-URL类的理解与实例化
P630 628.尚硅谷_IO流与网络编程-URL网络编程实现Tomcat服务端数据下载
P631 629.尚硅谷_反射-每天一考

3.所学内容概述

InetAddree类的实例化和基本方法

网络通讯TCP和UDP ip 端口号理解

TCP通讯 传文件

UDP通讯

URL浏览器 下载服务器

4、根据概述分章节描述

通讯的要素

image-20220509082517251

InetAddress的实例化方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class InetAddresseeTest {
public static void main(String[] args) throws Exception {
InetAddress ip = InetAddress.getByName("192.168.10.14");
System.out.println(ip);
System.out.print("本机ip地址 : ");
System.out.println(InetAddress.getLocalHost());
InetAddress ip1 = InetAddress.getByName("www.baidu.com");
System.out.println(ip1);
System.out.println();
InetSocketAddress inetSocketAddress = new InetSocketAddress("127.0.0.1",8082);
System.out.println(inetSocketAddress);
//返回主机名
System.out.println(inetSocketAddress.getHostName());
//获得InetSocketAddress的端口
System.out.println(inetSocketAddress.getPort());
//返回一个InetAddress对象(IP对象)
InetAddress address = inetSocketAddress.getAddress();
System.out.println(address);
}
}

本地ip和端口 设置IP端口

image-20220509082135570

TCP和UDP协议

image-20220509112537988

UDP网络编程

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
public class UdpTest {
public static void main(String[] args) throws IOException {
DatagramSocket socket = new DatagramSocket();
Scanner scanner = new Scanner(System.in);
byte[] bytes = scanner.next().getBytes();
DatagramPacket packet = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("192.168.56.1"),8081);
socket.send(packet);
socket.close();
}
@Test
public void sender() throws Exception{
DatagramSocket socket = new DatagramSocket();
String scanner = "我是无敌暴龙兽";
byte[] bytes = scanner.getBytes();
DatagramPacket packet = new DatagramPacket(bytes,bytes.length, InetAddress.getByName("127.0.0.1"),8081);
socket.send(packet);
socket.close();

}
@Test
public void receiver() throws IOException{
DatagramSocket socket = new DatagramSocket(8081);
byte[] bytes = new byte[100];
DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length);

socket.receive(packet);
System.out.println(new String(packet.getData(),0,packet.getLength()));


}
}

URL网页下载图片

URL实现Tomcat网络下载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class UrlTest {
public static void main(String[] args) throws Exception{
URL url = new URL("https://i2.hdslb.com/bfs/archive/9c1780a14371ae4866e5f62d2b73d563a971e198.jpg@672w_378h_1c.webp");
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
InputStream is = urlConnection.getInputStream();
FileOutputStream fileOutputStream = new FileOutputStream("day33\\person.jpg");

byte[] bytes = new byte[1024];
int len;
while ((len = is.read(bytes)) != -1){
fileOutputStream.write(bytes,0,len);
}
urlConnection.disconnect();
is.close();
fileOutputStream.close();

}
}

image-20220509110756799

5.章节内容 难点

章节内容(节标题,重点),难点(比较难理解的内容和较容易出错部分,关键代码或关键配置,BUG截图+解决方案)

TCP网络编程

tcp发送文件 并保存 服务器反馈给客户端

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
public class subject3Test {
//客户端发送文件给服务器 服务器保存到本地 并返回 发送成功 给客户端 关闭连接
@Test
public void client() throws Exception{
// 1.
Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),8081);
// 2.
OutputStream outputStream = socket.getOutputStream();
// 3.
FileInputStream fileInputStream = new FileInputStream("cxy1.jpg");
// 4.
byte[] bytes = new byte[1024];
int len;
while ((len = fileInputStream.read(bytes)) != -1){
outputStream.write(bytes,0,len);
}
socket.shutdownOutput();
//5.接受来自服务器端的数据 显示在控制台上
InputStream inputStream = socket.getInputStream();
byte[] bytes1 = new byte[1024];
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int len1;
while ((len1 = inputStream.read(bytes1)) != -1){
bos.write(bytes1,0,len1);
}
System.out.println(bos);
System.out.println("收到来自服务器 : " + socket.getInetAddress().getHostAddress());

//6.
inputStream.close();
bos.close();
socket.close();
outputStream.close();
fileInputStream.close();


}

@Test
public void server() throws Exception{
//1.
ServerSocket ss = new ServerSocket(8081);
//2.
Socket socket = ss.accept();
//3.
InputStream inputStream = socket.getInputStream();
//4.
FileOutputStream fis = new FileOutputStream("cxyCopy2.jpg");
//5.
byte[] bytes = new byte[1024];
int len;
while ((len = inputStream.read(bytes)) != -1){
fis.write(bytes,0,len);
}
//6.服务器给予客户端反馈
OutputStream outputStream = socket.getOutputStream();
outputStream.write("你好客户端 cxy照片已经收到".getBytes());


//7.close
socket.close();
ss.close();
inputStream.close();
fis.close();
outputStream.close();

}

}

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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
package java2;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class TcpTalkServer {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
//创建服务器对象
ServerSocket server = new ServerSocket(9999);
System.out.println("等待服务器响应");
//监听
Socket listen = server.accept();
System.out.println("服务器连接成功!");
//死循环
while (true){
//创建数据报
InputStream in = listen.getInputStream();
byte[] bytes = new byte[1024];
int len = in.read(bytes);
//接收消息
String recv = new String(bytes,0,len);
//打印消息
System.out.println("客户端: " + recv);

//发送消息
OutputStream out = listen.getOutputStream();
System.out.print("服务器: ");
String send = sc.next();
out.write(send.getBytes());
//关闭
/* out.close();
in.close();
ss.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
29
30
31
32
33
34
35
36
37
38
39
package java2;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;



public class TcpTalkClient {
public static void main(String[] args) throws IOException {
Scanner sc = new Scanner(System.in);
//创建客户端对象
Socket client = new Socket("127.0.0.1",9999);
//死循环
while (true){
//发送数据
OutputStream out = client.getOutputStream();
System.out.print("客户端: ");
String send = sc.next();
//out.write("Hello Server!!".getBytes());
out.write(send.getBytes());

//创建数据报
InputStream in = client.getInputStream();
byte[] bytes = new byte[1024];
int len = in.read(bytes);
//接受消息
String recv = new String(bytes,0,len);
//打印数据/消息
System.out.println("服务器: " + recv);
//关闭
/* in.close();
out.close();
client.close();*/
}
}
}

运行截图

img

img

1
缺点其实很显而易见,无法关闭通讯,而且只能一对一聊天,在python中有加入多任务的聊天,java肯定也可以,有空自己需要再 

7.总结

重点是哪些知识比较重要,难点是你在学习过程中觉得比较繁琐,掌握起来有一点

今天的学习任务不是很重,目标就是把IO流结束,并初步进入反射,网络编程比较简单,就是基础的TCP和UDP实现网络通信,基本都掌握了,TCP比较重要,自己也是敲了好几个不同作用的TCP聊天,自己做了一个实时聊天器,但是比较简单,只能实现一发一收,今天学习状态不错,也没出什么BUG。

5.10反射

1.头:日期、所学内容出处

https://www.bilibili.com/video/BV1Kb411W75N?p=405

2.标题

P636 634.尚硅谷_反射-反射的概述
P637 635.尚硅谷_反射-反射之前,类的实例化等操作
P638 636.尚硅谷_反射-使用反射,实现同上的操作
P639 637.尚硅谷_反射-反射的强大:调用类的私有结构
P640 638.尚硅谷_反射-如何看待反射和封装性两个技术
P641 639.尚硅谷_反射-Class类的理解
P642 640.尚硅谷_反射-获取Class实例的4种方式
P643 641.尚硅谷_反射-Class实例对应的结构的说明
P644 642.尚硅谷_反射-理解类的加载过程
P645 643.尚硅谷_反射-ClassLoader的理解
P646 644.尚硅谷_反射-使用ClassLoader加载配置文件
P647 645.尚硅谷_反射-通过反射,创建运行时类的对象
P648 646.尚硅谷_反射-举例体会反射的动态性
P649 647.尚硅谷_反射-提供结构丰富Person类
P650 648.尚硅谷_反射-获取运行时类的属性结构及其内部结构
P651 649.尚硅谷_反射-获取运行时类的方法结构
P652 650.尚硅谷_反射-获取运行时类的方法的内部结构
P653 651.尚硅谷_反射-获取运行时类的构造器结构
P654 652.尚硅谷_反射-获取运行时类的父类及父类的泛型
P655 653.尚硅谷_反射-获取运行时类的接口、所在包、注解等
P656 654.尚硅谷_反射-调用运行时类中的指定属性
P657 655.尚硅谷_反射-调用运行时类中的指定方法
P658 656.尚硅谷_反射-调用运行时类中的指定构造器
P659 657.尚硅谷_动态代理与Java8新特性-每天一考
P660 658.尚硅谷_动态代理与Java8新特性-复习:反射与Class
P661 659.尚硅谷_动态代理与Java8新特性-复习:ClassLoader与反射的应用
P662 660.尚硅谷_动态代理与Java8新特性-代理模式与动态代理
P663 660.尚硅谷_动态代理与Java8新特性-代理模式与动态代理
P664 662.尚硅谷_动态代理与Java8新特性-动态代理举例
P665 663.尚硅谷_动态代理与Java8新特性-AOP与动态代理的举例

3.所学内容概述

1.java反射机制概述

2.理解class类并获取class实例

3.类的加载与ClassLoader的理解

4.创建运行时类的对象

5.获取运行时类的完整结构

6.调用运行时类的指定结构

7.反射的应用动态代理

4、根据概述分章节描述

反射机制的概述

1
2
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.

获取Class实例

利用反射调用类
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
@Test
public void test2() throws Exception{
Class<person> clazz = person.class;
//1.通过反射创造person类的对象
Constructor<person> constructor = clazz.getConstructor(String.class,int.class);
person person = constructor.newInstance("Tom",12);
System.out.println(person);
//2.通过反射 调用对象指定的属性和方法
//调用属性
Field age = clazz.getDeclaredField("age");
age.set(person,10);
System.out.println(person);

//调用方法
Method show = clazz.getDeclaredMethod("show");
show.invoke(person);
System.out.println("=================================");

//通过反射 可以调用person类的私有的结构 私有的构造器 方法 属性
//调用私有构造器
Constructor<person> constructor1 = clazz.getDeclaredConstructor(String.class);
constructor1.setAccessible(true);
person person1 = constructor1.newInstance("Jerry");
System.out.println(person1);

//调用私有属性
Field name = clazz.getDeclaredField("name");
name.setAccessible(true);
name.set(person1,"LiHua");
System.out.println(person1);

//调用私有方法
Method showNation = clazz.getDeclaredMethod("showNation", String.class);
showNation.setAccessible(true);
String nation = (String) showNation.invoke(person1, "中国");
System.out.println(nation);
}

class实例化四种方式

第三种最重要

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
//获取class实例化的方式
@Test
public void test3() throws Exception {
//方式一 调用运行时类的属性
Class<person> personClass = person.class;
System.out.println(personClass);

//方式二 通过运行时类的对象,调用getClass()
person p1 = new person();
Class<? extends person> personClass1 = p1.getClass();
System.out.println(personClass1);


//方式三 调用Class的静态方法 forName(Sering classpath) 常用
Class<?> personClass2 = Class.forName("java1.person");
System.out.println(personClass2);

System.out.println(personClass == personClass2);
System.out.println(personClass2 == personClass1);
//方式四
ClassLoader classLoader = Reflection.class.getClassLoader();
Class<?> personClass3 = classLoader.loadClass("java1.person");
System.out.println(personClass3);
System.out.println(personClass3 == personClass);

//数组元素维度一样 就是同一个class
int[] a = new int[10];
int[] b = new int[100];
System.out.println(a.getClass() == b.getClass());
}

对class的理解

image-20220510172236894

ClassLoader的理解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Test
public void test(){

//自定义类 系统类加载
ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
System.out.println(classLoader);

//获取扩展类加载器 系统类加载器的getParent()
ClassLoader parent = classLoader.getParent();
System.out.println(parent);

//扩展类加载器的getParent() 无法获取引导类加载器
//引导类加载器 主要负责加载java的核心类库 无法加载自定义类
ClassLoader parent1 = parent.getParent();
System.out.println(parent1);

ClassLoader classLoader1 = String.class.getClassLoader();
System.out.println(classLoader1);
}

利用ClassLoader配置文件

注意两种方式路径是不一样的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Test
public void test2() throws Exception {
Properties pos = new Properties();

//此时的文件默认在当前的module下
//读取配置文件 方式一
// FileInputStream fis = new FileInputStream("jdbc.properties");
// pos.load(fis);

ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
InputStreamReader is = new InputStreamReader((Objects.requireNonNull(classLoader.getResourceAsStream("java1/jdbc1.properties"))), StandardCharsets.UTF_8);
pos.load(is);


String user = pos.getProperty("user");
String password = pos.getProperty("password");
System.out.println("user = " + user + ", password = " + password);
// fis.close();

}

创建运行时类的对象

1
2
3
4
5
调用newInstance()此方法 创建对应的运行时类的对象
调用空参构造器
要是想侧方法正常地创建运行时类的对象 要求
1.运行时类必须提供空参的构造器
2.空参的构造器的访问权限得够 通常设置为Public
1
2
3
4
5
6
@Test
public void test() throws Exception{
Class<person> personClass = person.class;
person person = personClass.newInstance();
System.out.println(person);
}

体会反射的动态性

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
@Test
public void test2(){
int num = new Random().nextInt(3); // 0 1 2
String s = "";
switch (num){
case 0:
s = "java.util.Date";
break;
case 1:
s = "java1.person";
break;
case 2:
s = "java.lang.Object";
break;
}
try {
System.out.println(getInstance(s));
} catch (Exception e) {
e.printStackTrace();
}

}
/*
创建一个指定类的对象
classpath : 指定类的全类名
*/
public Object getInstance(String classPath) throws Exception{
Class<?> objectClass = Class.forName(classPath);
return objectClass.newInstance();
}

获取运行时类完整的结构

博客 https://blog.csdn.net/qq_42653576/article/details/105335902?ops_request_misc=&request_id=&biz_id=102&utm_term=java反射运行时类&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-105335902.142^v9^pc_search_result_control_group,157^v4^control&spm=1018.2226.3001.4187

获取运行时类的方法和属性

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

import java2.person;
import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
* @ClassName ClassPersonTest
* @Description TODO
* @Author CC
* @DATE 2022/5/10 12:49
* @Version 1.0
*/

public class ClassPersonTest {

@Test
public void test() {
/*
1、取得类中的属性
public Field[] getFields()
返回此Class对象所表示的类或接口的public的Field。
public Field[] getDeclaredFields()
返回此Class对象所表示的类或接口的全部Field。
Field方法中:
public int getModifiers() 以整数形式返回此Field的修饰符
public Class<?> getType() 得到Field的属性类型
public String getName() 返回Field的名称。
*/
Class<person> clazz = person.class;
Field[] f1 = clazz.getFields();
for (Field f : f1) {
System.out.println(f);
}

System.out.println();

Field[] f2 = clazz.getDeclaredFields();
for (Field f : f2) {
System.out.println(f);
}

System.out.println();

for (Field f : f2) {
//权限修饰符
int modifier = f.getModifiers();
System.out.println(Modifier.toString(modifier));
//数据类型
Class<?> type = f.getType();
System.out.println(type.getName());
//变量名
String fName = f.getName();
System.out.println(fName);
System.out.println();
}
}

@Test
public void test2() {
Class<?> clazz = person.class;
Method[] method = clazz.getDeclaredMethods();
for (Method m : method) {
// System.out.println(m);
//1.获取方法声明中的注解
Annotation[] annotations = m.getAnnotations();
for (Annotation a : annotations) {
System.out.print(a + "\t");
}

//2.方法的权限修饰符
System.out.print(Modifier.toString(m.getModifiers()) + "\t");

//3.方法的返回值类型
System.out.print(m.getReturnType() + "\t");

//4.方法的方法名
System.out.print(m.getName() + "\t");

//5.方法的参数
System.out.print("(");
Class<?>[] p = m.getParameterTypes();
if (p.length != 0) {
for (int i = 0; i < p.length; i++) {
if (i == p.length - 1) {
System.out.print(p[i].getName());
break;
}
System.out.print(p[i].getName() + ",");
}
}
System.out.print(")");

//6.异常
System.out.print("[");
Class<?>[] e = m.getExceptionTypes();
if (e.length > 0) {
for (int i = 0; i < e.length; i++) {
if (i == e.length - 1) {
System.out.print(e[i].getName());
break;
}
System.out.print(e[i].getName() + ",");
}

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

如何调用静态方法

image-20220510152612168

5.章节内容 难点

章节内容(节标题,重点),难点(比较难理解的内容和较容易出错部分,关键代码或关键配置,BUG截图+解决方案)

重点

调用运行时类的指定结构

属性

1
2
3
4
5
6
7
8
9
10
11
12
Class<person> clazz = person.class;
//创建运行时类对象
person person = clazz.newInstance();
//获取指定的属性
Field id = clazz.getField("id");
id.set(person,1001);
System.out.println(id.get(person));

Field name = clazz.getDeclaredField("name");
name.setAccessible(true);
name.set(person,"Tom");
System.out.println(name.get(person));

方法

1
2
3
4
5
6
7
8
Class<person> clazz = person.class;
//创建运行时类对象
person person = clazz.newInstance();
//获取指定方法
Method show = clazz.getDeclaredMethod("show", String.class, int.class);
show.setAccessible(true);
Object invoke = show.invoke(person, "中国", 32);
System.out.println(invoke);

构造器

1
2
3
4
5
6
7
8
9
//构造器
Class<person> clazz = person.class;
Constructor<person> declaredConstructor = clazz.getDeclaredConstructor(String.class);
//保证可访问的
declaredConstructor.setAccessible(true);

//创建运行时类的对象
person person = declaredConstructor.newInstance("Tom");
System.out.println(person);

BUG

读取配置文件的时候报错,空指针异常,查看博客,发现如果用ClassLoader的路径是本包下,应该在src或者src中的包中,不然找不到文件,和FileInputStream输入流不一样。

img

6.扩展学习部分

中文乱码问题 输入流调编码格式

image-20220510102150119

1
2
3
4
5
6
7
8
9
冷静下来后,突然想起来,还是初学java时看过,java.io包中 Reader/Writer和Stream的区别。
(年代久远,具体细节忘记了,大概是:Reader/Write是处理编码文本的,而InputStream/OutputStream只把数据当作2进制流 )

正确解决方案

Properties prop=new Properties();
prop.load(new InputStreamReader(Client.class.getClassLoader().getResourceAsStream("config.properties"), "UTF-8"));

其中“UTF-8”,用于明确指定.properties文件的编码格式(不指定则默认使用OS的,这会造成同一份配置文件同一份代码,在linux和windows上、英文windows和中文windows之间的表现都不一致),这个参数应该和具体读取的properties文件的格式匹配。

image-20220510102511677

反射的问题

关于反射的一些问题:
说了这么多,那么通过直接new的方式或反射的方式都可以调用公共的结构,开发中用哪个?
这里建议是用new的方法的。

那么如何看待反射机制和面向对象中的封装性?
首先,封装,是将具体的实现细节隐藏,而把功能作为整体提供给类的外部使用,也就是说,公有方法能够完成类所具有的功能。当别人使用这个类时,如果通过反射直接调用私有方法,可能根本实现不了类的功能,甚至可能会出错,因此通过反射调用私有方法可以说是没有任何用处的,开发人员没有必要故意去破坏封装好的类。从这点上看,封装性并没有被破坏。

7.总结

重点是哪些知识比较重要,难点是你在学习过程中觉得比较繁琐,掌握起来有一点

​ 今天学习了反射的知识,花了一天的时间,将反射过掉了,学习内容比较多,而且反射中概念的问题比较难以理解,掌握程度80%,代码基本都会使用了,概念还是有点模糊,等到后面使用到反射,再回头熟悉熟悉。今天敲的代码不是很多,也比较简单,多敲几遍,加上IDEA的联想功能,使用起来也方便。很大的BUG没有,有一个路径问题,一个编码的问题。

5.13 java8新特性和动态代理

1.头:日期、所学内容出处

https://www.bilibili.com/video/BV1Kb411W75N?p=405

2.标题

P666 664.尚硅谷_动态代理与Java8新特性-Java8新特性内容概述
P667 665.尚硅谷_动态代理与Java8新特性-Java8新特性的好处
P668 666.尚硅谷_动态代理与Java8新特性-Lambda表达式使用举例
P669 667.尚硅谷_动态代理与Java8新特性-Lambda表达式语法的使用1
P670 668.尚硅谷_动态代理与Java8新特性-Lambda表达式语法的使用2
P671 669.尚硅谷_动态代理与Java8新特性-函数式接口的介绍
P672 670.尚硅谷_动态代理与Java8新特性-Java内置的函数式接口介绍及使用举例P673 671.尚硅谷_动态代理与Java8新特性-方法引用的使用情况1
P674 672.尚硅谷_动态代理与Java8新特性-方法引用的使用情况2
P675 673.尚硅谷_动态代理与Java8新特性-方法引用的使用情况3
P676 674.尚硅谷_动态代理与Java8新特性-构造器引用与项目引用的使用
P677 675.尚硅谷_动态代理与Java8新特性-Stream API的概述
P678 676.尚硅谷_动态代理与Java8新特性-Stream的实例化
P679 677.尚硅谷_动态代理与Java8新特性-Stream的中间操作:筛选与切片
P680 678.尚硅谷_动态代理与Java8新特性-Stream的中间操作:映射
P681 679.尚硅谷_动态代理与Java8新特性-Stream的中间操作:排序
P682 680.尚硅谷_动态代理与Java8新特性-Stream的终止操作:匹配与查找
P683 681.尚硅谷_动态代理与Java8新特性-Stream的终止操作:归约
P684 682.尚硅谷_动态代理与Java8新特性-Stream的终止操作:收集
P685 683.尚硅谷_动态代理与Java8新特性-Optional类的介绍
P686 684.尚硅谷_动态代理与Java8新特性-Optional类的使用举例

3.所学内容概述

反射的动态代理

java8新特性

lambda表达式

函数Functional接口

方法引用与构造器引用

强大的Stream API

Optional类

4、根据概述分章节描述

反射的动态代理

博客地址http://t.csdn.cn/0XKew

讲动态代理之前,首先用静态代理做个铺垫。
假设有一个Boy类继承自Person接口,接口里有一个方法print,现在有一个需求是不改变Boy类的情况下,在每次调用Boy的print方法前后各输出一句话。

静态代理

使用静态代理解决这个问题:
首先定义一个代理类BProxy也继承Person接口,并且在代理类中添加一个Person属性。实现print方法时,我们需要调用person对象的print方法,并且在调用前后各输出一句话,这样需要调用Boy的print方法时,只需要new一个BProxy代理类来调用print方法就可以间接的调用到了。

动态代理实现

还是用之前举例的Boy对象和Person接口,需要通过动态代理获取一个Boy的代理对象。
首先介绍需要用到的jdk提供的Proxy类和InvocationHandler接口。
Proxy可以帮我构造任何类(但是这个类必须是实现了某个接口)的代理类。
Proxy提供了一个newProxyInstance的静态方法,通过此方法可以返回任意对象的代理对象:

1
2
3
4
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)

这个方法有三个参数,第一个为需要被代理类的类加载器,这个可以通过反射获取,第二个参数是被代理类实现的接口数组,这个也可以通过反射获取,所以jdk动态代理前提是被代理类必须实现了某些接口。第三个参数为InvocationHandler对象,他相当于是被代理对象的一个封装类。下面详细介绍InvocationHandler这个接口类。
我们定义一个WanNengProxy类来实现这个接口类,需要实现一个invoke方法,当我们调用万能代理类的所有方法时,万能代理类都会通过调用invoke方法来调用被代理类的方法。在invoke方法中可以通过反射来调用我们实际需要调用的方法,然后就在调用前后就可以输出一句话了。

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.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
* @ClassName boyProxyTest
* @Description TODO
* @Author CC
* @DATE 2022/5/13 8:44
* @Version 1.0
*/
interface person {
void print();
}
//被代理类
class boyTest implements person{
@Override
public void print() {
System.out.println("我是一个小男孩");
}
}


//动态代理类
class proxyBoy implements InvocationHandler {
private final Object obj; //赋值时 需要使被代理类的对象赋值

public proxyBoy(Object obj) {
this.obj = obj;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

System.out.println("---before");
//实际调用方法 反射实现的
//将被代理类要执行的方法a的功能声明在invoke中
Object result = method.invoke(obj,args);

System.out.println("--after");
return result;//返回被代理类方法
}
}

public class boyProxyTest {
public static void main(String[] args) {
boyTest boyTest = new boyTest(); //boyTest被代理类对象
InvocationHandler handler = new proxyBoy(boyTest); //代理类对象

person boyProxy = (person) Proxy.newProxyInstance(boyTest.class.getClassLoader(),boyTest.class.getInterfaces(),handler);

boyProxy.print(); //代理类对象执行的
}
}

java 8的新特性

java 8是java 5一来最具革命性的版本 java 8给java语言、编译器、类库、开发工具与JVM带来了大量的新特性.

image-20220513102142786

lambda表达式的使用

举例

1
2
3
4
5
6
7
//lambda表达式的写法
Comparator<Integer> comparator = (o1,o2) -> Integer.compare(o1,o2);
System.out.println(comparator.compare(32,21));

// 方法引用
Comparator<Integer> comparator1 = Integer :: compare;
System.out.println(comparator1.compare(19,29));
1
2
3
4
格式
-> : lambda操作符 或 箭头操作符
->左边 : lambda形参列表(其实就是接口中的抽象方法的形参列表)
->右边 : lambda体(其实就是重写的抽象方法的方法体)

lambda表达式的实例 接口的对象

lambda表达式的使用(分六种情况介绍)
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
package lambdaTest;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.net.Socket;
import java.util.Comparator;
import java.util.function.Consumer;

/**
* @ClassName LambdaTest1
* @Description TODO
* @Author CC
* @DATE 2022/5/13 10:52
* @Version 1.0
*/

public class LambdaTest1 {
//语法格式一 : 无参,无返回值
@Test
public void test1(){
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("我就是终极一班");
}
};
r1.run();
Runnable r2 = () -> System.out.println("Lambda:我就是终极一班");
r2.run();
}
//语法格式二 lambda需要一个参数 但是没有返回值
@Test
public void test2(){
Consumer<String> consumer = new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
};
consumer.accept("谎言真的都是坏的吗?");
System.out.println("============================");
Consumer<String> consumer1 = (String s) -> System.out.println(s);
consumer1.accept("不一定 也有善意的");
}
//语法格式三 数据类型可以省略 因为可由编译器推断得去 称为 "类型推断”
@Test
public void test3(){
Consumer<String> consumer1 = (s) -> System.out.println(s);
consumer1.accept("不一定 也有善意的");
}
// 语法格式四 lambda只有一个参数 参数小括号可以省略
@Test
public void test4(){
Consumer<String> consumer1 = s -> System.out.println(s);
consumer1.accept("不一定 也有善意的");
}

//语法格式五 lambda需要两个或以上的参数 多条执行语句 并且可以有返回值
@Test
public void test5(){
Comparator<Integer> comparator = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
System.out.println(o1);
System.out.println(o2);
return o1.compareTo(o2);
}
};
System.out.println(comparator.compare(12,6));
Comparator<Integer> comparator2 = (o1, o2) -> {System.out.println(o1);
System.out.println(o2);
return o1.compareTo(o2);
};
System.out.println(comparator2.compare(3,56));
}
//语法格式六 当lambda提只有一条执行语句 return和大括号若有 省略
@Test
public void test6(){
Comparator<Integer> comparator = (o1,o2) -> o1.compareTo(o2);
System.out.println(comparator.compare(23, 4));
}
}

总结

image-20220513150936602

函数式接口

如果一个接口 只声明了一个抽象方法 就是函数式接口

如何理解

image-20220513151356455

方法引用的使用情况

http://t.csdn.cn/Pf5Zh详细博客地址

image-20220514124130616

好处代码更加简洁,但是我觉得可读性会变差。

5.章节内容 难点

章节内容(节标题,重点),难点(比较难理解的内容和较容易出错部分,关键代码或关键配置,BUG截图+解决方案)

强大的Stream API

Optional类

解决空指针问题

image-20220514184716265

Optional容器类的常用方法

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
    /**
* Optional容器类的常用方法:
* Optional.of(T t):创建一个Optional实例
* Optional.empty():创建一个空的Optional实例
* Optional.ofNullable(T t):若t不为null,创建Optional实列,否则创建空实例
* isPresent():判断是否包含值
* orElse(T t):如果调用对象包含值,返回该值,否则返回t
* orElseGet(Supplier s):如果调用对象包含值,返回该值,否则返回s获取的值
* map(Function f):如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
* flatMap(Function mapper):与map类似,要求返回值必须是Optional
*/
@Test
public void test1() {
Optional<Employee> op = Optional.of(new Employee());
Employee emp = op.get();
System.out.println(emp);
}

@Test
public void test2() {
Optional<Employee> op = Optional.empty();
System.out.println(op.get());
}

@Test
public void test3() {
// Optional<Employee> op = Optional.ofNullable(new Employee());
Optional<Employee> op = Optional.ofNullable(null); //不能传null
if (op.isPresent()) {
System.out.println(op.get());
// System.out.println(op1.get());
}
System.out.println("-------------------------------------------------------");
Employee emp = op.orElse(new Employee("zhangsan", 18, 888.88, Employee.Status.FREE));
System.out.println(emp);
System.out.println("-------------------------------------------------------");
Employee emp1 = op.orElseGet(() -> new Employee());
System.out.println(emp1);
}

@Test
public void test4() {
Optional<Employee> op = Optional.ofNullable(new Employee("zhangsan", 18, 888.88, Employee.Status.FREE));
// Optional<String> s = op.map((e) -> e.getName());
// System.out.println(s.get());
//多一步判空
Optional<String> s = op.flatMap((e) -> Optional.of(e.getName()));
System.out.println(s.get());

}

@Test
public void test5() {
Man man = new Man();
String name = getGodnessName(man);
System.out.println(name);

}

//需求:获取男生心中女神的名字
public String getGodnessName(Man man) {
// return man.getGoddness().getName();
if (man != null) {
Godness gn = man.getGoddness();
if (gn != null) {
return gn.getName();
}
}
return "小花";
}

public String getGodnessName2(Optional<NewMan> man) {
return man.orElse(new NewMan())
.getGodness()
.orElse(new Godness("小花花"))
.getName();
}

@Test
public void test6(){
Optional<Godness> gn = Optional.ofNullable(new Godness("小红"));
Optional<NewMan> op = Optional.ofNullable(new NewMan(gn));
// Optional<Godness> gn = Optional.ofNullable(null);
// Optional<NewMan> op = Optional.ofNullable(null);
String str = getGodnessName2(op);
System.out.println(str);

}

6.扩展学习部分

Python随机杯的排序

按名字排序 然后是年龄 学号

放在一个二维数组中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
t1 = ('Tom',19,80)
t2 = ('John',20,90)
t3 = ('Jony',17,91)
t4 = ('Jony',17,93)
t5 = ('Json',21,85)
list = []
list.append(t1)
list.append(t2)
list.append(t3)
list.append(t4)
list.append(t5)
for i in range(4):
for j in range(i+1,6):
for z in range(3):
if list[i][z] > list[j][z]:
list[i],list[j] = list[j],list[i]
break
elif list[i][z]<list[j][z]:
break
print(list)

利用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
class User{
private final String name;
private final int age;
private final int id;
public User(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}

public int getId() {
return id;
}

@Override
public String toString() {
return "[" + name +", " + age +", " + id +"]";
}
}
@Test
public void test(){
Comparator<User> comparator = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof User && o2 instanceof User){
User u1 = (User)o1;
User u2 = (User)o2;
int com = u1.getName().compareTo(u2.getName());
if (com != 0){
return com;
}else {
int intcom = Integer.compare(u1.getAge(), u2.getAge());
if (intcom != 0){
return intcom;
}else {
return Integer.compare(u1.getId(), u2.getId());
}
}
}else {
throw new RuntimeException("类型不匹配");
}
}
};
TreeSet<User> List1 = new TreeSet<>(comparator);
List1.add(new User("Tom",19,80));
List1.add(new User("John",20,90));
List1.add(new User("Jony",17,91));
List1.add(new User("Jony",17,93));
List1.add(new User("Json",21,85));
System.out.println(List1);


}

7.总结

重点是哪些知识比较重要,难点是你在学习过程中觉得比较繁琐,掌握起来有一点

今天学了java8的新特性,因为目前开发主流的还是java8,所以就只看到了java8的新特性,java高级也学完了。今天的学习内容有点难度,lambda和方法引用,两个简写代码量的方式,但是不太好理解,实际使用还没有那么成熟,代码敲了八九遍,想要顺便使用还是有点不熟练的,看博客有多点的心理体会,今天学了一上午,下午因为精神不太好,基本没看进去,学习状态一般吧。