MyNote

# 二维数组

```java
格式一:
    数据类型[][] 数组名字 = new 数据类型[二维数组长度][一维数组长度];
    int[][]       arr   =  new int[3][2];
格式二:
    int[][]   arr = new int[3][];
格式三:
    int[][]   arr ={{1,2,3},{1,2,3},{1,2,3}}
```

# 方法

````java
方法的定义:具有(特定功能)一段独立的小程序(代码块)
方法的格式:
    修饰符 返回值类型 方法名(数据类型 数据变量,·····){
    语句体内容(实现功能的代码);
    return 返回值;
}

注意:1.明确参数列表;
    2.明确返回值类型;
    
方法的使用:方法只有被调用才会执行,不调用是不会执行的;
    怎么调用:
    1.单独调用:方法名(参数);
    注意:
        如果方法有返回值,单独调用是没有意义的
        如果方法没有返回值,单独调用就有意义了
    2.输出调用
        System.put.println(方法名(参数));
    注意:如果方法没有返回值就不能输出调用;
    3.赋值调用
        数据类型 变量名 = 方法名(参数);
    注意:如果方法没有返回值,就不能,就不能赋值调用;
    

````



















# 多态

````java
好处:提高了扩展性;
弊端:父类引用不能使用子类特有的成员变量和成员方法;
怎么解决?
    向下转型
    向上转换:Fu fu = new Zi();
    向下转换:Zi zi = new (Zi)fu;

Animal an = new Dog();
Pig pig = (Pig)an;//错的
````



# 异常类型

```java
ClassCastException:类型转换异常
```



# final

```java
它是一个修饰符,代表最终的意思,它可以修饰类,修饰变量,修饰方法

特点:被final修饰的变量是常量;
1.java中常量的分类?
    字面值常量
    整数常量
    小数常量
    字符常量
    字符串常量
    布尔常量
    空常量
2.自定义常量
    被final修饰的变量就变成了自定义常量;
3.被final修饰的成员方法不能被重写;
4.被final修饰的类不能被继承;
    
注意事项:
    如果一个类的成员变量被final修饰,并且没有赋值的话,会编译报错
解决办法:1.定义变量的时候直接赋值
		2.构造方法给变量赋值
```

# 代码块

```java
有一对大括号{}组成的,就称为代码块;

代码块的分类
    局部代码块
    构造代码块
    静态代码块
    同步代码块

```

# 局部代码块

```java
定义:在方法中的代码块就是局部代码块;
作用:尽可能早的让局部变量在内存中消失,节省内存空间
    public void show() {
			{
				int i = 1;
			}
			
			/*
				一万行代码
			*/
		}
```



# 构造代码块

```java
定义:在类中的方法外的代码就是构造代码块
    
作用:构造代码块是构造方法调用的时候执行,并且优先于构造方法执行
    我们可以将一个类中的所有的构造方法中的构造方法中的共性内容抽取出来,放在构造代码块中
   class Demo {
			{
			
			}
			
			public Demo() {
			
			}
		
			public void show() {
			
			}
		}
```



# 静态代码块

```java
定义:就是在构造代码之前加上关键字static
    class A {
			static {
			
			}
		}
作用:静态代码块是在字节码文件加载到内存中的时候调用的,所以不管创建该类多少次对象,静态代码块
		只会执行一次
    静态代码块可以对数据进行初始化,当数据的初始化只需要加载一次的时候就可以选择使用静态代码块
```



# 抽象类

```java
定义:有抽象方法的类就是抽象类,被abstract修饰的类就是抽象类;
    
抽象方法:
    没有方法体的方法就是抽象类
    
特点:
    1.抽象类和抽象方法都要被abstract修饰
    abstract class Fu {
			public abstract void eat();
		}
    2.抽象类的对象中可以没有抽象方法,但是一定有抽象类
    3.抽象类不能创建对象
    4.如果一个类继承了抽象类,那么该类也是抽象类,就可以不用重写抽象方法,但是如果该类是一个普通类,那就必须重写抽象类中的所有抽象方法
        
抽象类成员特点:
    1.成员变量:
    可以有普通的成员变量
    int i
    可以有静态的成员变量
    static int i;
    可以有自定义常量
    final int i = 1;
2.成员方法
    可以有非抽象类的成员方法
    可以有抽象方法
    
3.构造方法:
    有构造方法,但是不能创建对象
    抽象类的构造方法就是为了让子类去调用,给属性初始化
    
    
abstract关键字不能和那些关键字共存?
     
    private关键字:被private所修饰的方法不能被重写,被abstract所修饰的方法是需要子类重写的,他们冲突
	
	final关键字:被final所修饰的方法不能被重写,被abstract所修饰的方法是需要子类重写的,他们冲突
	
	static关键字:如果抽象方法上面有static关键字的话,那就说明可以使用类名直接调用,但是类名直接调用
				  一个没有方法体的方法是没有意义的
    
```



# 接口

```java
    比抽象类更加抽象的表现形式,就是接口
    
格式:
    接口不是类
   
    interface 接口名{
        
    }
使用格式:
    interface Inter{}
    class interTmpl implements inter{
        
    }

特点:
    1.接口不能创建对象
    2.如果一个类想要实现接口,要么该类是一个普通类,就需要重写接口中的所有的抽象方法。
    要么该类就是
    
成员变量的特点
    1
```

# 内部类

```java
定义:一个类定义在另一个类的里面,里面的类就称为内部类(类的嵌套)
    
特点:
    内部类可以使用外部类的成员变量和方法
    外部类不可以直接使用内部类的成员变量和方法
    
内部类的分类:
    成员内部类
    定义在类中方法外的内部类
        
        不同的修饰的成员内部类该如何使用?
        
    
    
    局部内部类
    定义在方法中的内部类
```

# 匿名内部类

```java
定义:没有名字的局部内部类(匿名子类没有对
```



# 第三周

# 2021年12月21日

# 内部类

```java
内部类的特点?
	内部类可以直接使用外部类的成员变量和成员方法,包括私有的成员变量和成员方法。
	外部类不可以直接使用内部类的成员变量和成员方法,但是我们可以间接的使用
	
	class Outer {
		private int i = 1;
		
		private void show() {
			System.out.println("约吗");
		}
		
		class Inner {
			public void print() {
				System.out.println(i);
				show();
			}
		}
	}
	
内部类的分类?
	1.成员内部类
		什么是成员内部类?
			定义在类中方法外的内部类
		
		不同的修饰符所修饰成员内部类该如何使用?
			class Outer {
				修饰符 class Inner {
				
				}
			}	
			
			a.public/protected/默认
				class Outer {
					class Inner {
						int i = 1;
						
						public void print() {
							System.out.println("健康一身轻,跑步去北京");
						}
					}
				}
				
				class Demo {
					public static void main(String[] args) {
						//创建内部类对象
						Outer.Inner oi = new Outer().new Inner();
						System.out.println(oi.i);
						oi.print();
					}
				}
			
			b.static
				class Outer {
					static class Inner {
						int i = 1;
						
						public void print() {
							System.out.println("健康一身轻,跑步去北京");
						}
					}
				}
				
				import com.inner.Outer.Inner;
				class Demo {
					public static void main(String[] args) {
						//创建内部类对象
						/*Outer.Inner oi = new Outer.Inner();
						System.out.println(oi.i);
						oi.print();*/
						
						Inner inner = new Inner();
						System.out.println(inner.i);
						inner.print();
						
					}
				}
			
			c.private
				class Outer {
					private class Inner {
						int i = 1;
						
						public void print() {
							System.out.println("健康一身轻,跑步去北京");
						}
					}
					
					public void show() {
						Inner inner = new Inner();
						System.out.println(inner.i);
						inner.print();
					}
				}
		
				class Demo {
					public static void main(String[] args) {
						Outer outer = new Outer();
						outer.show();
					}
				}
2.局部内部类
		什么是局部内部类?
			定义在方法中的内部类
			
		局部内部类的使用?
			class Outer {
				public void show() {
					class Inner {
						int i = 2;
						
						public void print() {
							System.out.println("一天一苹果,医生远离我");
						}
					}
					
					Inner inner = new Inner();
					System.out.println(inner.i);
					inner.print();
				}
			}
			
			class Demo {
				public static void main(String[] args) {
					Outer outer = new Outer();
					outer.show();
				}
			}
```

# 局部内部类

```java
匿名内部类的格式?
	new 类名/接口名() {
		可以写重写的方法
		可以写自定义的方法
	};
	
	new Person() {
	
	};

练习:
	一:
		class Demo {
			public static void main(String[] args) {
				//需求:不全代码,要求能够调用到show方法和print方法,在控制台打印出"约吗"
				new Fu() {
					public void show(Inter inter) {
						inter.print();
					}
				}.show(new Inter() {
					public void print() {
						System.out.println("约吗");
					}
				});
			}
		}

		abstract class Fu {
			public abstract void show(Inter inter);
		}
		
		interface Inter {
			public abstract void print();
		}

	二:
		class Demo {
			public static void main(String[] args) {
				Tools.getInstance.print();
			}
		}
		
		interface Inter {
			public abstract void print();
		}

		//不全代码,在控制台上打印出"约吗"
```





# object

- ```java
  1.Object类
  什么是Object类?
  	类 Object 是类层次结构的根类。
  	每个类都使用 Object 作为超类。
  	所有对象(包括数组)都实现这个类的方法
  
  常用的构造方法?
  	public Object()
  	
  常用的方法有哪些?
  	public String toString():返回该对象的字符串表示,建议所有子类都重写此方法。 
  	
  		java.lang.Object             @         7852e922
  		this.getClass().getName() + '@' + Integer.toHexString(this.hashCode())
  		类名		           at 标记符“@”    对象哈希码的无符号十六进制表示
      
      	注意:当我们打印对象名的时候,其实默认是调用了对象的toString()
  ​		
  ​		public boolean equals(Object obj):指示其他某个对象是否与此对象“相等”。 
  ​			
  ​			 public boolean equals(Object obj) {
  ​				return (this == obj);
  ​				/*
  ​					==号是什么意思?
  ​						如果==比较的是数值的,就比较数值是否相等
  ​						如果==比较的是引用数据类型的数据的话,就比较是地址值是否相等
  ​				*/
  ​			 }
  ​			 
  			 注意:一般我们会重写equals(),来比较两个对象的属性是否完全相同的
  ```

# 对象数组

```java
什么是对象数组?
		就是数组的元素是对象
		

	对象数组的使用?
		//创建一个猪圈
		Pig[] pigs = new Pig[5];
		
		//创建一头猪,将猪扔到猪圈中
		Pig pig1 = new Pig("tom", 18);
		pigs[0] = pig1;
		
		//创建一头猪,将猪扔到猪圈中
		Pig pig2 = new Pig("jerry", 19);
		pigs[1] = pig2;
		
		//创建一头猪,扔到猪圈
		pigs[2] = new Pig("tony", 20);
		
		//创建一头猪,扔到猪圈
		pigs[3] = new Pig("mary", 21);
		
		//创建一头猪,扔到猪圈
		pigs[4] = new Pig("jack", 18);
		
		//遍历
		for(int i = 0; i < pigs.length; i++) {
			System.out.println(pigs[i]);
		}	


```

# string

```java
1.String
	什么是String类?
		String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。
		字符串是一个常量,同时也是一个对象,比如:"abc"
		字符串既然是一个常量,它的值是不可以改变的,所以字符串是一个长度不可以改变的字符序列。
    
    
常见的构造方法?
	1.public String():初始化一个新创建的 String 对象,使其表示一个空字符序列
	2.public String(byte[] bytes):将字节数组转换成字符串
	3.public String(byte[] bytes,int offset,int length):将字节数组转换成字符串(从指定索引开始,转换几个)
	4.public String(char[] value):将字符数组转换成字符串
	5.public String(char[] value,int offset,int count):将字符数组转换成字符串(从指定索引开始,转换几个)
	6.public String(String original):初始化一个新创建的 String 对象,使其表示一个与参数相同的字符序列
	7.String s = "abc"	
	
	常见的面试题?
		考题一:
			通过new出来的字符串对象和通过直接赋值方式创建出来的对象有什么区别?
				new出来的方式在内存中有2个对象
				直接赋值方式在内存中只有1个对象
				
		考题二:
			String s1 = "abc";
			String s2 = "abc";
			String s3 = new String("abc");
			System.out.println(s1 == s2);//true
			System.out.println(s1 == s3);//false
			
		考题三:
			String s1 = "abc";
			String s2 = "ab";
			String s3 = s2 + "c";
			System.out.println(s1 == s3);//false
			
		考题四:
			String s1 = "abc";
			String s2 = "ab" + "c";
			System.out.println(s1 == s2);//true				

常见的成员方法?
	1.public char charAt(int index):返回指定索引处的 char 值
	2.public int compareTo(String anotherString):按字典顺序比较两个字符串
	3.public String concat(String str):将指定字符串连接到此字符串的结尾
	4.public boolean contains(String s):当且仅当此字符串包含指定的 char 值序列时,返回 true
	5.public boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始
	6.public boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
	7.public boolean equals(Object anObject):将此字符串与指定的对象比较
	8.public boolean equalsIgnoreCase(String anotherString):将此 String 与另一个 String 
															比较,不考虑大小写
	9.public byte[] getBytes():将字符串转换为字节数组
	10.public int indexOf(int ch):返回指定字符在此字符串中第一次出现处的索引
	11.public int indexOf(String str):返回指定子字符串在此字符串中第一次出现处的索引
	12.public int lastIndexOf(int ch):返回指定字符在此字符串中最后一次出现处的索引
	13.public int length():返回此字符串的长度
	14.public String replace(char oldChar,char newChar):返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 得到的
	15.pusu'bblic String replace(String target,String replacement):返回一个新的字符串,将新的字符串替换老的字符串
	16.public String substring(int beginIndex):返回一个新的字符串,它是此字符串的一个子字符串。
	该子字符串从指定索引处的字符开始,直到此字符串末尾
	17.public String substring(int beginIndex,int endIndex):截取,从哪里截取到哪里,包头不包尾
	18.public char[] toCharArray():将此字符串转换为一个新的字符数组
	19.public String toLowerCase():将大写字母变成小写字母
	20.public String toUpperCase():将小写字母变成大写字母
	21.public String trim():返回字符串的副本,忽略前导空白和尾部空白
	22.public String[] split(String regex):根据给定正则表达式的匹配拆分此字符串,切割

练习题?
	1.字符串的遍历
		已知有一个字符串String s = "abcde",要求把每一个字符给遍历出来?
			方式一:
				String s = "abcde";
	
				for(int i = 0; i < s.length(); i++) {
					char ch = s.charAt(i);
					System.out.println(ch);
				}
				
			方式二:
				String s = "abcde";
				
				char[] chs = s.toCharArray();
				for (int i = 0; i < chs.length; i++) {
					System.out.println(chs[i]);
				}
			
			方式三:
				String s = "abcde";
	
				String[] strs = s.split("");
				for (int i = 0; i < strs.length; i++) {
					System.out.println(strs[i]);
				}
			
	2.已知有一个字符串String s = "afdsASFSDasdfjASFDskdfjsdaASFAD",要求把首字母变大写,其余字母变小写?
		System.out.println(s.substring(0, 1).toUpperCase().concat(s.substring(1).toLowerCase()));
```

# StringBuilder

```java
	2.StringBuilder
	什么是StringBuilder类?
		一个长度可变的字符序列字符串缓冲区,我们可以把它当成一个容器来使用
	
StringBuilder缓冲区容器的特点?
	它可以存储任何数据类型的数据,但是一旦存储进去以后,全部变成字符串,最终容器里面会一个完整的字符串
	
常见的构造方法?
	1.public StringBuilder():构造一个不带任何字符的字符串生成器,其初始容量为 16 个字符
	2.public StringBuilder(String str):构造一个字符串生成器,并初始化为指定的字符串内容。
									  该字符串生成器的初始容量为 16 加上字符串参数的长度

常见的成员方法?
	1.public StringBuilder append(Object obj):追加 Object 参数的字符串表示形式
	2.public int capacity():返回当前容量
	3.public int length():返回长度(字符数)。 
	4.public StringBuilder reverse():将此字符序列用其反转形式取代
	5.public String toString():将字符串缓冲区转换为字符串类型数据
	
String和StringBuilder的相互转换?
	String -> StringBuilder
		public StringBuilder(String str)
		
	StringBuilder -> String
		public String toString()

练习题?
	需求:已知有一个字符串String s = "abcde",要求将字符串中的内容进行反转,然后再遍历字符串打印出来?
		String s = "abcde";
	
		//将字符串转换成字符串缓冲区
		StringBuilder sb = new StringBuilder(s);
		
		//反转
		sb.reverse();
		
		//将字符串缓冲区转换成字符串
		s = sb.toString();
		
		System.out.println(s);
		
StringBuilder和StringBuffer?
	它们是亲兄弟
	
	StringBuilder中具备的方法StringBuffer也有
	
	它们的区别?
		先不讲(多线程的时候才能讲)
```

# Math

```java
什么是Math类?
		Math 类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数
		Math就是一个数学工具类
			构造方法私有了
			成员方法都是静态的
    
    
常见的成员方法?
	1.public static int abs(int a):返回 int 值的绝对值
	2.public static double ceil(double a):返回最小的(最接近负无穷大)double 值,该值大于等于参数,
										 并等于某个整数
	3.public static double floor(double a):返回最大的(最接近正无穷大)double 值,该值小于等于参数,
									     并等于某个整数
	4.public static int max(int a,int b):返回两个 int 值中较大的一个
	5.public static int min(int a,int b):返回两个 int 值中较小的一个
	6.public static double pow(double a, double b):返回第一个参数的第二个参数次幂的值
	7.public static int round(float a):返回最接近参数的 int
	8.public static double random():返回带正号的 double 值,该值大于等于 0.0 且小于 1.0
									[0.0, 1.0)
		练习题?
			获取1-100之间的随机正整数?
				(int)(Math.random() * 100 + 1) 
					Math.random() -> [0.0, 1.0)
					Math.random() * 100 -> [0.0, 100.0)
					Math.random() * 100 + 1 -> [1.0, 101.0)
					(int)(Math.random() * 100 + 1) -> [1, 100]
				
				(int)(Math.random() * 100) + 1;
					Math.random() -> [0.0, 1.0)
					Math.random() * 100 -> [0.0, 100.0)
					(int)(Math.random() * 100) -> [0, 99]
					(int)(Math.random() * 100) + 1 -> [1, 100]
					
			获取19-86之间的随机正整数?
```

# 基本数据类型包装类

```java
什么是基本数据类型包装类呢?
		针对8种基本数据类型包装成的8种引用数据类型
    
byte	 --->     Byte
short	 --->     Short
int      --->     Integer
long     --->     Long
float	 --->     Float
double	 --->     Double
char	 --->     Character
boolean  --->     Boolean
```

# Integer

```java
什么是Integer类?
		Integer 类在对象中包装了一个基本类型 int 的值
    
int基本数据类型的包装类
	
常见的构造方法?
	1.public Integer(int value):可以将int类型转换成Integer类型
	2.public Integer(String s):可以将数字格式的字符串转换成Integer类型
		注意:如果是非数字格式字符串,会运行报错

常见的成员方法?
	1.public int intValue():将Integer类型转换成int类型
	2.*public static int parseInt(String s):可以将数字格式的字符串转换成int类型
	3.public String toString():将Integer类型转换成String类型
	4.public static String toString(int i):将int类型转换String类型
	5.public static Integer valueOf(int i):将int类型转换成Integer类型
	6.public static Integer valueOf(String s):可以将数字格式的字符串转换成Integer类型
	
自动装箱和拆箱?
	什么是自动装箱?
		int -> Integer
		
		举例子:
			Integer in = 12;
			/*
				Integer in = Integer.valueOf(12);
			*/
			System.out.println(in);
		
	什么是自动拆箱?
		Integer -> int
		
		举例子:
			Integer in = new Integer(12);
			int num = in + 1;
			/*
				int num = in.intValue() + 1;
			*/
			System.out.println(num);

	自动装箱和拆箱?
		Integer in = new Integer(12);
		in = in + 1;
		/*
			in = Integer.valueOf(in.intValue() + 1);
		*/
		System.out.println(in);//13
		
常见的面试题?
	考题一:
		Integer in1 = new Integer(127);
		Integer in2 = new Integer(127);
		System.out.println(in1 == in2);//false
		
	考题二:
		Integer in1 = new Integer(128);
		Integer in2 = new Integer(128);
		System.out.println(in1 == in2);//false
		
	考题三:
		Integer in1 = 127;
			/*
				Integer.valueOf(127);
			*/
		Integer in2 = 127;
			/*
				Integer.valueOf(127);
			*/
		System.out.println(in1 == in2);//true
		
	考题四:
		Integer in1 = 128;
			/*
				Integer.valueOf(128);
			*/
		Integer in2 = 128;
			/*
				Integer.valueOf(128);
			*/
		System.out.println(in1 == in2);//false
```

# System

```java
什么是System类?
		系统工具类
		构造方法私有了
		成员方法静态的
常见的成员方法?	
1.public static void exit(int status):终止当前正在运行的 Java 虚拟机
2.public static long currentTimeMillis():返回以毫秒为单位的当前时间,获取当前时间的毫秒值
3.public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length):
                        从指定源数组中复制一个数组,复制从指定的位置开始,到目标数组的指定位置结束
        src - 源数组。
        srcPos - 源数组中的起始位置。
        dest - 目标数组。
        destPos - 目标数据中的起始位置。
        length - 要复制的数组元素的数量。
```

# Date

```java
什么是Date类?
    日期时间类
    类 Date 表示特定的瞬间,精确到毫秒
    常见的构造方法?
1.public Date():获取当前系统日期时间对象
2.public Date(long date):根据指定的毫秒值获取日期时间对象

常见的成员方法?
1.public long getTime():获取date对象的毫秒值
2.public void setTime(long time):设置date对象的日期时间

日期的解析和格式化?
SimpleDateFormat类可以帮助我们实现日期的解析和格式化

日期的格式化:Date -> String
    Date date = new Date();
    //SimpleDateFormat sdf = new SimpleDateFormat();
    //SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss E");
    //SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss E");
    //SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss E");
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss E");
    String time = sdf.format(date);
    System.out.println(time);

日期的解析:String -> Date
    String time = "2000-12-12 15:15:15";
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date = sdf.parse(time);
    System.out.println(date);

练习?
    你在这个世界活了多少天?
```

# Calendar

```java
什么是Calendar类?
    日期时间类
常见的成员方法?
1.public static Calendar getInstance():使用默认时区和语言环境获得一个日历,获取Calendar对象
2.public int get(int field):返回给定日历字段的值
3.public void set(int field,int value):将给定的日历字段设置为给定值
4.public final Date getTime():获取Date对象
5.public abstract void add(int field,int amount):
                                        根据日历的规则,为给定的日历字段添加或减去指定的时间量

练习题?
判断某一年是平年还是闰年?
```

# Arrays

```java
什么是Arrays类?
    数组工具类
    构造私有
    方法静态
常见的成员方法?
1.public static void sort(int[] a):排序
2.public static String toString(int[] a):打印数组
3.public static int[] copyOf(int[] original, int newLength):复制,扩容用的
```

# UUID

```java
什么是UUID类?
    表示通用唯一标识符 (UUID) 的类
常见的方法?
public static UUID randomUUID():获取UUID对象
public String toString():将UUID类型转化为String类型
```

# Random

```java
什么是Random类?
    此类的实例用于生成伪随机数流
常见的构造方法?
public Random()

常见的成员方法?
public int nextInt(int n):返回一个伪随机数,它是取自此随机数生成器序列的、在 
                            0(包括)和指定值(不包括)之间均匀分布的 int 值

练习?
获取1-100之间的随机正整数?
    方式一:
        int num = (int)(Math.random() * 100) + 1

    方式二:
        int num = new Random().nextInt(100) + 1
```

# BigDecimal

```java
什么是BigDecimal类?
    不可变的、任意精度的有符号十进制数
    目的:为了解决小数运算的精度损失,为了让数据更加精准

常见的构造方法?
public BigDecimal(int val)
public BigDecimal(String val)

注意:如果为了让小数计算的结果更加精确,要使用参数为字符串的构造方法

常见的成员方法?
public BigDecimal add(BigDecimal augend):加法运算
public BigDecimal subtract(BigDecimal subtrahend):减法运算
public BigDecimal multiply(BigDecimal multiplicand):乘法运算
public BigDecimal divide(BigDecimal divisor):除法运算

public BigDecimal divide(BigDecimal divisor, int scale, int roundingMode):除法运算(针对除不开的情况)
                    第一个参数:此 BigDecimal 要除以的值。
                    第二个参数:保留小数点后几位。
                    第三个参数:要应用的舍入模式
                        public static final int ROUND_DOWN:去尾
                        public static final int ROUND_UP:前进
                        public static final int ROUND_HALF_UP:四舍五入
```



# LocalDate类

```java
LocalDate是一个不可变的日期时间对象,表示日期,通常被视为年月日
    2021-12-12
LocalTime类?
LocalTime是一个不可变的日期时间对象,代表一个时间,通常被看作是小时 - 秒。 时间表示为纳秒精度
10:10:10.543

LocalDateTime类?
LocalDateTime是一个不可变的日期时间对象,代表日期时间,通常被视为年 - 月 - 日 - 时 - 分 - 秒
2021-12-12 10:10:10

常见的成员方法?
    1.获取LocalDateTime对象的方法
        public static LocalDateTime now():获取当前日期时间对象
        public static LocalDateTime of(int year,
                       Month month,
                       int dayOfMonth,
                       int hour,
                       int minute,
                       int second):获取指定日期时间对象

    2.获取年月日时分秒的方法
        public int getYear():获取年
        public int getMonthValue():获取月
        public int getDayOfMonth():获取日
        public int getHour():获取时
        public int getMinute():获取分
        public int getSecond():获取秒

    3.转换方法
        public LocalDate toLocalDate():将LocalDateTime转换成LocalDate
        public LocalTime toLocalTime():将LocalDateTime转换成LocalTime

    4.解析和格式化的方法
        DateTimeFormatter类:
            public static DateTimeFormatter ofPattern(String pattern)

        格式化:LocalDateTime -> String
        public String format(DateTimeFormatter formatter):格式化

            LocalDateTime localDateTime = LocalDateTime.now();
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss E");
            String time =localDateTime.format(dateTimeFormatter);
            System.out.println(time);

        解析:String -> LocalDateTime
        public static LocalDateTime parse(CharSequence text,DateTimeFormatter formatter)

            String s = "2022-12-12 12:12:12";
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            LocalDateTime localDateTime = LocalDateTime.parse(s, dateTimeFormatter);
            System.out.println(localDateTime);

    5.增量和减量的方法
        plus系列方法
        public LocalDateTime plusXXX(long xxx):添量或者减量对应的日期时间

    6.修改的方法
        with系列方法
        public LocalDateTime withXXX(int xxx):修改对应的日期时间

练习题?
已知String s = "2021-12-24",增加一天时间?
    方式一:Date版本
        String s = "2021-12-24";

        //解析:String -> Date
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date date = sdf.parse(s);

        //增加1天的时间量
        long time = date.getTime();
        time += 1 * 24 * 60 * 60 * 1000;
        date.setTime(time);

        //格式化:Date -> String
        String newS = sdf.format(date);

        System.out.println(s);
        System.out.println(newS);

方式二:LocalDate版本
				String s = "2021-12-24";
			DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
			
			//解析:String -> LocalDate
			LocalDate localDate = LocalDate.parse(s, dateTimeFormatter);
			
			//增加1天时间量
			localDate = localDate.plusDays(1);
			
			//格式化:LocalDate -> String
			String newS = localDate.format(dateTimeFormatter);
			
			System.out.println(s);
			System.out.println(newS);
```

# 异常

````java
什么是异常?
		异常就是程序出现的错误,bug
    
异常的体系结构?
	Throwable
		-- Error 错误
			非常严重的问题
			一般都是格式语法错误,类找不到或者是内存溢出等,都会引发错误
		
		-- Exception 异常
			中小型的问题
			-- 非RuntimeException(编译时期异常:在编译的使用出现的异常)
				-- ParseException
				
			-- RuntimeException(运行时期异常:在运行的时候出现的异常)
				-- IndexOutOfBoundsException
					-- ArrayIndexOutOfBoundsException
					-- StringIndexOutOfBoundsException
				-- NullPointerException
				-- ClassCastException
				
异常的处理?
	1.捕获
		格式:
			try {
				出现异常的代码
			} catch(异常类名 变量名) {
				异常的处理方案
			} finally {
				资源的释放
			}
			
			----------------------------
			
			try {
				出现异常的代码
			} finally {
				资源的释放
			}
			
			----------------------------
			try {
				出现异常的代码
			} catch(异常类名 变量名) {
				异常的处理方案
			}
	
	2.抛
        
    1.被动抛
            格式:throws 异常类名
            位置:方法声明上

            注意:
                1.哪里调用抛哪里
                2.如果抛的是编译时期异常,接收到的异常的地方需要处理(1.要么继续抛,2.要么捕获)
                  如果抛的是运行时期异常,接收到的异常的地方就不需要处理
                3.在子父类继承中,子类重写父类方法,如果父类方法没有抛异常,子类重写的方法也不能抛异常
                4.在子父类继承中,子类重写父类方法,子类重写的方法所抛的异常不能是父类方法抛的异常的父类类型

        2.主动抛
            格式:throw 异常对象
            位置:方法中

自定义异常?
    自己创建一个异常类

    public class MyException extends RuntimeException {
        public MyException() {}

        public MyException(String message) {
            super(message);
        }
    }
````

# 集合

```java
什么是集合?
		就是一个容器
		
	集合的作用?
		用来装东西
		
	集合容器的特点?
		1.集合容器长度可以改变
		2.集合容器只能存储引用数据类型的数据(元素只能是对象)
		3.一个集合容器中,可以存储不同引用数据类型的数据
		
	集合容器和数组容器的区别?
		1.
			数组容器:一旦初始化,长度就不可以改变了
			集合容器:长度是可变的
			
		2.
			数组容器:数组容器中既可以存储基本数据类型,也可以存储引用数据类型的数据
			集合容器:集合容器只能存储引用数据类型的数据(元素只能是对象)
				
		3.
			数组容器:一个数组容器中所有的元素的数据类型必须一致
			集合容器:一个集合容器中,可以存储不同引用数据类型的数据
			
	集合的体系结构?
		单列集合:
			Collection 单列集合顶层接口
				-- List 子接口
					-- ArrayList  实现类
					-- LinkedList 实现类
					-- Vector     实现类
					
				-- Set  子接口
					-- HashSet    实现类
					-- TreeSet    实现类
					-- LinkedHashSet 实现类
					
		双列集合:
			Map 双列集合顶层接口
				-- HashMap       实现类
				-- TreeMap       实现类
				-- LinkedHashMap 实现类
				-- Hashtable     实现类
					-- Properties 实现类
```

# Collection接口

```java
单列集合顶层接口
	
常见的成员方法?
    boolean add(Object obj):添加元素
    boolean addAll(Collection c):添加一个集合中的所有元素
    void clear():清空
    boolean isEmpty():判断容器中是否为空
    boolean contains(Object o):判断是否包含指定元素
    boolean remove(Object o): 删除指定元素
    boolean removeIf(Predicate filter):按照条件删除元素
    int size(): 获取容器的长度
    Object[] toArray():将集合容器转换成数组容器
    Iterator<E> iterator():获取迭代器对象

Collection集合容器的遍历?
    方式一:转数组
        //创建集合容器
        Collection c = new ArrayList();

        //添加元素
        c.add("aaa");
        c.add("bbb");
        c.add("ccc");

        Object[] objs = c.toArray();
        for(int i = 0; i < objs.length; i++) {
            System.out.println(objs[i]);
        }

    方式二:迭代器
        //创建集合容器
        Collection c = new ArrayList();

        //添加元素
        c.add("aaa");
        c.add("bbb");
        c.add("ccc");

        //Iterator iterator()
        Iterator it = c.iterator();
        while(it.hasNext()) {
            Object obj = it.next();
            System.out.println(obj);
        }

    方式三:增强for(foreach)
        格式: 
            for(元素的数据类型 变量名 : 容器的名字) {

            }

        增强for循环底层:使用的是迭代器

        //创建集合容器
        Collection c = new ArrayList();

        //添加元素
        c.add("aaa");
        c.add("bbb");
        c.add("ccc");

        //遍历集合容器
        for(Object obj : c) {
            System.out.println(obj);
        }

```

![image-20211227173941130](C:\Users\DD\AppData\Roaming\Typora\typora-user-images\image-20211227173941130.png)

# List接口

```java
List是Collection子接口

特点?
1.有序的(存入和取出的顺序是一致的)
2.元素可以重复
3.有索引

常见的成员方法?
List接口中大部分方法和Collection中的方法是一样的,
我们只需要学习特有的方法即可。

void add(int index, Object element):增
Object remove(int index):删
Object set(int index, Object element):改
Object get(int index):查

List集合容器的遍历?
方式一:转数组
    //创建集合容器
    List list = new ArrayList();

    //添加元素
    list.add("aaa");
    list.add("bbb");
    list.add("ccc");
    list.add("ddd");
    list.add("eee");

    //遍历
    Object[] objs = list.toArray();
    for (int i = 0; i < objs.length; i++) {
        System.out.println(objs[i]);
    }

方式二:迭代器
    //创建集合容器
    List list = new ArrayList();

    //添加元素
    list.add("aaa");
    list.add("bbb");
    list.add("ccc");
    list.add("ddd");
    list.add("eee");

    //遍历
    Iterator it = list.iterator();
    while(it.hasNext()) {
        Object obj = it.next();
        System.out.println(obj);
    }

方式三:增强for
    //创建集合容器
    List list = new ArrayList();

    //添加元素
    list.add("aaa");
    list.add("bbb");
    list.add("ccc");
    list.add("ddd");
    list.add("eee");

    //遍历
    for (Object obj : list) {
        System.out.println(obj);
    }

方式四:普通for
    //创建集合容器
    List list = new ArrayList();

    //添加元素
    list.add("aaa");
    list.add("bbb");
    list.add("ccc");
    list.add("ddd");
    list.add("eee");

    //遍历
    for(int i = 0; i < list.size(); i++) {
        Object obj = list.get(i);
        System.out.println(obj);
    }
```



# ArrayList类	

```java
ArrayList是List的实现类

特点?
1.有序的(存入和取出的顺序是一致的)
2.元素可以重复
3.有索引

常见的构造方法?
public ArrayList():构造一个初始容量为 10 的空列表

常见的成员方法?
和List是一样的

ArrayList集合的遍历方式?
方式一:转数组
    //创建集合容器
    ArrayList list = new ArrayList();

    //添加元素
    list.add("aaa");
    list.add("bbb");
    list.add("ccc");
    list.add("ddd");
    list.add("eee");

    //遍历
    Object[] objs = list.toArray();
    for (int i = 0; i < objs.length; i++) {
        System.out.println(objs[i]);
    }

方式二:迭代器
    //创建集合容器
    ArrayList list = new ArrayList();

    //添加元素
    list.add("aaa");
    list.add("bbb");
    list.add("ccc");
    list.add("ddd");
    list.add("eee");

    //遍历
    Iterator it = list.iterator();
    while(it.hasNext()) {
        Object obj = it.next();
        System.out.println(obj);
    }

方式三:增强for
    //创建集合容器
    ArrayList list = new ArrayList();

    //添加元素
    list.add("aaa");
    list.add("bbb");
    list.add("ccc");
    list.add("ddd");
    list.add("eee");

    //遍历
    for (Object obj : list) {
        System.out.println(obj);
    }

方式四:普通for
    //创建集合容器
    ArrayList list = new ArrayList();

    //添加元素
    list.add("aaa");
    list.add("bbb");
    list.add("ccc");
    list.add("ddd");
    list.add("eee");

    //遍历
    for(int i = 0; i < list.size(); i++) {
        Object obj = list.get(i);
        System.out.println(obj);
    }

练习题?
一:已知有一个ArrayList容器,里面存储以下几个元素:"aaa","bbb","aaa","aaa","ccc","ddd",
要求删除集合容器中所有的"aaa"?
    方式一:迭代器
    方式二:普通for
```

# 数据结构

```java
队列:先进先出,后进后出
栈:先进后出,后进先出
数组:查询快,增删慢
    ArrayList集合底层的数据结构就是数组数据结构
链表:查询慢,增删快
    单向链表和双向链表
    LinkedList集合底层的数据结构就是双向链表数据结构
二叉树:
    1.普通二叉树
        特点:
            1.二叉树是由节点组成的
            2.二叉树有且只有一个根节点
            3.任何一个节点最多只能有2个子节点

    2.二叉查找树
        特点:
            1.二叉树是由节点组成的
            2.二叉树有且只有一个根节点
            3.任何一个节点最多只能有2个子节点
            4.大的放在节点的右边,小的放在节点的左边,也就是说任何节点的
              左子树都比它小,右子树都比它大

    3.二叉平衡树
    4.红黑树
```

# LinkedList

```java
LinkedList是List的实现类

特点?
    1.有序的(存入和取出的顺序是一致的)
    2.元素可以重复
    3.有索引

常见的构造方法?
    public LinkedList()

常见的成员方法?
    和List中的方法是一样

    public void addFirst(Object e)
    public void addLast(Object e)
    public Object getFirst()
    public Object getLast()
    public Object removeFirst()
    public Object removeLast()

LinkedList集合容器的遍历?
    方式一:转数组
        //创建集合容器
        LinkedList list = new LinkedList();

        //添加元素
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("eee");

        //遍历
        Object[] objs = list.toArray();
        for (int i = 0; i < objs.length; i++) {
            System.out.println(objs[i]);
        }

    方式二:迭代器
        //创建集合容器
        LinkedList list = new LinkedList();

        //添加元素
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("eee");

        //遍历
        Iterator it = list.iterator();
        while(it.hasNext()) {
            Object obj = it.next();
            System.out.println(obj);
        }

    方式三:增强for
        //创建集合容器
        LinkedList list = new LinkedList();

        //添加元素
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("eee");

        //遍历
        for (Object obj : list) {
            System.out.println(obj);
        }

    方式四:普通for
        //创建集合容器
        LinkedList list = new LinkedList();

        //添加元素
        list.add("aaa");
        list.add("bbb");
        list.add("ccc");
        list.add("ddd");
        list.add("eee");

        //遍历
        for(int i = 0; i < list.size(); i++) {
            Object obj = list.get(i);
            System.out.println(obj);
        }
```

# 泛型

```java
什么是泛型?
    是指参数化类型,定义泛型的时候格式很像在定义方法的形参,在使用的时候需要传递具体的数据类型

泛型的格式?
    <E>
    <K, V>

泛型的使用?
    //创建集合容器
    ArrayList<String> al = new ArrayList<String>();

    //添加元素
    al.add("aaa");
    al.add("bbb");
    al.add("ccc");

    //遍历
    for (String s : al) {
        System.out.println(s);
    }
    --------------------------------------------------
    //创建集合容器
    ArrayList<String> al = new ArrayList<String>();

    //添加元素
    al.add("aaa");
    al.add("bbb");
    al.add("ccc");

    //遍历
    Iterator<String> it = al.iterator();
    while(it.hasNext()) {
        String s = it.next();
        System.out.println(s);
    }

泛型的作用?
    限制集合中存储的元素的数据类型
    避免强制类型转换

泛型的注意事项?
    1.泛型只能是引用数据类型,不能写基本数据类型
    2.前面的泛型的数据类型要和后面的泛型的数据类型匹配
    3.后面的箭头可以省略不写
        ArrayList<String> al1 = new ArrayList<String>();
        ArrayList<String> al2 = new ArrayList<>();
        ArrayList<String> al3 = new ArrayList();

自定义泛型?
    1.自定义泛型类
        class A<QQ> {
            public void print(QQ q) {
                System.out.println(q);
            }
        }

    2.自定义泛型方法
        class B {
            public <E> void print(E e) {
                System.out.println(e);
            }
        }

    3.自定义泛型父类(父接口)
        interface Inter<E> {
            public abstract void print(E e);
        }

        class InterImpl<E> implements Inter<E> {
            public void print(E e) {
                System.out.println(e);
            }
        }

泛型通配符?
    1.?
        ArrayList<?> al1 = new ArrayList<String>();
        ArrayList<?> al2 = new ArrayList<Integer>();
        ArrayList<?> al3 = new ArrayList<Character>();
        ArrayList<?> al4 = new ArrayList<Object>();

    2.? extends E
        向上限定

        ArrayList<? extends Number> al1 = new ArrayList<Number>();
        ArrayList<? extends Number> al2 = new ArrayList<String>();错误
        ArrayList<? extends Number> al3 = new ArrayList<Object>();错误
        ArrayList<? extends Number> al4 = new ArrayList<Integer>();
        ArrayList<? extends Number> al5 = new ArrayList<Double>();

    3.? super E
        向下限定

        ArrayList<? super Number> al1 = new ArrayList<Number>();
        ArrayList<? super Number> al2 = new ArrayList<Object>();
        ArrayList<? super Number> al3 = new ArrayList<Integer>();错误
        ArrayList<? super Number> al4 = new ArrayList<Double>();错误
        ArrayList<? super Number> al5 = new ArrayList<String>();错误

```

# Set接口

```java
Set接口是Collection的子接口
	
	特点:
		1.无序的(存入和取出的顺序不一致)
    2.元素唯一的
		3.无索引
	
	常见的成员方法?
		和Collection是一样的
		
	Set集合的遍历?
		1.方式一:转数组
		2.方式二:迭代器
		3.方式三:增强for
```

# TreeSet实现类

```java
TreeSet是Set接口的实现类

特点:
1.无序的(存入和取出的顺序不一致)
2.元素唯一的
3.无索引
4.可以排序

常见的成员方法?
和Set接口是一样的

TreeSet集合的遍历?
1.方式一:转数组
2.方式二:迭代器
3.方式三:增强for

练习题?
题一:创建一个TreeSet集合,里面存储String类型的数据,遍历?
//创建集合容器
TreeSet<String> ts = new TreeSet<String>();

//添加元素
ts.add("aca");
ts.add("c");
ts.add("abb");

//遍历集合容器
for (String s : ts) {
System.out.println(s);
}

是根据字符串的字典顺序进行排序,由小到大

题二:创建一个TreeSet集合,里面存储Integer类型的数据,遍历?
//创建集合容器
TreeSet<Integer> ts = new TreeSet<Integer>();

//添加元素
ts.add(12);
ts.add(11);
ts.add(15);
ts.add(14);
ts.add(13);

//遍历
for (Integer in : ts) {
System.out.println(in);
}

是根据数字大小进行排序,由小到大

题三:创建一个TreeSet集合,里面存储自定义对象,遍历?
//创建集合容器
TreeSet<Pig> ts = new TreeSet<Pig>();

//添加元素
ts.add(new Pig("tom", 18));
ts.add(new Pig("jack", 18));
ts.add(new Pig("rose", 17));
ts.add(new Pig("jerry", 19));
ts.add(new Pig("tony", 23));

//遍历
for (Pig p : ts) {
System.out.println(p);
}

运行结果会报异常ClassCastException,
如果想要不报错,正常运行,我们至少要实现2个条件之一:
1.自然排序
实现步骤:
    1.自定义一个类,实现Comparable接口
    2.重写compareTo()
    3.在compareTo()方法中写排序规则
    4.创建集合,添加元素,遍历

    public int compareTo() {
        return 0; 元素只有一个
        return 正数; 正序排列
        return 负数; 倒叙排列
    }

2.比较器
实现步骤:
    1.自定义一个类
    2.创建TreeSet集合对象,在有参构造中传递Comparator对象
    3.重写compare()
    4.在compare()方法中写排序规则
    5.添加元素,遍历

    public int compare() {
        return 0; 元素只有一个
        return 正数; 正序排列
        return 负数; 倒叙排列
    }
```

# 数据结构

```java
队列:先进先出,后进后出

栈:先进后出,后进先出

数组:查询快,增删慢
ArrayList集合底层的数据结构就是数组数据结构

链表:查询慢,增删快
单向链表和双向链表
LinkedList集合底层的数据结构就是双向链表数据结构

二叉树:
1.普通二叉树
特点:
1.二叉树是由节点组成的
2.二叉树有且只有一个根节点
3.任何一个节点最多只能有2个子节点

2.二叉查找树
特点:
1.二叉树是由节点组成的
2.二叉树有且只有一个根节点
3.任何一个节点最多只能有2个子节点
4.大的放在节点的右边,小的放在节点的左边,也就是说任何节点的
左子树都比它小,右子树都比它大

3.平衡二叉树
自平衡的二叉查找树

特点:
1.二叉树是由节点组成的
2.二叉树有且只有一个根节点
3.任何一个节点最多只能有2个子节点
4.大的放在节点的右边,小的放在节点的左边,也就是说任何节点的
左子树都比它小,右子树都比它大
5.任何节点的左子树和右子树的高度差不能超过1,一旦超过1就会发生自旋转(左旋和右旋)

4.红黑树
特点:
1.节点的颜色要么是黑色要么是红色
2.根节点必须是黑色的
3.如果一个节点是红色的,那么它的两个子节点必须是黑色的,也就是说不能出现
连续两个红色的节点
4.如果一个节点没有子节点,那么它默认指向了名为Nil的节点,该节点被称为叶子节点,
叶子节点的颜色必须是黑色的
5.任何节点到其叶子节点这条简单路径上的黑色节点的个数是一样多的

注意:
1.节点的默认颜色是红色
2.如果出现了两个连续的红色节点,怎么办?
子节点是红色,父节点是红色,出现了连续两个红色
1.如果叔叔的节点是红色的,那么父节点由红变黑,叔叔节点由红变黑,
  爷爷节点由黑变红,如果爷爷节点是根节点,由红变黑
2.如果叔叔的节点是黑色的,那么父节点由红变黑,爷爷节点由黑变红,然后再旋转
TreeSet集合底层数据结构是红黑树

哈希表:
哈希值:哈希值是由对象的地址值再结合其他的一系列算法最终得到的一个int类型的数字,可以通过
Object类中的hashCode()获取到。

1.7之前:哈希表 = 数组 + 链表 (元素为链表的数组)
1.7之前:哈希表 = 数组 + 链表 + 红黑树 (元素为链表或者红黑树的数组)
```

# TreeSet实现类

```java
TreeSet是Set接口的实现类

特点:
1.无序的(存入和取出的顺序不一致)
2.元素唯一的
3.无索引
4.可以排序

常见的成员方法?
和Set接口是一样的

TreeSet集合的遍历?
1.方式一:转数组
2.方式二:迭代器
3.方式三:增强for

练习题?
题一:创建一个TreeSet集合,里面存储String类型的数据,遍历?
//创建集合容器
TreeSet<String> ts = new TreeSet<String>();

//添加元素
ts.add("aca");
ts.add("c");
ts.add("abb");

//遍历集合容器
for (String s : ts) {
System.out.println(s);
}

是根据字符串的字典顺序进行排序,由小到大

题二:创建一个TreeSet集合,里面存储Integer类型的数据,遍历?
//创建集合容器
TreeSet<Integer> ts = new TreeSet<Integer>();

//添加元素
ts.add(12);
ts.add(11);
ts.add(15);
ts.add(14);
ts.add(13);

//遍历
for (Integer in : ts) {
System.out.println(in);
}

是根据数字大小进行排序,由小到大

题三:创建一个TreeSet集合,里面存储自定义对象,遍历?
//创建集合容器
TreeSet<Pig> ts = new TreeSet<Pig>();

//添加元素
ts.add(new Pig("tom", 18));
ts.add(new Pig("jack", 18));
ts.add(new Pig("rose", 17));
ts.add(new Pig("jerry", 19));
ts.add(new Pig("tony", 23));

//遍历
for (Pig p : ts) {
System.out.println(p);
}

运行结果会报异常ClassCastException,
如果想要不报错,正常运行,我们至少要实现2个条件之一:
1.自然排序
实现步骤:
1.自定义一个类,实现Comparable接口
2.重写compareTo()
3.在compareTo()方法中写排序规则
4.创建集合,添加元素,遍历

public int compareTo() {
    return 0; 元素只有一个
    return 正数; 正序排列
    return 负数; 倒叙排列
}

练习题?
需求一:根据人的年龄从小到大排序,如果年龄相同,则去重?
    @Override
    public int compareTo(Person p) {
        //比较年龄
        return this.age - p.age;
    }

需求二:根据人的年龄从大到小排序,如果年龄相同,则去重?
    @Override
    public int compareTo(Person p) {
        return p.age - this.age;
    }

需求三:根据人的年龄从小到道排序,如果年龄相同,再按照姓名字典顺序排序,
        如果姓名也相同,则去重?
    @Override
    public int compareTo(Person p) {							
        //比较年龄
        int num = this.age - p.age;

        //比较姓名
        return num == 0 ? this.name.compareTo(p.name) : num;
    }

2.比较器
实现步骤:
1.自定义一个类
2.创建TreeSet集合对象,在有参构造中传递Comparator对象
3.重写compare()
4.在compare()方法中写排序规则
5.添加元素,遍历

public int compare() {
    return 0; 元素只有一个
    return 正数; 正序排列
    return 负数; 倒叙排列
}

练习题?
需求一:根据人的年龄从小到大排序,如果年龄相同,则去重?
    TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
        @Override
        public int compare(Student s1, Student s2) {
            //比较年龄:小到大
            return s1.getAge() - s2.getAge();
        }
    });

需求二:根据人的年龄从大到小排序,如果年龄相同,则去重?
    TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
        @Override
        public int compare(Student s1, Student s2) {
            //比较年龄:小到大
            return s2.getAge() - s1.getAge();
        }
    });

需求三:根据人的年龄从小到道排序,如果年龄相同,再按照姓名字典顺序排序,
        如果姓名也相同,则去重?
    TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
        @Override
        public int compare(Student s1, Student s2) {
            //比较年龄
            int num = s1.getAge() - s2.getAge();
            //比较姓名
            return num == 0 ? s1.getName().compareTo(s2.getName()) : num;
        }
    });
```

# HashSet实现类

```java
HashSet是Set接口的实现类

特点:
1.无序的(存入和取出的顺序不一致)
2.元素唯一的
3.无索引

常见的成员方法?
和Set接口是一样的

TreeSet集合的遍历?
1.方式一:转数组
2.方式二:迭代器
3.方式三:增强for

练习题?
题一:使用HashSet集合存储String类型的数据,遍历?
    //创建集合容器
    HashSet<String> hs = new HashSet<String>();

    //添加元素
    hs.add("aaa");
    hs.add("bbb");
    hs.add("ccc");
    hs.add("bbb");
    hs.add("ddd");

    //遍历
    for (String s : hs) {
        System.out.println(s);
    }

题二:使用HashSet集合存储Integer类型的数据,遍历?
    //创建集合容器
    HashSet<Integer> hs = new HashSet<>();

    //添加元素
    hs.add(111);
    hs.add(4);
    hs.add(222);
    hs.add(333);

    //遍历
    for (Integer in : hs) {
        System.out.println(in);
    }

题三:使用HashSet集合存储自定义类型的数据,遍历?
    HashSet<Pig> hs = new HashSet<>();

    hs.add(new Pig("tom", 18));
    hs.add(new Pig("jerry", 18));
    hs.add(new Pig("rose", 17));
    hs.add(new Pig("tom", 18));
    hs.add(new Pig("jack", 23));

    for (Pig p : hs) {
        System.out.println(p);
    }

    通过测试发现,如果地址值相同,就会去重。

    提出新的需求:如果属性值全部相同,要去重?
        重写hashCode()和equals()

        @Override
        public int hashCode() {
            return this.name.hashCode() + this.age * 12;
        }

        @Override
        public boolean equals(Object obj) {
            Pig p = (Pig)obj;
            return this.name.equals(p.name) && this.age == p.age;
        }
```

# LinkedHashSet实现类

```java
LinkedHashSet是Set接口的实现类

特点?
    1.有序的(存入和取出的顺序一致)
    2.元素唯一的
    3.无索引
```

# 2021年12月30日

# Map接口

```java
双列集合
	
	特点?
		1.无序的(存入和取出的顺序不一致)
		2.无索引
		3.元素唯一(键唯一,值可以重复)
		4.双列的
		
	常见的成员方法?
		V put(K key,V value):添加,修改(根据键修改值)
		V get(Object key):根据键获取值
		V remove(Object key):根据键删除键值对,返回被删除的值
		int size():获取集合长度
		void clear():清空容器
		boolean containsKey(Object key):判断是否包含指定键
		boolean containsValue(Object value):判断是否包含指定值
		Collection<V> values():将所有的值获取到,存储到Collection集合中
		Set<K> keySet():将所有的键获取到,存储到set集合中
		Set<Map.Entry<K,V>> entrySet():将键值对对象存储到了Set集合中
		
	集合的遍历?
		方式一:通过键找值
			Set<K> keySet()
			
			//创建集合容器
			Map<String, Integer> map = new HashMap<>();
			
			//添加元素
			map.put("tom", 18);
			map.put("jerry", 18);
			map.put("jack", 19);
			map.put("rose", 19);
			map.put("tony", 20);
			
			//遍历集合
			//Set<K> keySet()
			Set<String> set = map.keySet();
			for(String key : set) {
				Integer value = map.get(key);
				System.out.println(key + "..." + value);
			}
		
		方式二:通过键值对对象找键和值
			Set<Map.Entry<K,V>> entrySet()
			
			//创建集合容器
			Map<String, Integer> map = new HashMap<>();
			
			//添加元素
			map.put("tom", 18);
			map.put("jerry", 18);h
			map.put("jack", 19);
			map.put("rose", 19);
			map.put("tony", 20);
			
			//遍历
			//Set<Map.Entry<K,V>> entrySet()
			Set<Entry<String, Integer>> set = map.entrySet();
			for (Entry<String, Integer> entry : set) {
				String key = entry.getKey();
				Integer value = entry.getValue();
				System.out.println(key + "..." + value);
			}
```

# HashMap实现类

```java
特点?
		1.无序的(存入和取出的顺序不一致)
		2.无索引
		3.元素唯一(键唯一,值可以重复)
		4.双列的
		
	常见的成员方法?
		和Map是一样的
		
	遍历?
		方式一:通过键找值
		方式二:通过键值对对象找键和值
		
	练习题?
		题一:使用HashMap存储元素,键是String,值是Pig,遍历?
			//创建集合
			HashMap<String, Pig> hm = new HashMap<>();
			
			//添加元素
			hm.put("9527", new Pig("tom", 18));
			hm.put("9528", new Pig("jerry", 19));
			hm.put("9529", new Pig("rose", 20));
			
			//遍历集合
			Set<Entry<String, Pig>> set = hm.entrySet();
			for (Entry<String, Pig> entry : set) {
				String key = entry.getKey();
				Pig value = entry.getValue();
				System.out.println(key + ":" + value.getName() + "..." + value.getAge());
			}
		
		题二:使用HashMap存储元素,键是Pig(属性相同,去重),值是String,遍历?
			//创建集合容器
			HashMap<Pig, String> hm = new HashMap<>();
			
			//添加元素
			hm.put(new Pig("tom", 18), "9527");
			hm.put(new Pig("jerry", 18), "9528");
			hm.put(new Pig("rose", 19), "9529");
			hm.put(new Pig("tom", 18), "9530");
			
			//遍历
			Set<Pig> set = hm.keySet();
			for (Pig key : set) {
				String value = hm.get(key);
				System.out.println(key.getName() + "..." + key.getAge() + "..." + value);
			}
```

# TreeMap实现类

```java
特点?
		1.无序的(存入和取出的顺序不一致)
		2.无索引
		3.元素唯一(键唯一,值可以重复)
		4.双列的
		
	常见的成员方法?
		和Map是一样的
		
	遍历?
		方式一:通过键找值
		方式二:通过键值对对象找键和值	
	
	练习题?
		题一:使用TreeMap存储元素,键是String,值是Person,遍历?
			//创建集合容器
			TreeMap<String,Person> tm = new TreeMap<>();
			
			//添加元素
			tm.put("成都", new Person("tom", 18));
			tm.put("都江堰", new Person("jerry", 19));
			tm.put("眉山", new Person("rose", 19));
			tm.put("乐山", new Person("jack", 20));
			tm.put("乐山", new Person("tony", 21));
			
			//遍历
			for(String key : tm.keySet()) {
				Person value = tm.get(key);
				System.out.println(key + "..." + value.getName() + "..." + value.getAge());
			}
		
		题二:使用TreeMap存储元素,键是Person,值是String,遍历?
			//创建集合容器
			TreeMap<Person,String> tm = new TreeMap<>(new Comparator<Person>() {
				@Override
				public int compare(Person p1, Person p2) {
					int num1 = p2.getAge() - p1.getAge();
					int num2 = num1 == 0 ? p2.getName().compareTo(p1.getName()) : num1;
					return num2;
				}
			});
			
			//添加元素
			tm.put(new Person("tom", 18),"成都");
			tm.put(new Person("jerry", 19),"都江堰");
			tm.put(new Person("rose", 19),"眉山");
			tm.put(new Person("tom", 18),"成都");
			tm.put(new Person("jack", 20),"乐山");
			tm.put(new Person("tony", 21),"乐山");
			
			//遍历
			for(Person key : tm.keySet()) {
				String value = tm.get(key);
				System.out.println(key + "..." + value);
			}
```

# Collections

````java
集合工具类

	常见的成员方法?	
		public static <T extends Comparable<? super T>> void sort(List<T> list):
															根据元素的自然顺序 对指定列表按升序进行排序
		public static <T> void sort(List<T> list,Comparator<? super T> c):
````

# 可变参数

```java
需求:定义一个方法,该方法的功能是获取两个整数和?
		public static int getSum(int i, int j) {
			return i + j;
		}
		
	需求:定义一个方法,该方法的功能是获取三个整数和?
		public static int getSum(int i, int j, int k) {
			return i + j + k;
		}
		
	需求:定义一个方法,该方法的功能是获取四个整数和?
		public static int getSum(int i, int j, int x, int y) {
			return i + j + x + y;
		}
		
	需求:定义一个方法,该方法的功能是获取N个整数和?
		public static int getSum(???) {
			return 
		}

	什么是可变参数?
		参数的个数可以变化的
		
	可变参数的定义格式?
		修饰符 返回值类型 方法的名字(数据类型...变量名) {
			语句体;
			return 返回值;
		}
		
		public static void print(int...a) {
		
		}
		
	可变参数的本质?
		就是数组
		
	注意事项?
		如果一个方法的形参有多个的话,而且还有一个是可变参数的话,那么可变参数必须放在最后面
		
6.递归
	什么是递归?
		递归是指方法内部调用方法本身
		
	递归的注意事项?
		1.递归次数不能太多,太多会容易造成内存溢出
		2.递归要有出口,没有出口会造成死递归
	
	练习题?
		题一:使用递归求N的阶乘
			5! = 5 * 4 * 3 * 2 * 1
	
			public class Demo02 {
				public static void main(String[] args) {
					System.out.println(getJC(5));
				}
				
				//使用递归求N的阶乘
				public static int getJC(int n) {
					if(n == 1) {
						return 1;
					} else {
						return n * getJC(n-1);
					}
				}
			}
	
```

# File类

```java
什么是File类?
		文件和目录路径名的抽象表示形式
		它就代表文件或者文件夹(目录),就是将文件或者文件夹封装成File对象来体现的
		
	常见的构造方法?
		public File(String pathname)
		public File(File parent,String child)
		public File(String parent,String child)
	
	常见的成员方法?
		创建相关方法?
			public boolean createNewFile():创建文件,如果创建成功返回true,创建失败返回false
			public boolean mkdir():创建文件夹
			public boolean mkdirs():创建多级文件夹
		
		删除相关方法?
			public boolean delete():删除文件或者文件夹
			
			注意:
				1.使用该方法删除的文件或者文件夹是不会经过回收站的
				2.该方法不能删除里面有子文件或者子文件夹的文件夹
		
		判断相关方法?
			public boolean exists():判断指定的文件或者文件夹是否存在
			public boolean isDirectory():判断file是文件夹吗
			public boolean isFile():判断file是文件吗
		
		获取相关方法?
			public long length():获取文件的字节大小
			public String getName():获取文件或者文件夹的名字
			public String getPath():获取文件或者文件夹的路径
			public String getAbsolutePath():获取绝对路径
			public File[] listFiles():将文件夹中的子文件和子文件夹都封装成file对象,并且存储到了数组容器中
		
```

# 绝对路径和相对路径

```java
什么是绝对路径?
		以盘符开始的路径就称为绝对路径
		
		例子:C:\\Users\\apple\\Desktop\\ccc\\ddd
		
	什么是相对路径?
		不以盘符开始的路径就称为相对路径
		
		aaa
		aaa\\bbb
		
		相对于谁?
			相对于当前项目所在目录下
```

# IO流

```java
我们学习IO流的目的?
		当我们要操作的数据多的时候,就需要对数据进行存储,方便后期的管理操作。
		这个时候我们就要考虑使用容器来存储,但是呢容器有数组和集合,不管使用哪一个容器,都不能够
		将数据永久性的进行存储。但是有些情况下我们是需要对数据进行永久性的存储,那集合和数组就无法实现了。
		
		这个时候我们就要使用IO流技术来实现这样的需求
		IO流:
			1.将内存中的数据存储到本地磁盘
			2.将本地磁盘中的数据还原到内存中
			
	什么是IO流?
		I:
			Input
			
			输入,读取
			
			将本地磁盘中的数据读取到内存中
		
		O:
			Output
			
			输出,写出
			
			将内存中的数据写出到本地磁盘
			
		流:
			是指数据就像水流一样传输着
			
			水流,电流
			
	IO流的分类?
		按照流向分?
			输入流
			输出流
		
		按照类型分?
			字节流
			字符流
			
		我们平时都怎么这些IO流?
			1.字节输入流
			2.字节输出流
			3.字符输入流
			4.字符输出流
			
	IO流的体系结构?
		OutputStream 字节输出流的顶层抽象类
			-- *FileOutputStream 
			-- *ObjectOutputStream
			-- FilterOutputStream
				-- *BufferedOutputStream
				-- *PrintStream 
				
		InputStream 字节输入流的顶层抽象类
			-- *FileInputStream
			-- *ObjectInputStream
			--  FilterInputStream
				-- *BufferedInputStream
		
		Writer 字符输出流的顶层抽象类
			-- *OutputStreamWriter
				-- *FileWriter 
			-- *BufferedWriter
			-- *PrintWriter
			
		Reader 字符输入流的顶层抽象类
			-- *InputStreamReader
				-- *FileReader 
			-- *BufferedReader
```

# FileOutputStream

```java
字节输出流
	
	常见的构造方法?
		public FileOutputStream(File file)
		public FileOutputStream(String name)
		public FileOutputStream(File file, boolean append)
		public FileOutputStream(String name, boolean append)
		
		注意:如果文件不存在,构造方法也会帮助我们创建出一个文件
	
	常见的成员方法?
		public void write(int b):向文件中写数据,一次写出一个字节数据
		public void write(byte[] b):向文件中写数据,一次写出一个字节数组的数据
		public void write(byte[] b,int off,int len):向文件中写数据,一次写出一个字节数组的一部分
		
		2个小问题?
			1.如何实现追加数据?
				public FileOutputStream(File file, boolean append)
				public FileOutputStream(String name, boolean append)
				
				第二个参数传递true实现追加
			
			2.如何实现换行功能?
				换行符:
					windows:\r\n
					linux:\n
					mac:\r
```

# FileInputStream

```java
字节输入流
	
	常见的构造方法?
		public FileInputStream(File file)
		public FileInputStream(String name)
		
		注意:如果文件不存在,则运行报错
	
	常见的成员方法?
		public int read():读取文件中的数据,一次读取一个字节数据,如果读不到了返回-1
		public int read(byte[] b):读取文件中的数据,一次读取一个字节数组的数据,如果读不到了返回-1,读到了
									返回读取到的字节个数

```

# 文件的复制

```java
方式一:一次读取一个字节,一次写出一个字节
		//创建字节输入流对象
		FileInputStream fis = new FileInputStream("aaa.txt");
		
		//创建字节输出流对象
		FileOutputStream fos = new FileOutputStream("bbb.txt");
		
		//一次读取一个字节,一次写出一个字节
		int by = 0;
		while((by = fis.read()) != -1) {
			fos.write(by);
		}
		
		//释放资源
		fos.close();
		fis.close();
	
	方式二:一次读取一个字节数组,一次写出一个字节数组的一部分
		//创建字节输入流对象
		FileInputStream fis= new FileInputStream("aaa.txt");
		
		//创建字节输出流对象
		FileOutputStream fos = new FileOutputStream("ccc.txt");
		
		//一次读取一个字节数组,一次写出一个字节数组的一部分
		byte[] bys = new byte[1024];
		int len = 0;
		while((len = fis.read(bys)) != -1) {
			fos.write(bys, 0, len);
		}
		
		//释放资源
		fos.close();
		fis.close();
```

# IO流的异常处理

```java
//创建字节输入流对象
	FileInputStream fis = null;
	//创建字节输出流对象
	FileOutputStream fos = null;
	try {
		fis = new FileInputStream("aaa.txt");
		fos = new FileOutputStream("ccc.txt");
		
		//一次读取一个字节数组,一次写出一个字节数组的一部分
		byte[] bys = new byte[5];
		int len = 0;
		while((len = fis.read(bys)) != -1) {
			fos.write(bys);
		}
	} catch(Exception e) {
		e.printStackTrace();
	} finally {
		//释放资源
		if(fos != null) {
			try {
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
		if(fis != null) {
			try {
				fis.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
```

# 2022年1月5日

# BufferedOutputStream

```java
缓冲字节输出流
	高效字节输出流
	效率高

	常见的构造方法?
		public BufferedOutputStream(OutputStream out)
	
	常见的成员方法?
		和FileOutputStream中的方法是一样的
		
		public void flush():刷新此缓冲的输出流
			close()和flush()的区别?
				close()用来释放资源的,在释放之前先自动刷新一次,close()方法只能调用一次
				flush()用来刷新的,flush()方法可以调用多次
```

# BufferedInputStream

```java
缓冲字节输入流
	高效字节输入流
	效率高
	
	常见的构造方法?
		public BufferedInputStream(InputStream in)
	
	常见的成员方法?
		和FileInputStream中的方法是一样的
```

# 复制文件

```java
方式一:普通字节输入流 + 普通字节输出流:一次读取一个字节,一次写出一个字节
	方式二:普通字节输入流 + 普通字节输出流:一次读取一个字节数组,一次写出一个字节数组的一部分
	方式三:高效字节输入流 + 高效字节输出流:一次读取一个字节,一次写出一个字节
		//创建高效字节输入流对象
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("aaa.txt"));
		
		//创建高效字节输出流对象
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bbb.txt"));
		
		//一次读取一个字节,一次写出一个字节
		int by = 0;
		while((by = bis.read()) != -1) {
			bos.write(by);
		}
		
		//释放资源
		bos.close();
		bis.close();
		
	方式四:高效字节输入流 + 高效字节输出流:一次读取一个字节数组,一次写出一个字节数组的一部分
		//创建高效字节输入流对象
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream("aaa.txt"));
		
		//创建高效字节输出流对象
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("bbb.txt"));
		
		//一次读取一个字节,一次写出一个字节
		int by = 0;
		while((by = bis.read()) != -1) {
			bos.write(by);
		}
		
		//释放资源
		bos.close();
		bis.close();
```

# 装饰设计模式

```java
应用场景:
		当我们想要对某个类中的某些方法进行增强的时候,就可以使用装饰设计模式
		
		选择方案:
			1.继承
			2.装饰设计模式
			3.动态代理设计模式
			
	例子:
		1.
			public class Demo01 {
				public static void main(String[] args) {
					托尼 tony = new 托尼();
					tony.eat();
					tony.drink();
					tony.sleep();
					tony.run();
					tony.jump();
					
					钢铁侠 gtx = new 钢铁侠(tony);
					gtx.eat();
					gtx.drink();
					gtx.sleep();
					gtx.run();
					gtx.jump();
				}
			}

			abstract class Person {
				public abstract void eat();
				
				public abstract void drink();
				
				public abstract void sleep();
				
				public abstract void run();
				
				public abstract void jump();
			}

			class 托尼 extends Person {
				@Override
				public void eat() {
					System.out.println("吃肉");
				}

				@Override
				public void drink() {
					System.out.println("喝水");
				}

				@Override
				public void sleep() {
					System.out.println("睡觉");
				}

				@Override
				public void run() {
					System.out.println("正常跑");
				}

				@Override
				public void jump() {
					System.out.println("正常跳");
				}
			}

			class 钢铁侠 extends Person {
				private Person person;
				
				public 钢铁侠(Person person) {//Person person = new 托尼();
					this.person = person;
				}

				@Override
				public void eat() {
					person.eat();//托尼.eat()
				}

				@Override
				public void drink() {
					person.drink();//托尼.drink();
				}

				@Override
				public void sleep() {
					person.sleep();//托尼.sleep();
				}

				@Override
				//方法功能增强了
				public void run() {
					System.out.println("超级跑");
				}

				@Override
				//方法功能增强了
				public void jump() {
					System.out.println("超级跳");
				}
			}
			
		2.
			public class Demo02 {
				public static void main(String[] args) {
					FileInputStream fis = new FileInputStream("aaa.txt");
					int by = fis.read();
					System.out.println(by);
					fis.close();
					
					BufferedInputStream bis = new BufferedInputStream(new FileInputStream("aaa.txt"));
					int by = bis.read();
					System.out.println(by);
					bis.close();
				}
			}

			abstract class InputStream {
				public abstract int read();
				public abstract int read(byte[] bys);
				public abstract void close();
				public abstract void aaa();
				public abstract void bbb();
				public abstract void ccc();
			}

			class FileInputStream extends InputStream {
				public FileInputStream(String path) {
					
				}
				
				@Override
				public int read() {
					xxxooo
					return 0;
				}

				@Override
				public int read(byte[] bys) {
					xxxooo
					return 0;
				}

				@Override
				public void close() {
					xxxooo
				}

				@Override
				public void aaa() {
					xxxooo
				}

				@Override
				public void bbb() {
					xxxooo
				}

				@Override
				public void ccc() {
					xxxooo
				}
			}

			class BufferedInputStream extends InputStream {
				private InputStream is;
				
				public BufferedInputStream(InputStream is) {
					this.is = is;
				}

				@Override
				public int read() {
					增强的代码
					return 0;
				}

				@Override
				public int read(byte[] bys) {
					增强的代码
					return 0;
				}

				@Override
				public void close() {
					is.close();
				}

				@Override
				public void aaa() {
					is.aaa();
				}

				@Override
				public void bbb() {
					is.bbb();
				}

				@Override
				public void ccc() {
					is.ccc();
				}
				
			}
			
```

# 字符流

```java
为什么会有字符流呢?
		因为在有些情况下使用字节流是无法完成的
		比如说当我们对有中文文件进行读取操作的时候,就会出现乱码问题
		
		字符流 = 字节流 + 编码表
```

# 编码表

```java
ASCII:是所有编码表中最最基础的编码表,里面的内容很少,只有26个大小写的英文字母,数字和一些特殊符号组成
	
	GBK:中国的编码表,收录汉字有21003个,一个汉字占2个字节,里面囊括了ASCII
	
	Unicode:
		统一码(Unicode),也叫万国码、单一码,是计算机科学领域里的一项业界标准,包括字符集、编码方案等。
		Unicode是为了解决传统的字符编码方案的局限而产生的,
		它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求
		里面囊括了ASCII
	
		*UTF-8:一个中文占3个字节
		UTF-16:一个中文占2个字节
		UTF-32:一个中文占4个字节
```

# 字符串的编码和解码

```java
编码?
		字符串变成字节数据
		
		怎么实现编码操作?
			public byte[] getBytes():使用平台的默认字符集将此 String 编码为 byte数组
			public byte[] getBytes(String charsetName):使用指定的字符集将此 String 编码为 byte数组
	
	解码?
		字节数据变成字符串
		
		怎么实现解码操作?
			public String(byte[] bytes):通过使用平台的默认字符集解码指定的 byte 数组
			public String(byte[] bytes,String charsetName):通过使用指定的 charset 解码指定的 byte 数组

```

# FileWriter

```java
字符输出流
	
	常见的构造方法?
		public FileWriter(File file)
		public FileWriter(String fileName)
		public FileWriter(File file, boolean append)
		public FileWriter(String fileName, boolean append)
	
	常见的成员方法?
		public void write(int c)
		public void write(char[] cbuf)
		public void write(char[] cbuf,int off,int len)
		public void write(String str)
		public void write(String str,int off,int len)
```

# FileReader

```java
字符输入流
	
	常见的构造方法?
		public FileReader(File file)
		public FileReader(String fileName)
	
	常见的成员方法?
		public int read()
		public int read(char[] cbuf)
```

# 文件复制

```java

```

方式五:普通字符输入流 + 普通字符输出流:一次读取一个字符,一次写出一个字符
		//创建字符输入流对象
		FileReader fr = new FileReader("aaa.txt");
		

		//创建字符输出流对象
		FileWriter fw = new FileWriter("bbb.txt");
		
		//一次读取一个字符,一次写出一个字符
		int ch = 0;
		while((ch = fr.read()) != -1) {
			fw.write(ch);
		}
		
		//释放资源
		fw.close();
		fr.close();
	方式六:普通字符输入流 + 普通字符输出流:一次读取一个字符数组,一次写出一个字符的一部分
		//创建字符输入流对象
		FileReader fr = new FileReader("aaa.txt");
		
		//创建字符输出流对象
		FileWriter fw = new FileWriter("ccc.txt");
		
		//一次读取一个字符数组,一次写出一个字符数组的一部分
		char[] chs = new char[1024];
		int len = 0;
		while((len = fr.read(chs)) != -1) {
			fw.write(chs, 0, len);
		}
		
		//释放资源
		fw.close();
		fr.close();

# BufferedWriter

```java
缓冲字符输出流
	高效字符输出流
	提高效率
	
	常见的构造方法?
		public BufferedWriter(Writer out)
	
	常见的成员方法?
		和FileWriter是一样的
	
		特有方法:public void newLine():换行,会根据不同的操作系统变化换行符
```

# BufferedReader

```java
缓冲字符输入流
	高效字符输入流
	提高效率
	
	常见的构造方法?
		public BufferedReader(Reader in)
	常见的成员方法?
		和FileReader是一样的
		
		特有方法:public String readLine():一次读取一行
```

# 复制文件

```java
方式七:高效字符输入流 + 高效字符输出流:一次读取一个字符,一次写出一个字符
		//创建高效字符输入流对象
		BufferedReader br = new BufferedReader(new FileReader("Demo01.java"));
		
		//创建高效字符输出流对象
		BufferedWriter bw = new BufferedWriter(new FileWriter("Demo02.java"));
		
		//一次读取一个字符,一次写出一个字符
		int ch = 0;
		while((ch = br.read()) != -1) {
			bw.write(ch);
		}
		
		//释放资源
		bw.close();
		br.close();
	方式八:高效字符输入流 + 高效字符输出流:一次读取一个字符数组,一次写出一个字符数组的一部分
		//创建高效字符输入流对象
		BufferedReader br = new BufferedReader(new FileReader("Demo01.java"));
		
		//创建高效字符输出流对象
		BufferedWriter bw = new BufferedWriter(new FileWriter("Demo03.java"));
		
		//一次读取一个字符数组,一次写出一个字符数组的一部分
		char[] chs = new char[1024];
		int len = 0;
		while((len = br.read(chs)) != -1) {
			bw.write(chs, 0, len);
		}
		
		//释放资源
		bw.close();
		br.close();
	方式九:高效字符输入流 + 高效字符输出流:一次读取一个行,一次写出一行
		//创建高效字符输入流对象
		BufferedReader br = new BufferedReader(new FileReader("Demo01.java"));
		
		//创建高效字符输出流对象
		BufferedWriter bw = new BufferedWriter(new FileWriter("Demo04.java"));
		
		//一次读取一行,一次写出一个字符串
		String line = null;
		while((line = br.readLine()) != null) {
			bw.write(line);
			bw.newLine();
		}
		
		//释放资源
		bw.close();
		br.close();
```

# 字符流和字节流复制文件的区别

```java
字节流:万能流,也就是说使用字节流复制任何类型的文件都可以
	
	字符流:不是万能流,只能复制我们看得懂的文件
	
	能看懂的文件:
		.txt
		.java
		...
	
	看不懂的文件:
		.jpg
		.mp3
		.mp4
		.avi
```

# 转换流

```java
什么是转换流?
		能将字节流转换成字符流的流就称为转换流
		转换流是所有流中唯一可以设置编码的流
		
	a.OutputStreamWriter
		转换字符输出流
		
		常见的构造方法?
			public OutputStreamWriter(OutputStream out)
			public OutputStreamWriter(OutputStream out, String charsetName)
		
		常见的成员方法?
			和FileWriter是一样的
	
	b.InputStreamReader
		转换字符输入流对象
	
		常见的构造方法?
			public InputStreamReader(InputStream in)
			public InputStreamReader(InputStream in,String charsetName)

		常见的成员方法?
			和FileReader是一样的
```

# 复制文件

````java
方式一:
		//创建转换输入流对象
		InputStreamReader isr = new InputStreamReader(new FileInputStream("aaa.txt"));
		
		//创建转换输出流对象
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("bbb.txt"));
		
		//一次读取一个字符,一次写出一个字符
		int ch = 0;
		while((ch = isr.read()) != -1) {
			osw.write(ch);
		}
		
		//释放资源
		osw.close();
		isr.close();
		
	方式二:
		//创建转换输入流对象
		InputStreamReader isr = new InputStreamReader(new FileInputStream("aaa.txt"));
		
		//创建转换输出流对象
		OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("ccc.txt"));
		
		//一次读取一个字符数组,一次写出一个字符数组的一部分
		char[] chs = new char[1024];
		int len = 0;
		while((len = isr.read(chs)) != -1) {
			osw.write(chs, 0, len);
		}
		
		//释放资源
		osw.close();
		isr.close();
	
	方式三:
		//创建高效字符输入流对象
		BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("aaa.txt")));
		
		//创建高效字符输出流对象
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("ddd.txt")));
		
		//一次读取一个字符,一次写出一个字符
		int ch = 0;
		while((ch = br.read()) != -1) {
			bw.write(ch);
		}
		
		//释放资源
		bw.close();
		br.close();
	
	方式四:
		//创建高效字符输入流对象
		BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("aaa.txt")));
		
		//创建高效字符输出流对象
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("eee.txt")));
		
		//一次读取一个字符数组,一次写出一个字符数组的一部分
		char[] chs = new char[1024];
		int len = 0;
		while((len = br.read(chs)) != -1) {
			bw.write(chs, 0, len);
		}
		
		//释放资源
		bw.close();
		br.close();
	
	方式五:
		//创建高效字符输入流对象
		BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("aaa.txt")));
		
		//创建高效字符输出流对象
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream("fff.txt")));
		
		//一次读取一行,一次写出一行
		String line = null;
		while((line = br.readLine()) != null) {
			bw.write(line);
			bw.newLine();
		}
		
		//释放资源
		bw.close();
		br.close();

方式六:
		写法一:
			//创建高效字符输入流对象
			BufferedReader br = new BufferedReader(new FileReader("aaa.txt"));
			
			//创建打印流对象
			PrintWriter pw = new PrintWriter("bbb.txt");
			
			//一次读取一行,一次打印一行
			String line = null;
			while((line = br.readLine()) != null) {
				pw.println(line);
			}
			
			//释放资源
			pw.close();
			br.close();
		
		写法二:
			//创建高效字符输入流对象
			BufferedReader br = new BufferedReader(new FileReader("aaa.txt"));
			
			//创建打印流对象
			PrintWriter pw = new PrintWriter(new FileWriter("ccc.txt"), true);
			
			//一次读取一行,一次打印一行
			String line = null;
			while((line = br.readLine()) != null) {
				pw.println(line);
			}
			
			//释放资源
			br.close();
````

# 打印流

```java
打印用到的流就是打印流,打印流是一个输出流
	PrintStream
	PrintWriter	
	
	PrintWriter?
		常见的构造方法?
			public PrintWriter(String fileName)
			public PrintWriter(Writer out, boolean autoFlush)
				注意:
					开启自动刷新的条件:
						1.autoFlush为true
						2.println、printf 或 format方法
			
		常见的成员方法?
			和FileWriter是一样的
			
			特有的方法:
				public void println(XXX xxx)
				
			println()和writer()方法的区别?
				1.println()自带换行,writer()不带换行
				2.println()可以接受任意类型的数据,writer()只能几种类型的数据
				3.println()能够开启刷新,writer()不能开启刷新
			
```

# 对象操作流

```java
用来操作对象的流就是对象操作流
	
	注意:想要实现序列化和反序列化操作,该类要实现序列化接口
	
	a.ObjectOutputStream
		序列化流
		
		什么是序列化?
			是指将对象从内存中写出到本地磁盘中
			
			对象 内存 -> 磁盘
			
		常见的构造方法?
			public ObjectOutputStream(OutputStream out)
		
		常见的成员方法?
			public final void writeObject(Object obj)
	
	b.ObjectInputStream
		反序列化流
	
		什么是反序列化?
			是指将本地磁盘中的数据还原成内存中的对象
			
			对象 磁盘 -> 内存
			
		常见的构造方法?
			public ObjectInputStream(InputStream in)
		
		常见的构造方法?
			public final Object readObject()
```

# Properties

```java
双列集合
	
	Properties 类表示了一个持久的属性集。
	Properties 可保存在流中或从流中加载。
	属性列表中每个键及其对应值都是一个字符串
	
	常见的构造方法?
		public Properties()
	
	常见的成员方法?
		和map是一样的
		put()
		get()
		
		特有方法?
			public Object setProperty(String key, String value)
			*public String getProperty(String key)
			public Set<String> stringPropertyNames()
			
			和IO流相关方法:
			public void store(OutputStream out,String comments):将集合中的数据存储到文件中
			*public void load(InputStream inStream):将文件中的数据加载到集合容器中

	Properties的作用?
		用来加载配置文件的
			
```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值