反函数的定义:简单理解就是只有一个x0与y0与之对应。所以不是所有函数都有反函数,如果一个y0有多个x0与他对应,那就要做定义域限制才能有反函数。image-20230306234433540

image-20230306234214970

反函数的用法:把x和y进行调换,然后乘的变除,除的变乘,类推。

比如y=2x,它的反函数就是:x除以2,也就是y=2/1x

image-20230306233924194

反函数的图像与原函数的图像呈对称。

Java学习笔记

数组

数组的声明

1
2
3
4
5
6
7
8
9
10
11
12
13
int [] arr = new int[3];
/*
左边:
int:说明数组中的元素类型是int
[]:说明这是一个数组
arr:数组名称
右边:
new:为当前数组申请内存空间
int:说明数组中的元素类型是int
[]:说明这是一个数组
3:数组长度,数组中的元素个数


数组的访问形式

1
2
arr[0]
//数组的访问从0开始,如果不跟数组名后面不跟[]输出的就是arr的内存地址。

内存分配

栈内存:存取局部变量;也就是new等号旁边的内容(左边);定义在方法中的变量,使用完毕,立即消失。

堆内存:储蓄new出来的内容(实体,对象),数组在初始化时,会自动添加默认值。

整数:0
浮点数:0.0
布尔:false
字符:空字符
引用数据类型:null

为什么java需要new才能使用数组?
答案:java数组是一种引用对象,引用对象都在内存堆里,所以需要开辟内存空间。

多个数组指向相同

1
2
3
int[] arr = new int[3];
int[] arr2 = arr;
//此时数组arr和arr2的内存地址是相同的,也就是说修改arr2对象的实体等同于修改arr的实体。

数组的静态初始化

1
int[] arr = {1,2,3}

方法

什么是方法

由独立功能的代码块组织成为一个整体,使其具有特殊功能的代码及。
方法定义:要想使用方法就必须要先创建方法。
方法调用:方法创建后并不是自动运行的,而是需要手动使用才能执行,所以该过程被称为方法调用。

方法定义

1
2
3
public static void 方法名(){
//方法体
}

带参数方法定义

1
2
3
4
5
public static void 方法名(int number1,int number2){
}
/*其中括号里的int是数据类型,其次是变量名。
方法定义时,多个参数之间用逗号分隔8/

形参和实参

形参:方法定义中的参数
实参:方法调用中的参数

1
2
3
4
5
6
7
8
形参例子:
public static void test(int number){}
//括号里面的Int number就是形参
实参例子:
test(10);
//括号里面的数字10就是实参。
总结:
形参相当于名字,实参是具体的对象。

方法中:void表示无返回值,可以省略return,但是也可以写return,但是不加数据。

方法重载

什么是方法重载?

  1. 指多个方法在同一个类中
  2. 多个方法具有相同的方法名
  3. 多个方法参数不同,类型不同或者数量不同。

方法重载的特点:

  1. 方法重载仅对应方法的定义,与调用无关,调用方式参考标准格式。
  2. 方法重载仅针对同一个类中方法的名称与参数进行识别,与返回值无关,换句话说不能通过返回值来判定两个方法是否构成重载。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
错误的方法重载:
public class MethodDemo{
public static void fn(int a){}
public static int fn(int a){}
}
上面的代码块就不属于方法重载,因为方法重载与返回值无关。

错误的方法重载2
public class MethodDemo01{
public static void fn(int a){}
}
public class MethodDemo02{
public static int fn(int a){}
}
因为他们不在一个类里面所以不属于方法重载。


正确的方法重载1
public class MethodDemo{
public static void fn(int a){}
public static int fn(int b,int b){}
}
正确的方法重载2
public class MethodDemo{
public static void fn(int a){}
public static int fn(float b){}
}

方法参数传递之间的差异

对于引用类型的参数,形式参数的改变,影响实际参数的值。(这句话其实很好理解,因为数组是引用类型,而引用类型修改的是他的实体,也就是堆内存。)

而java的基本数据类型的参数是储蓄在栈内存里的,用完就消失了。

类和对象

类的定义

1
2
3
4
5
6
public class Phone{
String brand;
public static void call(){
System.out.println("i can call")
}
}

创建对象

1
2
3
Phone p = new Phone();
使用成员方法:
p.call()

成员变量和局部变量

区别 成员变量 局部变量
类中位置不同 类中方法外 方法内或者方法声明上
内存中位置不同 堆内存 栈内存
生命周期不同 随着对象的存在而存在,随着对象的消失而小时 随着方法的调用而存在,随着方法的调用而小时
初始化值不同 有默认的初始化值 没有默认的初始化值,必须先声明,然后才能使用

实例

1
2
3
4
5
6
7
8
public class two_tiger {
static int a;
public static void main(String[] args) {
System.out.println("a is "+ a);
}

//a为0

封装

private关键字

作用是保护成员不被别的类使用,被private修饰的成员只在本类中才能访问。
private修饰的成员变量如果需要被其他的类使用,需要提供get变量名()方法,用于获取值。方法用public修饰。如果需要设置成员变量的值,需要提供set变量名(参数)方法。同样需要public修饰。

this关键字

this修饰的变量用于指代成员变量。(堆内存)

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

在方法中没有用this修饰的变量是局部变量,用this修饰的是成员变量。也就是指到当前的类的堆变量。

封装

  1. 封装是对客观世界的模拟,把成员变量隐藏在对象内部,使得外界无法直接进行操作。
  2. 封装原则:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过指定的程序来访问,getXxx()/setXxx()方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public calss Student{
//封装的成员变量
private String name;
//提供给外部的访问方法
public String getName(){
return name;
}
private int age;
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
}

封装的好处:

  1. 提高了代码的安全性。
  2. 提高了代码的复用性。

API概述

API全称(Application Programming Interface)应用程序编程接口。

String 概述

String类在java.lang包下,所以使用的时候不需要手动导入。
Sring类代表字符串,所有的双引号字符串,都是String类的对象。

特点

字符串不可变,在创建后不能被更改。
虽然String的值不能变,但是他 们可以被共享。
字符串效果上相当于字符数组(char[]),但底层原理是字节数组(byte[])

String对象的特点

通过new创建的字符串对象,每次new都会申请一个新的内存空间,虽然内容相同,但是地址不同。

1
2
3
4
5
6
7
8
char[] chs = {'a','b','c'};
String s1 = new String(chs);
String s2 = new String(chs);
String s3 = "abc";
String s4 = "abc";
String s5 = "avs";
//其中S1与S2的内存地址不同,因为他们是通过new方法构造的。但是s3和s4的内存地址是一样的,因为他们的内容一样,所以java会将数据储蓄在常量池。s3,s4与s5内存地址不同。

字符串的比较

使用==做比较时
基本类型:比较的是数据值是否相同
引用类型:比较的是地址值是否相同

字符串是对象,比较的是他们的地址值,所以如果需要对字符串进行比较,需要通过equals()方法实现。

StringBuilder

如果使用String进行拼接,每次拼接都会构建一个新的String对象,浪费内存空间。StringBuilder类就是来解决这个问题的。

StringBuilder概述

一个可变的字符串类,可以把它看成一个容器。StringBuilder对象中的内容是可变的。(String内容是不可变的。)

StringBuilder与String之间的转换

正确使用方法

1
2
StringBuilder s = new StringBuilder();
Strign s2 = s.toString();

错误的做法

1
2
StringBuilder s = new StringBuilder();
Strign s2 = s;

集合

集合概述

储蓄多个数据,使用长度固定的数组不一定能满足我们的需求,更适应不了变化的要求。Java传统数组是引用类型,并且数组大小不可变。

1
2
3
4
5
6
7
8
9
10
11
//创建集合对象
ArrayList<Student> array = new ArrayList<Student>();
//创建学生对象
Student s1 = new Student(name,age);
//将学生对象添加到集合中
array.add(s1);
//使用遍历进行查看
for(int i=0;i<array.size();i++){
Student s = array.get(i);//array.get获取到的是Student的内存地址
System.out.println(s.getNmae());//输出名字
}

继承

继承概述

面向对象的三大特征之一。使得子类可以获得父类的属性和方法,还可以在子类中重新定义,追加。

继承的格式

1
public class 子类名 extends 父类名{}

父类也被称为:基类,超类
子类:也被称作派生类

小提示:Java中的return内容并不显示在控制台中,必须通过System.out.println()的方法。

继承的好处和弊端

好处:
1.提高了代码的复用性(多个类相同的成员可以放到同一个类中)
2.提高了代码的维护性(如果方法的代码需要修改,修改一处的即可)

弊端:
继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类也不得不变化,削弱了子类的独立性。

什么时候才应该使用继承?
1.继承体现的关系:is a

继承中变量访问的特点

当在子类中访问一个变量,java首先会在:

  1. 子类局部范围内寻找

  2. 子类成员范围内寻找

  3. 父类成员范围内寻找

  4. 如果都没有就报错,不考虑父类的父类

super

super用法跟this关键字相似。
this:表示本类对象引用
super:表示父类存储空间的表示(可以理解为父类对象引用)

1
2
3
4
5
6
7
8
9
10
11
public class Zi extends Fu {
int age = 18;
public void show(){
int age = 30;
System.out.println(age);//18
//访问子类的age
System.out.println(this.age);//30
//访问父类的age
System.out.println(super.age);//22
}
}

继承中构造方法的访问特点

子类所有的构造方法默认都会访问父类中无参的构造方法。

  1. 这是因为子类会继承父类中的数据,还会使用父类中的数据。所以在子类初始化之前,一定要对父类数据进行初始化。

  2. 每个子类构造方法中的第一条语句默认都是super。

  3. 如果父类中没有提供无参构造方法,指提供带参构造方法,第一,这时候我们应该通过super关键字去显示调用父类的带参构造方法。第二,我们可以再父类中自己提供一个无参构造方法。第二种方法比较推荐。

构造方法的特性

如果方法名与类名相同,那么在new的时候就会自动执行。

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

通过子类对象访问一个方法:

  1. 子类成员范围找

  2. 父类成员范围找

  3. 如果都没有就报错

方法重写

概述:当子类出现了和父类中一模一样的方法声明。
方法重写的应用:
当子类需要父类的功能,而功能主体子类有自己的特有内容时,可以重写父类中的方法,这样就沿袭了父类的功能,又定义了子类特有的功能。

在方法前添加

1
@Override

虽然加不加这个Override都没问题,但是最好还是加上去,因为它会帮我们检测我们的重写是否正确。

导包的概述和使用

使用不同包下的类时,使用时要写全类的全路径,为了简化操作,java提供了import。

import的用法

如果不在文件头进行引用也想要使用Scanner等别的包的功能,就需要指定完整的路径。

1
java.util.Scanner sc = new java.util.Scanner(System.in)

导包的格式

1
2
格式:import 包名
范例:import cn.itcast.Teacher

权限和修饰符

区别自行百度

static修饰符

是关键字是静态的意思,可以修饰成员方法,成员变量。

特点:被类的所有对象共享。这也是我们判断是否使用关键字的条件。被static修饰的变量可以通过类名访问,也可以通过对象名访问。但是并不推荐使用对象名调用,推荐使用类名调用。

比如在Student的类中大学这一变量被static修饰了,那在main方法中新构建一个学生一旦赋予了大学这一变量,之后的学生也都有这个大学的变量。

多态

多态概述

同一个对象,在不同时刻表现出来的不同形态
举例:猫 cat = new 猫();
也可以说猫是动物:动物 animal = new猫();
在这里猫在不同的时刻表现出来了不同的形态,这就是多态。

多态的前提和体现:

  1. 有继承/实现关系
  2. 有方法重写
  3. 有父类引用指向子类对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃东西!");
}
}

public class Animal {
public void eat(){
System.out.println("动物吃东西!");
}
}

public class AnimalDemo {
public static void main(String[] args) {
Animal a = new Cat();
a.eat();//猫吃东西!
}
}

多态中成员访问特点

成员变量:编译看左边,执行看左边
成员方法:编译看左边,执行看右边

为什么成员变量和成员方法的访问不一样呢?

因为成员方法有重写,而成员变量没有。

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 Animal {
public int age = 40;
public void eat(){
System.out.println("动物吃东西!");
}
}
public class Cat extends Animal{
public int age = 20;
public int weight = 10;
@Override
public void eat() {
System.out.println("猫吃东西!");
}
public void playGame(){
System.out.println("捉迷藏!");
}
}
public class AnimalDemo {

public static void main(String[] args) {
Animal a = new Cat();
a.playGame();//报错,因为Animal类里没有playGame方法
System.out.println(a.age);//这里输出的还是40;
System.out.println(a.weight);//报错,因为Animal类里面没有weight属性。
a.eat();//输出,猫吃鱼。
}
}

多态中的转型

向上转型:
从子到父
父类引用指向子类对象

向下转型:
从父到子,其实就是强转换
父类引用转为子类对象

1
2
3
4
5
6
7
8
9
10
11
12
13
public class AnimalDemo {

public static void main(String[] args) {
Animal a = new Cat(); //向上转型
a.eat();
//a.playGame();报错,因为animal类没有这个方法
//如果我们要使用playgame这个方法,我们可以创建Cat对象,但是这样子就会浪费内存的空间。
//向下转型 强制转换成子累对象
Cat c = (Cat)a;
c.eat();
c.playGame();
}
}

需要注意,假如狗和猫都继承至动物类,那么强行把狗转换成猫或者猫转换成狗就会出现转换类型报错。ClassCastException。

抽象类

抽象类概述

在Java中,一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类。

1
2
3
4
//比如说 ,有一个动物类,你可以定义一个吃的功能。然后用来创建猫和狗,但是猫和狗吃的东西是不一样的,所以我们最好设计成抽象类。抽象方法需要和抽象类搭配使用!
public abstract class Animal {
public abstract void eat();
}

抽象类的特点

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

public static void main(String[] args) {
//Animal a1 = new Animal();//抽象类无法实例化!
//如果我们 要使用抽象类中的方法,我们就需要找一个类来继承他,然后实例化
Animal a = new Cat();
a.say();
}
}
public abstract class Animal {
public abstract void eat();
public void say(){
System.out.println("hi!");
}
}

抽象类和抽象方法必须使用abstract关键字修饰
public abstract class {}
public abstract void eat();
抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类。
抽象类不能实例化,如果要实例化则需要参战多态的方式,通过子类对象实例化,这叫抽象类多态。
抽象类的子类:要么重写抽象类中的所有抽象方法,要么他本身也是抽象类。

接口

接口概述

接口就是一种公共的规范标准,只要符合规范标准大家都可以通用,Java中的接口更多的体现在对行为的抽象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class AnimalDemo {

public static void main(String[] args) {
Jumpping c = new Cat();
c.jump();//输出猫现在可以跳高了
}
}
public interface Jumpping {
public abstract void jump();
}
public class Cat implements Jumpping{
@Override
public void jump() {
System.out.println("猫可以跳高了!");
}
}

接口用关键字interface修饰:public interface 接口名{}
类实现接口用implements表示:public class 类名 implements 接口名{}
接口不能实例化:接口如何实现实例化呢?参考多态的方式,通过实现类对象实例化,这叫接口多态。
多态的形式:具体类多态,抽象类多态,接口多态。
多态的前提:有继承或实现关系,有方法重写,有父类指向子类对象。
接口的实现类:
要么重写接口中的所有抽象方法
要么是抽象类

接口是没有构造方法的。

接口的成员特点

成员变量:只能是常量,因为接口里的成员变量都默认自带public static final.
构造方法:接口没有构造方法,因为接口主要是对行为进行抽象的,是没有具体存在,一个类如果没有父类,默认继承自Object类。

成员方法:只能是抽象方法。因为他们默认带修饰符public abstract

类和接口的关系

类和类的关系:继承关系,只能单继承,但是可以多层继承。
类和接口的关系:实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口。
接口和接口的关系:继承关系,可以单继承,也可以多继承。

抽象类和接口的区别

比如说一个门有开门,关门,报警的功能。那么我们可以把这三个功能都写在一个类,或者接口里,但是这样的设计并不好,假设我们需要新实现一个报警器,那么我们不应该需要开门和关门的功能。

注意!抽象类是对事物的抽象,而接口是对行为的抽象。

所以最好的设计方案应该是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public interface Alram{
void alarm();
}
public abstract class Door(){
public abstract void open();
public abstract void close();
}
public class AlarmDoor extends Door implements Alarm{
public void open(){
//...
}
public void close(){
//...
}
public void alarm(){
//...
}
}

内部类

形参和返回值

类名作为形参和返回值

方法的形参是类名,其实需要的是该类的对象
方法的返回值是类名,其实返回的是该类的对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 类名作为形参
public class Cat {
public void eat(){
System.out.println("猫吃鱼!");
}
}
public class CatOperator {
public void useCat(Cat c){
c.eat();
}
}
public class CatDemo {
public static void main(String[] args) {
CatOperator co = new CatOperator();
Cat c = new Cat();
co.useCat(c);//输出猫吃鱼
}
}

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 CatOperator {
public void useCat(Cat c){
c.eat();
}
public Cat getCat(){
Cat c = new Cat();
return c;
}
}

public class Cat {
public void eat(){
System.out.println("猫吃鱼!");
}
}
public class CatDemo {
public static void main(String[] args) {
Cat c = new Cat();
CatOperator co = new CatOperator();
co.useCat(c);
Cat c2 = co.getCat();//这里返回的是一个Cat对象
c2.eat();//输出猫吃鱼

}
}


内部类

就是在一个类中定义一个类。比如可以再A类内部中再定义一个B类。B类就是内部类。

1
2
3
4
public class Outer{
public class Inner{
}
}

内部类的访问特点:

内部类可以直接访问外部类的成员对象包括私有。
外部类要访问内部类的成员,必须创建对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Outer {

private int num = 10;
public class Inner{
public void show(){
System.out.println("I'm inner"+num);//可以访问外部类的成员对象
}
}
public void method(){
//show()外部类无法直接访问内部类,需要先进行实例化
Inner i = new Inner();
i.show();
}
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}

成员内部类

根据内部类在类中定义的位置不同,可以分为如下两种形式

  1. 在类的成员位置:成员内部类
  2. 在类的局部位置:局部内部类

成员内部类,外界应该如何创建对象使用呢?

格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象
范例:Outer.Inner oi = new Outer().new Inner(); //但是如果是private类型的方法或成员变量就无法调用。
如果内部类为private,那么就应该在外部类中写一个public的method来调用Inner创建对象然后操作。

局部内部类

简单来说就是在方法里面的类。该类可以直接访问外部类的成员,也可以访问方法内的局部变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Outer {
private int num = 10;
public void method(){
class Inner {
public void saynum(){
System.out.println("Outer的num是"+num);
}
}
Inner i = new Inner();
i.saynum();
}

}

public class OuterDemo {
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}

匿名内部类

前提:存在一个类或者接口,这里的类可以是具体类也可以是抽象类。

格式:

1
2
3
4
5
6
7
8
9
new 类名或接口名(){
重写方法;
};

new Inter(){
public void show(){

}
}

匿名内部类本质是一个对象。是一个继承了该类或者实现了该接口的子类匿名对象。

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 Outer {
public void method(){
// new Inter(){
// @Override
// public void show() {
// System.out.println("匿名内部类");
// }
// }.show();//这里如果不加.show而是选择分号的话就只是一个Inter对象。

Inter i = new Inter() {
@Override
public void show() {
System.out.println("匿名内部类");
}
};
i.show();
i.show();
}
}

public class OuterDemo {
public static void main(String[] args) {
Outer o = new Outer();
o.method();//输出两次匿名内部类
}
}
public interface Inter {
void show();
}

常见类

Math&System类

Math类

abs:返回参数的绝对值
ceil:返回大于或等于参数的最小double值,等于一个整数
floor:返回小于或等于参数的最大double值,等于一个整数
round:按照四舍五入返回最接近参数的int
max:返回两个参数中最大值
min:返回两个参数中的最小值
pow:返回a的b词幂的值 public static double pow(double a, double b)
random:返回值为double的正值。范围是[0.0,1.0]

System类

System包含几个有用的类字段和方法,它不能被实例化。

1
2
punlic static void exit(int status) //终止当前运行的虚拟机,非0表示异常中止
public static long currentTimeMillis()//返回当前时间(以毫秒为单位)

我们可以利用currentTimeMillis来计算程序耗时

1
2
3
4
5
6
7
8
public static void main(String[] args) {
long start = System.currentTimeMillis();
for(int i =0;i<10000;i++){
System.out.println(i);
}
long end = System.currentTimeMillis();
System.out.println("共耗时"+(end-start)+"毫秒");
}

Object类

Object类是类层次结构的根。每个类都有Object作为超类。所有对象(包括数组)都实现了类的这个方法。

面向对象中,为什么说子类的构造方法默认访问的都是父类的无参构造方法?
这是因为它们的顶级父类只有无参构造方法。

toString方法默认现实的是在内存中的地址,Java建议我们每个子类都应该重构它。Idea中提供了快捷重构的方式alt+insert即可。

Arrays

使用Arrays我们可以很方便的实现冒泡排序。
冒泡排序:一种排序的方式,对要进行排序的数据中相邻的数据进行两两比较,将较大的数据放在后面,依次对所有的数据进行操作,直至所有数据按照要求完成排序。

冒泡排序

  1. 如果有n个数据进行排序,总共需要比较n-1次。(因为每次比较完都会有一个数据出去)
  2. 每一次比较完毕,下一次比较就会少一个数据参与。

冒泡算法的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class test {
public static void main(String[] args) {
int[] arr = {24,69,80,57,13};
System.out.println(arrayToString(arr));
//根据特性,我们可以知道一共需要比较n-1次
for(int x=0;x<arr.length-1;x++){ //计算机是从0开始计算的,所以我们的比较范围应该是arr.length-1
for(int i=0;i<arr.length-1-x;i++){
if(arr[i]>arr[i+1]){
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
}
System.out.println(arrayToString(arr));
}
public static String arrayToString(int[] arr){
StringBuilder sb = new StringBuilder();
sb.append("[");
for(int i=0;i<arr.length;i++){
if(i==arr.length-1){
sb.append(arr[i]);
}else{
sb.append(arr[i]).append(",");
}
}
sb.append("]");
String s = sb.toString();
return s;
}
}

Arrays的常用方法

Arrays类包含用于操作数组的各种方法,常用的就是toString和sort(排序)。

Arrays类是个工具类,Java 为工具类命名规则是加添以个 s 。

其中Arrays的sort方法默认就是冒泡排序。如果你查看Arrays的源码会发现他的默认构造方法是用private修饰,为的就是防止我们进行构造Arrays的对象。因为Arrays设计出来就是为了当工具使用的,比如说,Arrays.toString()是吃饭,new代表一个人。

查看源码的方式是ctrl+b。

工具类的设计思想:

  1. 构造方法用private修饰
  2. 成员用public static修饰

Date类

Date类概述和构造方法

Data代表了一个特定的事件,精确到毫秒。

public Data() //分配一个Data对象,并初始化,以便它代表它被分配的时间,精确到毫秒。
public Data(long date) //分配一个Data对象,并将其初始化为表示从标准基准时间起指定的毫秒数。

1
2
3
4
5
6
7
8
9
public class my {
public static void main(String[] args) {
Date d1 = new Date();
System.out.println(d1); //Sat Feb 25 19:59:21 HKT 2023
long date = 1000*60*60;
Date d2 = new Date(date);//Thu Jan 01 09:00:00 HKT 1970
System.out.println(d2);
}
}

Date类的常用方法

public long getTime(); //获取的是日期对象从1970年1月1日00:00:00到现在的毫秒。

public void setTime(long time); //设置时间,给的是毫秒值。

SimpleDateFormat类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class my {
public static void main(String[] args) throws ParseException {
Date d = new Date();
SimpleDateFormat sfd = new SimpleDateFormat("yyyy年mm月dd日 HH:mm:ss");
String s = sfd.format(d);
System.out.println(s);//2023年08月25日 20:08:23

System.out.println("-------");
String ss = "2048-08-09 11:11:11";
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");//这里一定要跟ss的格式一样,不然会报ParseException
Date dd = sdf2.parse(ss);
System.out.println(dd);
}
}

Calendar 类

image-20230225201702683

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class my {
public static void main(String[] args) throws ParseException {
Date d = new Date();
String s1 = DateUtils.dateToString(d, "yyyy年-MM月-dd日 HH:mm:ss");
System.out.println(s1);

String s2 = DateUtils.dateToString(d, "yyyy年-MM月-dd日");
System.out.println(s2);

String s3 = DateUtils.dateToString(d, "HH:mm:ss");
System.out.println(s3);

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

String s = "2048-08-12 12:12:12";
String d1 = DateUtils.stringToDate(s,"yyyy-mm-dd HH:mm:ss");
System.out.println(d1);
}
}

Calendar类

image-20230225202935639

1
2
3
4
5
6
7
8
9
10
11
12
13
public class my {
public static void main(String[] args) throws ParseException {
Calendar c = Calendar.getInstance();

int year = c.get(Calendar.YEAR);
int month = c.get(Calendar.MONTH)+1;//因为月份是从0开始的,所以要加1
int date = c.get(Calendar.DATE);

System.out.println(year);
System.out.println(month);
System.out.println(date);
}
}

异常

image-20230227170513440

Java分error和异常两种情况,如果是error表示非常严重的错误,一般不捕获。异常就是能接收捕获的。

异常类和不是RuntimeException的子类的任何类都是检查异常。

RuntimeException是Java虚拟机的正常操作期间可以抛出的异常的超类。其子类是未经检查的异常。

JVM的默认处理方案

image-20230227170701521

try…catch处理异常

image-20230227170757106

image-20230227170911767

Throwable的成员用法

Throwable的成员用法

image-20230227171346626

一般printStackTrace是最全的,一般用这个就可以了。

编译时异常和运行时异常的区别

image-20230227171528078

throws

image-20230227172218603

运行时异常如果通过在方法后面跟throws来处理,java仅仅会只是把异常情况抛出,并不会真正进行处理,并且也不会往下运行。真正的处理还得是try-catch。

image-20230227172100742

image-20230227172152009

自定义异常

image-20230227172315163

image-20230227172737592

Collection 集合体系结构

集合的特点:提供一种存储空间可变的存储模型,存储的数据容量额可以随时发生改变。

集合类体系结构

在Java中又分为单列集合和双列集合。

image-20230227173757787

Collection中的List实现可重复集合,Set实现的是不可重复的集合。

image-20230227173910382

image-20230227185953369

Collection集合常用的方法

image-20230227190324963

集合的遍历

image-20230227190810788

image-20230227191508308

Student类的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
public class Student {
private int age;
private String name;

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

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

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

public int getAge() {
return age;
}

public String getName() {
return name;
}
}

public class ArrayListStudent {
public static void main(String[] args) {
Collection<Student> s = new ArrayList<Student>();
Student a = new Student("linmouren",12);
Student b = new Student("linmouren1",13);
Student c = new Student("linmouren",14);
s.add(a);
s.add(b);
s.add(c);
Iterator<Student> IS = s.iterator();
while (IS.hasNext()){
Student st = IS.next();
System.out.println("hello" + " " + st.getAge()+st.getName());

}
}
}

Hexo博客搭建与备份

搭建hexo博客

第一步:下载nodejs和git,官网下载,一路next即可。

第二步:配置git:

1
2
3
git config --global user.name "username" //到时候提交显示的用户名
git config --global user.email "username@email.com" //注册github的邮箱
git config --global --list //查看当前git帐号信息

第三步:生成ssh-key

1
2
3
ssh-keygen -t rsa
//一般生成的rsa秘钥会在:c:\user\xxx\.ssh id_rsa.pub 里面 将这里面的内容填到github中
ssh -T git@github.com //测试是ssh-key否配置正确

第四步:建立hexo博客文件

1
npm install -g hexo-cli --registry=https://registry.npm.taobao.org
1
hexo init myblog //初始化blog文件夹

如果提示无权限,请输入

1
set-ExecutionPolicy RemoteSigned

进入myblog文件夹后,使用该命令安装所需组件

1
npm install

以下是hexo博客的启动命令

1
2
hexo g
hexo server

第六步安装hexo部署

1
npm install hexo-deployer-git --save

安装完deployer之后,进入blog文件夹,修改config文件,滑到最底部修改成。(请注意,中间有空格),repo就是仓库的https地址。

1
2
3
4
deploy:
type: git
repo: https://github.com/cdroad/cdroad.github.io.git
branch: master

申请github.io的地址

创建一个跟自己用户名一致的仓库即可,比如我是cdroad.github.io。