Java基础语法总览

JAVA基础

java进阶(学完基础后再看)

基础语法通识

关键字
(1)被Java语言赋予特定含义的单词
(2)特点:
	全部小写。
(3)注意事项:
	A:goto和const作为保留字存在。
	B:类似于Notepad++这样的高级记事本会对关键字有特殊颜色标记
标识符
(1)就是给类,接口,方法,变量等起名字的字符序列
(2)组成规则:
	A:英文大小写字母
	B:数字
	C:$和_
(3)注意事项:
	A:不能以数字开头
	B:不能是java中的关键字
	C:区分大小写
(4)常见的命名规则(见名知意)
	A:包	全部小写
		单级包:小写
			举例:liuyi,com
		多级包:小写,并用.隔开
			举例:cn.itcast,com.baidu				
	B:类或者接口
		一个单词:首字母大写
			举例:Student,Demo
		多个单词:每个单词首字母大写
			举例:HelloWorld,StudentName
	C:方法或者变量
		一个单词:首字母小写
			举例:name,main
		多个单词:从第二个单词开始,每个单词首字母大写
			举例:studentAge,showAllNames()
	D:常量
		全部大写
		一个单词:大写
			举例:PI
		多个单词:大写,并用_隔开
			举例:STUDENT_MAX_AGE
注释(掌握)
(1)就是对程序进行解释说明的文字
(2)分类:
	A:单行注释	//
	B:多行注释	/**/
	C:文档注释 /** */
(3)把HelloWorld案例写了一个带注释的版本。
	后面我们要写一个程序的过程。
	需求:
	分析:
	实现:
	代码体现:
(4)注释的作用
	A:解释说明程序,提高了代码的阅读性。
	B:可以帮助我们调试程序。
		后面我们会讲解一个更高端的一个调试工具
常量
(1)在程序执行的过程中,其值不发生改变的量
(2)分类:
	A:字面值常量
	B:自定义常量
(3)字面值常量
	A:字符串常量 "hello"
	B:整数常量	12,23
	C:小数常量	12.345
	D:字符常量	'a','A','0'
	E:布尔常量	true,false
	F:空常量	null
(4)在Java中针对整数常量提供了四种表现形式
	A:二进制	由0,1组成。以0b开头。
	B:八进制	由0,1,...7组成。以0开头。
	C:十进制	由0,1,...9组成。整数默认是十进制。
	D:十六进制	由0,1,...9,a,b,c,d,e,f(大小写均可)组成。以0x开头。
变量
(1)在程序的执行过程中,其值在某个范围内可以发生改变的量
(2)变量的定义格式:
	A:数据类型 变量名 = 初始化值;
	B:数据类型 变量名;
	  变量名 = 初始化值;
数据类型
(1)Java是一种强类型语言,针对每种数据都提供了对应的数据类型。
(2)分类:
	A:基本数据类型:4类8种
	B:引用数据类型:类,接口,数组。
(3)基本数据类型
	A:整数			占用字节数
		byte			1
		short			2
		int 			4
		long			8
	B:浮点数
		float			4
		double			8
	C:字符
		char			2
	D:布尔
		boolean			1
		
	==注意==:
		整数默认是int类型,浮点数默认是double。
		长整数要加L或者l。
		单精度的浮点数要加F或者f。
数据类型转换
(1)boolean类型不参与转换
(2)默认转换
	A:从小到大
	B:byte,short,char -- int -- long -- float -- double
	C:byte,short,char之间不相互转换,直接转成int类型参与运算。
(3)强制转换
	A:从大到小
	B:可能会有精度的损失,一般不建议这样使用。
	C:格式:
		目标数据类型 变量名 = (目标数据类型) (被转换的数据
运算符
(1)算术运算符
	A:+,-,*,/,%,++,--
	B:+的用法
		a:加法
		b:正号
		c:字符串连接符
	C:/和%的区别
		数据做除法操作的时候,/取得是商,%取得是余数
	D:++和--的用法
		a:他们的作用是自增或者自减
		b:使用
			**单独使用
				放在操作数据的前面和后面效果一样。
				a++或者++a效果一样。
			**参与操作使用
				放在操作数的前面:先自增或者自减,再参与操作
					int a = 10;
					int b = ++a;
				放在操作数的后面:先参与操作,再自增或者自减
					int a = 10;
					int b = a++;
(2)赋值运算符
	A:=,+=,-=,*=,/=,%=等
	B:=叫做赋值运算符,也是最基本的赋值运算符
		int x = 10; 把10赋值给int类型的变量x。
	C:扩展的赋值运算符的特点
		隐含了自动强制转换。
(3)比较运算符
	A:==,!=,>,>=,<,<=
	B:无论运算符两端简单还是复杂最终结果是boolean类型。
	C:千万不要把==写成了=
(4)逻辑运算符
	A:&,|,^,!,&&,||
	B:逻辑运算符用于连接boolean类型的式子
	C:结论
		&:有false则false
		|:有true则true
		^:相同则false,不同则true。
		!:非true则false,非false则true
		&&:结果和&是一样的,只不过有短路效果。左边是false,右边不执行。
		||:结果和|是一样的,只不过有短路效果。左边是true,右边不执行。
(5)位运算符(了解)
	A:^的特殊用法
		一个数据针对另一个数据位异或两次,该数不变
	B:面试题
		a:请实现两个变量的交换
			**采用第三方变量
			**用位异或运算符
				左边a,b,a
				右边a^b
		b:请用最有效率的方式计算出2乘以8的结果
			2<<3
(6)三元运算符
	A:格式
		比较表达式?表达式1:表达式2;
	B:执行流程:
		首先计算比较表达式的值,看是true还是false。
		如果是true,表达式1就是结果。
		如果是false,表达式2就是结果。
	C:案例:
		a:比较两个数据是否相等
		b:获取两个数据中的最大值
		c:获取三个数据中的最大值
流程控制语句
(1)顺序结构 从上往下,依次执行
(2)选择结构	按照不同的选择,执行不同的代码
(3)循环结构 做一些重复的代码
if语句
(1)三种格式
	A:格式1
		if(比较表达式) {
			语句体;
		}
		
		执行流程:
			判断比较表达式的值,看是true还是false
			如果是true,就执行语句体
			如果是false,就不执行语句体
	
	B:格式2
		if(比较表达式) {
			语句体1;
		}else {
			语句体2;
		}
		
		执行流程:
			判断比较表达式的值,看是true还是false
			如果是true,就执行语句体1
			如果是false,就执行语句体2
			
	C:格式3
		if(比较表达式1) {
			语句体1;
		}else if(比较表达式2){
			语句体2;
		}
		...
		else {
			语句体n+1;
		}
		
		执行流程:
			判断比较表达式1的值,看是true还是false
			如果是true,就执行语句体1
			如果是false,就继续判断比较表达式2的值,看是true还是false
			如果是true,就执行语句体2
			如果是false,就继续判断比较表达式3的值,看是true还是false
			...
			如果都不满足,就执行语句体n+1
(2)注意事项
	A:比较表达式无论简单还是复杂,结果是boolean类型
	B:if语句控制的语句体如果是一条语句,是可以省略大括号的;如果是多条,不能省略。
		建议:永远不要省略。
	C:一般来说,有左大括号,就没有分号,有分号,就没有左大括号。
	D:else后面如果没有if,是不会出现比较表达式的。
	E:三种if语句其实都是一个语句,只要有一个执行,其他的就不再执行。
(3)三元运算符和if语句第二种格式的关系
	所有的三元运算符能够实现的,if语句的第二种格式都能实现。
	反之不成立。
	
	如果if语句第二种格式控制的语句体是输出语句,就不可以。
	因为三元运算符是一个运算符,必须要有一个结果返回,不能是一个输出语句。
switch语句(掌握)
(1)格式:
	switch(表达式) {
		case 值1:
			语句体1;
			break;
		case 值2:
			语句体2;
			break;
		...
		default:
			语句体n+1;
			break;
	}
	格式解释说明:
		switch:说明这是switch语句。
		表达式:可以是byte,short,int,char
			JDK5以后可以是枚举
			JDK7以后可以是字符串
		case:后面的值就是要和表达式进行比较的值
		break:表示程序到这里中断,跳出switch语句
		default:如果所有的情况都不匹配,就执行这里,相当于if语句中的else
(2)执行流程:
	A:首先计算表达式的值
	B:和每一个case进行匹配,如果有就执行对应的语句体,看到break就结束。
	C:如果没有匹配,就执行default的语句体n+1。
(3)注意事项:
	A:case后面只能是常量,不能是变量,而且,多个case后面的值不能出现相同的
	B:default可以省略吗?
		可以省略,但是不建议,因为它的作用是对不正确的情况给出提示。
		特殊情况:
			case就可以把值固定。
			A,B,C,D
	C:break可以省略吗?
		可以省略,但是结果可能不是我们想要的。
		会出现一个现象:case穿透。
		最终我们建议不要省略
	D:default一定要在最后吗?
		不是,可以在任意位置。但是建议在最后。
	E:switch语句的结束条件
		a:遇到break就结束了
		b:执行到末尾就结束了
(4)if语句和switch语句各自的场景
	A:if
		针对boolean类型的判断
		针对一个范围的判断
		针对几个常量的判断
	B:switch
		针对几个常量的判断
循环语句
(1)有三种:for,while,do...while
(2)for循环语句
	A:格式
		for(初始化语句;判断条件语句;控制条件语句){
			循环体语句;
		}
		
		执行流程:
			a:执行初始化语句
			b:执行判断条件语句
				如果这里是true,就继续
				如果这里是false,循环就结束
			c:执行循环体语句
			d:执行控制条件语句
			e:回到b
	B:注意事项
		a:判断条件语句无论简单还是复杂,结果是boolean类型
		b:循环体语句如果是一条,可以省略大括号,但是不建议
		c:有分号就没有左大括号,有左大括号就没有分号
(3)while循环
	A:基本格式
		while(判断条件语句) {
			循环体语句;
		}
		
		扩展格式:
		初始化语句;
		while(判断条件语句){
			循环体语句;
			控制条件语句;
		}
		
		通过查看这个格式,我们就知道while循环可以和for循环等价转换。
	B:while的练习
		把for语句的练习用while改进
	C:for和while的区别
		a:使用上的区别
			for语句的那个控制条件变量,在循环结束后不能在使用了。
			而while的可以继续使用。
		b:理解上的区别
			for适合于一个范围的判断
			while适合次数不明确的
				举例:吃葡萄
(4)do...while循环
	A:基本格式
		do {
			循环体语句;
		}while(判断条件语句);
		
		扩展格式:
		初始化语句;
		do {
			循环体语句;
			控制条件语句;
		}while(判断条件语句);
		
		通过查看格式,我们就可以看出其实三种循环的格式可以是统一的。
	B:三种循环的区别
		a:do...while循环至少执行一次循环体
		b:for和while必须先判断条件是否是true,然后后才能决定是否执行循环体
(5)循环使用的注意事项(死循环)
	A:一定要注意修改控制条件,否则容易出现死循环。
	B:最简单的死循环格式
		a:while(true){...}
		
		b:for(;;){}
控制跳转语句
(1)break:中断的意思
	A:用在循环和switch语句中,离开此应用场景无意义。
	B:作用
		a:跳出单层循环
		b:跳出多层循环,需要标签语句的配合
(2)continue:继续
	A:用在循环中,离开此应用场景无意义。
	B:作用
		a:跳出单层循环的一次,可以继续下一次
	C:填空题
		for(int x=1; x<=10; x++) {
			if(x%3 == 0) {
				//补齐代码
			}
			System.out.println("Java基础班");
		}
		如何让控制台输出2次:Java基础班
		如何让控制台输出7次:Java基础班
		如何让控制台输出13次:Java基础班
(3)return:返回
	A:用于结束方法的,后面还会在继续讲解和使用。
	B:一旦遇到return,程序就不会在继续往后执行。

不同的基础点

键盘录入
(1)实际开发中,数据是变化的,为了提高程序的灵活性,我们加入键盘录入数据。
(2)如何实现呢?目前就记住
	A:导包
		import java.util.Scanner;
		位置:在class的上边
	B:创建对象
		Scanner sc = new Scanner(System.in);
	C:获取数据
		如:int x = sc.nextInt();
		常用的
		next():读取输入知道空格。不能读取有空格或符号隔开的单词,读取后光标在本行
		nextLine():能读取所有直到行尾
		nextByte()
		nextDouble()
		nextFloat()
		nextLong()
		nextShort()
	D:用完后要记得close()
方法(掌握)
(1)方法:就是完成特定功能的代码块。
	注意:在很多语言里面有函数的定义,而在Java中,函数被称为方法。
(2)格式:
	修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2...) {
		方法体语句;
		return 返回值;
	}
	修饰符:
	default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用		对象:类、接口、变量、方法
	private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外		部类)
	public : 对所有类可见。使用对象:类、接口、变量、方法
	protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注		意:不能修饰类(外部类)
	返回值类型:就是功能结果的数据类型
	方法名:就是起了一个名字,方便我们调用该方法。
	参数类型:就是参数的数据类型
	参数名:就是变量
	参数分类:
		实参:实际参与运算的数据
		形参:方法上定义的,用于接收实际参数的变量
	方法体语句:就是完成功能的代码块
	return:结束方法
	返回值:就是功能的结果,由return带给调用者。
(3)两个明确:
	返回值类型:结果的数据类型
	参数列表:参数的个数及对应的数据类型
(4)方法调用
	A:有明确返回值的方法
		a:单独调用,没有意义
		b:输出调用,不是很好,因为我可能需要不结果进行进一步的操作。但是讲课一般我就用了。
		c:赋值调用,推荐方案
	B:void类型修饰的方法
		a:单独调用
(5)案例:
	A:求和方案
	B:获取两个数中的较大值
	C:比较两个数据是否相同
	D:获取三个数中的最大值
	E:输出m行n列的星形
	F:输出nn乘法表
(6)方法的注意事项
	A:方法不调用不执行
	B:方法之间是平级关系,不能嵌套定义
	C:方法定义的时候,参数是用,隔开的
	D:方法在调用的时候,不用在传递数据类型
	E:如果方法有明确的返回值类型,就必须有return语句返回。
(7)**方法重载**
	在同一个类中,方法名相同,参数列表不同。与返回值无关。
	
	参数列表不同:
		参数的个数不同。
		参数的对应的数据类型不同。
(8)方法重载案例
	不同的类型的多个同名方法的比较。
数组
(1)数组:存储同一种数据类型的多个元素的容器。
(2)特点:每一个元素都有编号,从0开始,最大编号是长度-1。
         编号的专业叫法:索引
(3)定义格式
	A:数据类型[] 数组名;
	B:数据类型 数组名[];
	
	推荐是用A方式,B方法就忘了吧。
	但是要能看懂
(4)数组的初始化
	A:动态初始化
		只给长度,系统给出默认值
		
		举例:int[] arr = new int[3];
	B:静态初始化
		给出值,系统决定长度
		
		举例:int[] arr = new int[]{1,2,3};
		简化版:int[] arr = {1,2,3};
(5)数组内存图
	A:一个数组
	B:二个数组
	C:三个数组(两个栈变量指向同一个堆内存)
	![](file://D:/blog/post-images/1569138701134.bmp)
二维数组
(1)元素是一维数组的数组。
(2)格式:
	A:数据类型[][] 数组名 = new 数据类型[m][n];
	B:数据类型[][] 数组名 = new 数据类型[m][];
	C:数据类型[][] 数组名 = new 数据类型[][]{{...},{...},{...}};
	D:数据类型[][] 数组名 = {{...},{...},{...}};
Java的内存分配
	A:栈 存储局部变量
	B:堆 存储所有new出来的
	C:方法区(面向对象部分详细讲解)
	D:本地方法区(系统相关)
	E:寄存器(CPU使用)
	
	注意:
		a:局部变量 在方法定义中或者方法声明上定义的变量。
		b:栈内存和堆内存的区别
			栈:数据使用完毕,就消失。
			堆:每一个new出来的东西都有地址
			    每一个变量都有默认值
					byte,short,int,long 0
					float,double 0.0
					char '\u0000'
					boolean false
					引用类型 null
			    数据使用完毕后,在垃圾回收器空闲的时候回收。

在这里插入图片描述

面向对象

基本概念
(1)面向对象
	面向对象是基于面向过程的编程思想
(2)面向对象的思想特点
	A:是一种更符合我们思考习惯的思想
	B:把复杂的事情简单化
	C:让我们从执行者变成了指挥者
	
	举例:
		买电脑
		洗衣服
		做饭
		...
		万事万物皆对象
(3)类与对象
	A:现实世界的事物
		属性	事物的基本描述
		行为	事物的功能
	B:Java语言中最基本的单位是类。所以,我们要用类来体现事物
	C:类
		成员变量	事物属性
		成员方法	事物行为
	D:类:是一组相关的属性和行为的集合。是一个抽象的概念。
	  对象:是该类事物的具体存在,是一个具体的实例。(对象)
	  
	  举例:
		学生:类
		班长:对象
(4)类的定义及使用
	A:类的定义
		成员变量	定义格式和以前一样,就是位置不同,在类中,方法外。
		成员方法	定义格式和以前一样,就是去掉了static。
	B:使用类的内容
		a:创建对象? 格式
			类名 对象名 =  new 类名();
		b:如何使用成员变量和成员方法呢
			对象名.成员变量
			对象名.成员方法()
(5)案例:
	A:学生类的定义和使用
	B:手机类的定义和使用
(6)内存图
	A:一个对象的内存图
	B:二个对象的内存图
	C:三个对象的内存图
	
(7)Java程序的开发,设计和特征
	A:开发:就是不断的创建对象,通过对象调用功能
	B:设计:就是管理和维护对象间的关系
	C:特征
		a:封装
		b:继承
		c:多态
一些关键理解
成员变量和局部变量的区别
(1)在类中的位置不同
	成员变量:类中方法外
	局部变量:方法定义中或者方法声明上
(2)在内存中的位置不同
	成员变量:在堆中
	局部变量:在栈中
(3)生命周期不同
	成员变量:随着对象的创建而存在,随着对象的消失而消失
	局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
(4)初始化值不同
	成员变量:有默认值
	局部变量:没有默认值,必须定义,赋值,然后才能使用
类作为形式参数的问题?
(1)如果你看到一个方法需要的参数是一个类名,就应该知道这里实际需要的是一个具体的对象。
匿名对象
(1)没有名字的对象
(2)应用场景
	A:调用方法,仅仅只调用一次的时候。
	b:可以作为实际参数传递。
封装(理解)
(1)隐藏实现细节,提供公共的访问方式
(2)好处:
	A:隐藏实现细节,提供公共的访问方式
	B:提高代码的复用性
	C:提高代码的安全性
(3)设计原则
	把不想让外界知道的实现细节给隐藏起来,提供公共的访问方式
(4)private是封装的一种体现。
	封装:类,方法,private修饰成员变量
private关键字再提
(1)私有的意义,可以修饰成员变量和成员方法
(2)特点:
	被private修饰的后的成员只能在本类中被访问
(3)private的应用:
	以后再写一个类的时候:
		把所有的成员变量给private了
		提供对应的getXxx()/setXxx()方法
this关键字
(1)代表当前类的引用对象
	记住:哪个对象调用方法,该方法内部的this就代表那个对象
(2)this的应用场景:
	A:解决了局部变量隐藏成员变量的问题
	B:其实this还有其他的应用,明天讲解。
构造方法
(1)作用:用于对对象的数据进行初始化
(2)格式:
	A:方法名和类名相同
	B:没有返回值类型,连void都不能有
	C:没有返回值

(3)构造方法的注意事项
	A:如果我们没写构造方法,系统将提供一个默认的无参构造方法
	B:如果我们给出了构造方法,系统将不再提供默认构造方法
		如果这个时候,我们要使用无参构造方法,就必须自己给出。
		推荐:永远手动自己给出无参构造方法。
(4)给成员变量赋值的方式
	A:setXxx()
	B:带参构造方法
建立一个对象发生了什么?
以Student s = new Student()为例

(1)把Student.class文件加载到内存
(2)在栈内存为s开辟空间
(3)在堆内存为学生对象申请空间
(4)给学生的成员变量进行默认初始化。null,0
(5)给学生的成员变量进行显示初始化。林青霞,27             
(6)通过构造方法给成员变量进行初始化。刘意,30
(7)对象构造完毕,把地址赋值给s变量

在这里插入图片描述

static关键字
(1)静态的意思。可以修饰成员变量和成员方法。
(2)静态的特点:
	A:随着类的加载而加载
	B:优先与对象存在
	C:被类的所有对象共享
		这其实也是我们判断该不该使用静态的依据。
		举例:饮水机和水杯的问题思考
	D:可以通过类名调用
		既可以通过对象名调用,也可以通过类名调用,建议通过类名调用。
(3)静态的内存图
	静态的内容在方法区的静态区

在这里插入图片描述

(4)静态的注意事项;
	A:在静态方法中没有this对象
	B:静态只能访问静态(代码测试过)
(5)静态变量和成员变量的区别
	A:所属不同
		静态变量:属于类,类变量
		成员变量:属于对象,对象变量,实例变量
	B:内存位置不同
		静态变量:方法区的静态区
		成员变量:堆内存
	C:生命周期不同
		静态变量:静态变量是随着类的加载而加载,随着类的消失而消失
		成员变量:成员变量是随着对象的创建而存在,随着对象的消失而消失
	D:调用不同
		静态变量:可以通过对象名调用,也可以通过类名调用
		成员变量:只能通过对象名调用
(6)main方法是静态的
	public:权限最大
	static:不用创建对象调用
	void:返回值给jvm没有意义
	main:就是一个常见的名称。
	String[] args:可以接收数据,提供程序的灵活性
		格式:java MainDemo hello world java
			  java MainDemo 10 20 30
(7)一些小用法
可以把构造方法私有化,外界就无法创建对象了,自己可以通过静态化方法调用类中的方法
(8)内存图解

在这里插入图片描述

代码块
(1)用{}括起来的代码。
(2)分类:
	A:局部代码块
		用于限定变量的生命周期,及早释放,提高内存利用率。
	B:构造代码块
		把多个构造方法中相同的代码可以放到这里,每个构造方法执行前,首先执行构造代码块。
	C:静态代码块
		对类的数据进行初始化,仅仅只执行一次。
(3)静态代码块,构造代码块,构造方法的顺序问题?
	静态代码块 > 构造代码块 > 构造方法
继承
(1)把多个类中相同的成员给提取出来定义到一个独立的类中。然后让这多个类和该独立的类产生一个关系,这多个类就具备了这些内容。这个关系叫继承。
(2)Java中如何表示继承呢?格式是什么呢?
	A:用关键字extends表示
	B:格式:
		class 子类名 extends 父类名 {}
(3)继承的好处:
	A:提高了代码的复用性
	B:提高了代码的维护性
	C:让类与类产生了一个关系,是多态的前提
(4)继承的弊端:
	A:让类的耦合性增强。这样某个类的改变,就会影响其他和该类相关的类。
		原则:低耦合,高内聚。
		耦合:类与类的关系
		内聚:自己完成某件事情的能力
	B:打破了封装性
(5)Java中继承的特点
	A:Java中类只支持单继承
	B:Java中可以多层(重)继承(继承体系) 即a继承b,b继承c,则a也同时继承c
(6)继承的注意事项:
	A:子类不能继承父类的私有成员(方法或者变量)
	B:子类不能继承父类的构造方法,但是可以通过super去访问
	C:不要为了部分功能而去继承
(7)什么时候使用继承呢?
	A:继承体现的是:is a的关系。
	B:采用假设法
(8)Java继承中的成员关系
	A:成员变量
		a:子类的成员变量名称和父类中的成员变量名称不一样,这个太简单
		b:子类的成员变量名称和父类中的成员变量名称一样,这个怎么访问呢?
			子类的方法访问变量的查找顺序:
				在子类方法的局部范围找,有就使用。
				在子类的成员范围找,有就使用。
				在父类的成员范围找,有就使用。
				找不到,就报错。
	B:构造方法
		a:子类的构造方法默认会去访问父类的无参构造方法
			是为了子类访问父类数据的初始化
			子类构造方法第一条语句默认为super()
		b:父类中如果没有无参构造方法,怎么办?
			子类通过super去明确调用带参构造 super(...)
			子类通过this调用本身的其他构造,但是一定会有一个去访问了父类的构造
			让父类提供无参构造 this(...)
			子类中一定得有一个去访问了父类的构造方法,否则父类数据就没有初始化
	注意事项:
	super(…)或者this(….)必须出现在第一条语句
	
	C:成员方法
		a:子类的成员方法和父类中的成员方法名称不一样,这个太简单
		b:子类的成员方法和父类中的成员方法名称一样,这个怎么访问呢?
			通过子类对象访问一个方法的查找顺序:
				在子类中找,有就使用
				在父类中找,有就使用
				找不到,就报错
(9)两个面试题:
	A:Override(重写)和Overload(重载)的区别?Overload是否可以改变返回值类型?
	重写不能重写父类私有方法
	子类重写父类方法时,权限不能更低
	B:this和super的区别和各自的作用?
(10)数据初始化的面试题
	A:一个类的初始化过程
		成员变量进行初始化
			默认初始化
			显示初始化
			构造方法初始化
	B:子父类的构造执行过程
	C:分层初始化
final关键字
(1)是最终的意思,可以修饰类,方法,变量。
(2)特点:
	A:它修饰的类,不能被继承。
	B:它修饰的方法,不能被重写。
	C:它修饰的变量,是一个常量。
(3)面试相关:
	A:局部变量
		a:基本类型 值不能发生改变
		b:引用类型 地址值不能发生改变,但是对象的内容是可以改变的
	B:初始化时机
		a:只能初始化一次。
		b:常见的给值
			定义的时候。(推荐)
			构造方法中。
多态
(1)同一个对象在不同时刻体现出来的不同状态。
如:水的三种不同状态
(2)多态的前提:
	A:有继承或者实现关系。
	B:有方法重写。
	C:有父类或者父接口引用指向子类对象。


	多态的分类:
		a:具体类多态
			class Fu {}
			class Zi extends Fu {}
			
			Fu f = new Zi();
		b:抽象类多态
			abstract class Fu {}
			class Zi extends Fu {}
			
			Fu f = new Zi();
		c:接口多态
			interface Fu {}
			class Zi implements Fu {}
			
			Fu f = new Zi();
(3)多态中的成员访问特点
	A:成员变量
		编译看左边,运行看左边
	B:构造方法
		子类的构造都会默认访问父类构造
	C:成员方法
		编译看左边,运行看右边(方法重写)
	D:静态方法
		编译看左边,运行看左边
		(静态和类相关,算不上重写)
	为什么?
		因为成员方法有重写。
(4)多态的好处:
	A:提高代码的维护性(继承体现)
	B:提高代码的扩展性(多态体现)
(5)多态的弊端:
	不能使用子的特有功能。
	现象:
		子可以当作父使用,父不能当作子使用。
(6)多态中的转型(孔子装爹案例)
	A:向上转型
	Fu f = new Zi();
		从子到父
		
	B:向下转型
	Zi z = (zi)f;
		从父到子
		把父类的引用强行转换为子类的引用
(7)多态内存图解

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

抽象类
(1)把多个共性的东西提取到一个类中,这是继承的做法。
但是呢,这多个共性的东西,在有些时候,方法声明一样,但是方法体。
也就是说,方法声明一样,但是每个具体的对象在具体实现的时候内容不一样。
所以,我们在定义这些共性的方法的时候,就不能给出具体的方法体。
而一个没有具体的方法体的方法是抽象的方法。
在一个类中如果有抽象方法,该类必须定义为抽象类。
(2)抽象类的特点
	A:抽象类和抽象方法必须用关键字abstract修饰
	B:抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类
	C:抽象类不能实例化
	有构造方法,但是不能实例化,用于子类访问父类数据的初始化
	D:抽象类的子类
		a:是一个抽象类。
		b:是一个具体类。这个类必须重写抽象类中的所有抽象方法。
	E:抽象的实例化其实是靠具体的子类实现的,属于多态
	Animal a = new Dog();
(3)抽象类的成员特点: 
	A:成员变量
		有变量,有常量
	B:构造方法
		有构造方法
	C:成员方法
		有抽象 强制要求子类做的事,没有方法体
		有非抽象 子类继承的事
		
(4)抽象类的几个小问题
	A:抽象类有构造方法,不能实例化,那么构造方法有什么用?
		用于子类访问父类数据的初始化
	B:一个类如果没有抽象方法,却定义为了抽象类,有什么用?
		为了不让创建对象
	C:abstract不能和哪些关键字共存
		a:final	冲突
		b:private 冲突
		c:static 无意义
接口
(1)为表示类中额外的功能,java提供了接口表示。
接口呢,是一个规范,满足该规范的类就可以实现这个接口,可以根据不同的需要重写里面的方法。
(2)接口的特点:
	A:接口用关键字interface修饰
		interface 接口名 {}
	B:类实现接口用implements修饰
		class 类名 implements 接口名 {}
	C:接口不能实例化
	D:接口的实现类
		a:是一个抽象类。
		b:是一个具体类,这个类必须重写接口中的所有抽象方法。
(3)接口的成员特点:
	A:成员变量
		只能是常量
		默认修饰符:public static final
		建议手动给出
	B:构造方法
		没有构造方法
	C:成员方法
		只能是抽象的
		默认修饰符:public abstract
(4)类与类,类与接口,接口与接口
	A:类与类
		继承关系,只能单继承,可以多层继承
	B:类与接口  
		实现关系,可以单实现,也可以多实现。
		还可以在继承一个类的同时,实现多个接口
	C:接口与接口
		继承关系,可以单继承,也可以多继承
(5)抽象类和接口的区别?
	A:成员区别
		抽象类:
			成员变量:可变量可常量
			构造方法:有
			成员方法:可抽象,可非抽象
		接口:
			成员变量:只可常量
			构造方法:无
			成员方法:只可抽闲
	B:关系区别:
		类与类: 
			继承,单继承
		类与接口:
			实现,单实现,多实现
		接口与接口:
			继承,单继承,多继承
	C:设计理念不同
		抽象类:is a,抽象类中定义的是共性功能。
		接口:like a,接口中定义的是扩展功能。
形式参数和返回值(引用类型)
(1)形式参数:
	类名:需要该类的对象
	抽象类名:需要该类的子类对象,多态
	接口名:需要该接口的实现类对象
(2)返回值类型:
	类名:返回的是该类的对象
	抽象类名:返回的是该类的子类对象
	接口名:返回的是该接口的实现类的对象
(3)链式编程
	对象.方法1().方法2().......方法n();
	
	这种用法:其实在方法1()调用完毕后,应该一个对象;
		      方法2()调用完毕后,应该返回一个对象。
			  方法n()调用完毕后,可能是对象,也可以不是对象。
(1)其实就是文件夹
(2)作用:
	A:区分同名的类
	B:对类进行分类管理
		a:按照功能分
		b:按照模块分
(3)包的定义(掌握)
	package 包名;
	多级包用.分开。
(4)注意事项:(掌握)
	A:package语句必须在文件中的第一条有效语句
	B:在一个java文件中,只能有一个package
	C:如果没有package,默认就是无包名
(5)带包的编译和运行
	A:手动式
	B:自动式(掌握)
		javac -d . HelloWorld.java
导包
(1)我们多次使用一个带包的类,非常的麻烦,这个时候,Java就提供了一个关键字import。
(2)格式:
	import 包名...类名;
	另一种:
		import 包名...*;(不建议)
(3)package,import,class的顺序
	package > import > class
权限修饰符
(1)权限修饰符
				本类	同一个包下	不同包下的子类	不同包下的无关类
	private		Y
	默认		   Y		Y
	protected	Y		Y			Y
	public		Y		Y			Y				Y
(2)这四种权限修饰符在任意时刻只能出现一种。
	public class Demo {}		
常见的修饰符
(1)分类:
	权限修饰符:private,默认,protected,public
	状态修饰符:static,final
	抽象修饰符:abstract
(2)常见的类及其组成的修饰
	类:
		默认,public,final,abstract
		
		常用的:public
	
	成员变量:
		private,默认,protected,public,static,final
		
		常用的:private
		
	构造方法:
		private,默认,protected,public
		
		常用的:public
	
	成员方法:
		private,默认,protected,public,static,final,abstract
		
		常用的:public
(3)另外比较常见的:
	public static final int X = 10;
	public static void show() {}
	public final void show() {}
	public abstract void show();
内部类
(1)把类定义在另一个类的内部,该类就被称为内部类。
	举例:把类B定义在类A中,类B就被称为内部类。
(2)内部类的访问规则
	A:可以直接访问外部类的成员,包括私有
	B:外部类要想访问内部类成员,必须创建对象
(3)内部类的分类
	A:成员内部类:在成员位置定义的类
	B:局部内部类:定义在成员方法内的类
(4)成员内部类
	A:private 为了数据的安全性
	B:static 为了访问的方便性
	
	成员内部类不是静态的:
		外部类名.内部类名 对象名 = new 外部类名.new 内部类名();
	成员内部类是静态的:
		外部类名.内部类名 对象名 = new 外部类名.内部类名();
(5)局部内部类
	A:局部内部类访问局部变量必须加final修饰。
	B:为什么呢?
		因为局部变量使用完毕就消失,而堆内存的数据并不会立即消失。
		所以,堆内存还是用该变量,而改变量已经没有了。
		为了让该值还存在,就加final修饰。
		通过反编译工具我们看到了,加入final后,堆内存直接存储的是值,而不是变量名。
(6)匿名内部类(掌握)
	A:是局部内部类的简化形式
	B:前提
		存在一个类或者接口
	C:格式:
		new 类名或者接口名() {
			重写方法; 
		}
	D:本质:
		其实是继承该类或者实现接口的子类匿名对象
(7)匿名内部类在开发中的使用
	我们在开发的时候,会看到抽象类,或者接口作为参数。
	而这个时候,我们知道实际需要的是一个子类对象。
	如果该方法仅仅调用一次,我们就可以使用匿名内部类的格式简化。
API的概述(了解)
(1)应用程序编程接口。
(2)就是JDK提供给我们的一些提高编程效率的java类。
Object类(掌握)
(1)Object是类层次结构的根类,所有的类都直接或者间接的继承自Object类。
(2)Object类的构造方法有一个,并且是无参构造
	这其实就是理解当时我们说过,子类构造方法默认访问父类的构造是无参构造
(3)要掌握的方法:
	A:toString()
		返回对象的字符串表示,默认是由类的全路径+'@'+哈希值的十六进制表示。
		这个表示其实是没有意义的,一般子类都会重写该方法。
	B:equals()
		比较两个对象是否相同。默认情况下,比较的是地址值是否相同。
		而比较地址值是没有意义的,所以,一般子类也会重写该方法。
(4)要了解的方法:
	A:hashCode() 返回对象的哈希值。不是实际地址值,可以理解为地址值。
	B:getClass() 返回对象的字节码文件对象,反射中我们会详细讲解	
	C:finalize() 用于垃圾回收,在不确定的时间
	D:clone() 可以实现对象的克隆,包括成员变量的数据复制,但是它和两个引用指向同一个对象是有区别的。
(5)两个注意问题;
	A:直接输出一个对象名称,其实默认调用了该对象的toString()方法。
	B:面试题 
		==和equals()的区别?
		A:==
			基本类型:比较的是值是否相同
			引用类型:比较的是地址值是否相同
		B:equals()
			只能比较引用类型。默认情况下,比较的是地址值是否相同。
			但是,我们可以根据自己的需要重写该方法。
            String类 就是重写了equals()方法,比较的是内容
Scanner
(1)在JDK5以后出现的用于键盘录入数据的类。
(2)构造方法:
	A:讲解了System.in这个东西。
		它其实是标准的输入流,对应于键盘录入
	B:构造方法
		InputStream is = System.in;
		
		Scanner(InputStream is)
	C:常用的格式
		Scanner sc = new Scanner(System.in);
(3)基本方法格式:
	A:hasNextXxx() 判断是否是某种类型的
	B:nextXxx()	返回某种类型的元素
(4)要掌握的两个方法
	A:public int nextInt()
	B:public String nextLine()
(5)需要注意的小问题
	A:同一个Scanner对象,先获取数值,再获取字符串会出现一个小问题。
	B:解决方案:
		a:重新定义一个Scanner对象
		b:把所有的数据都用字符串获取,然后再进行相应的转换
String类的概述和使用
(1)多个字符组成的一串数据。
	可以和字符数组进行相互转换。
(2)构造方法:
	A:public String()
	B:public String(byte[] bytes)
	C:public String(byte[] bytes,int offset,int length)
	D:public String(char[] value)
	E:public String(char[] value,int offset,int count)
	F:public String(String original)把字符常量转换为字符串
	下面的这一个虽然不是构造方法,但是结果也是一个字符串对象
	G:String s = "hello";
(3)字符串的特点
	A:字符串一旦被赋值,就不能改变。
		注意:这里指的是字符串的内容不能改变,而不是引用不能改变。
	B:字面值作为字符串对象和通过构造方法创建对象的不同
		String s = new String("hello");和String s = "hello"的区别?

(4)字符串的功能
	A:判断功能
		boolean equals(Object obj)比较字符串内容
		boolean equalsIgnoreCase(String str)比较字符串内容忽略大小写
		boolean contains(String str)大字符串是否包含小字符串
		boolean startsWith(String str)判断以某字符串开头
		boolean endsWith(String str)
		boolean isEmpty()
	B:获取功能
		int length()
		char charAt(int index)
		int indexOf(int ch)返回指定字符的第一次索引
		int indexOf(String str)返回指定字符串的第一次索引
		int indexOf(int ch,int fromIndex)
		int indexOf(String str,int fromIndex)
		String substring(int start)从指定位置开始截取字符串
		String substring(int start,int end)
	C:转换功能
		byte[] getBytes()把字符串转换为字节数组
		char[] toCharArray()转换为字符数组
		static String valueOf(char[] chs)
		static String valueOf(int i)
        value把任意类型的数据转换为字符串
		String toLowerCase()
		String toUpperCase()
		String concat(String str)拼接字符串
	D:其他功能
		a:替换功能 
			String replace(char old,char new)
			String replace(String old,String new)
		b:去空格功能
			String trim()
		c:按字典比较功能
			int compareTo(String str)
			int compareToIgnoreCase(String str) 按字典顺序比较字符串
StringBuffer
(1)用字符串做拼接,比较耗时并且也耗内存,而这种拼接操作又是比较常见的,为了解决这个问题,Java就提供了一个字符串缓冲区类。StringBuffer供我们使用。
(2)StringBuffer的构造方法
	A:StringBuffer()
	B:StringBuffer(int capacity)构造一个没有字符的字符串缓冲区和指定的初始容量
	C:StringBuffer(String str)构造一个初始化为指定字符串内容的字符串缓冲区
(3)StringBuffer的常见功能(自己补齐方法的声明和方法的解释)
	A:添加功能
    public StringBuffer append(anydata):把任意类型添加到字符缓冲区里面
    需要创建对象,返回值是对象本身
    public StringBuffer insert(int offset,anydata):在指定位置把任意数据插入缓冲区
	B:删除功能
    public StringBuffer delete(int start, int end)
    public StringBuffer deleteCharAt(int index)
	C:替换功能
    public StringBuffer replace(int start, int end, String str) 包含左边不含右边
	D:反转功能
    public StringBuffer reverse()
	E:截取功能(注意这个返回值)
    String substring(int start)
    String substring(int start, int end) 
(4)StringBuffer的练习
	A:String和StringBuffer相互转换
		String -- StringBuffer
            String s = "cool"
			构造方法
            StringBuffer sb = new StringBuffer(s)
            添加
            sb.append(s)
		StringBuffer -- String
        StringBuffer buffer = new StringBuffer()
            构造方法
            String s = new String(buffer)
			toString()方法
            String s = buffer.toString()
	B:字符串的拼接
	C:把字符串反转
	D:判断一个字符串是否对称
(5)小细节:
		StringBuffer:同步的,数据安全,效率低。
		StringBuilder:不同步的,数据不安全,效率高。
	A:String,StringBuffer,StringBuilder的区别
	B:StringBuffer和数组的区别?
(6)注意的问题:
	String作为形式参数,StringBuffer作为形式参数。
数组高级以及Array
(1)排序
	A:冒泡排序
		
	B:选择排序
		把0索引的元素,和索引1以后的元素都进行比较,第一次完毕,最小值出现在了0索引。同理,其他的元素就可以排好。
		
(2)查找
	A:基本查找
		针对数组无序的情况
	B:二分查找(折半查找)
		针对数组有序的情况(千万不要先排序,在查找)
		
		public static int binarySearch(int[] arr,int value) {
			int min = 0;
			int max = arr.length-1;
			int mid = (min+max)/2;
			
			while(arr[mid] != value) {
				if(arr[mid] > value) {
					max = mid - 1;
				}else if(arr[mid] < value) {
					min = mid + 1;
				}
				
				if(min > max) {
					return -1;
				}
				
				mid = (min+max)/2;
			}
			
			return mid;
		}
(3)Arrays工具类
	A:是针对数组进行操作的工具类。包括排序和查找等功能。
	B:要掌握的方法
		把数组转成字符串:
        static String toString(any type)
		排序:
        static void sort(any type)
		二分查找:
        static int binarySearch(int[] a,int key)

Integer
(1)为了让基本类型的数据进行更多的操作,Java就为每种基本类型提供了对应的包装类类型
	byte 		Byte
	short		Short
	int			Integer
	long		Long
	float		Float
	double		Double
	char		Character
	boolean		Boolean
(2)Integer的构造方法
	A:Integer i = new Integer(100);
	B:Integer i = new Integer("100");
		注意:这里的字符串必须是由数字字符组成
(3)String和int的相互转换
	A:String -- int
		Integer.parseInt("100");
	B:int -- String
		String.valueOf(100);
(4)其他的功能
	进制转换
    static String toBinaryString(int i) 
	在基数2中返回整数参数的字符串表示形式为无符号整数。  
	static String toHexString(int i) 
	返回整数参数的字符串表示形式,作为16位中的无符号整数。  
	static String toOctalString(int i) 
	在基数8中返回整数参数的字符串表示形式为无符号整数。  
Character
(1)Character构造方法	
	Character ch = new Character('a');
(2)要掌握的方法:
    :判断是否是字母
    static boolean isLetter(char ch)  
    :字母或数字
    static boolean isLetterOrDigit(char ch)  
	:判断给定的字符是否是大写
    static boolean isUpperCase(char ch)  
	:判断给定的字符是否是小写
    static boolean isLowerCase(char ch)  
	:判断给定的字符是否是数字字符
    static boolean isDigit(char ch) 确定指定的字符是否是数字 
	:把给定的字符转成大写
    static char toUpperCase(char ch)
	:把给定的字符转成小写
    stastic char toLowerCase(char ch)
正则表达式
(1)就是符合一定规则的字符串
(2)常见规则
	A:字符
		x 字符 x。举例:'a'表示字符a
		\\ 反斜线字符。
		\n 新行(换行)符 ('\u000A') 
		\r 回车符 ('\u000D')
		
	B:字符类
		[abc] a、b 或 c(简单类) 
		[^abc] 任何字符,除了 a、b 或 c(否定) 
		[a-zA-Z] a到 z 或 A到 Z,两头的字母包括在内(范围) 
		[0-9] 0到9的字符都包括
		
	C:预定义字符类
		. 任何字符
		\d 数字:[0-9]
		\w 单词字符:[a-zA-Z_0-9]
			在正则表达式里面组成单词的东西必须有这些东西组成

	D:边界匹配器
		^ 行的开头 
		$ 行的结尾 
		\b 单词边界
			就是不是单词字符的地方。
			举例:hello world?haha;xixi
		
	E:Greedy 数量词 
		X? X,一次或一次也没有
		X* X,零次或多次
		X+ X,一次或多次
		X{n} X,恰好 n 次 
		X{n,} X,至少 n 次 
		X{n,m} X,至少 n 次,但是不超过 m 次 
(3)常见功能:
	A:判断功能
		String类的public boolean matches(String regex)
	B:分割功能
		String类的public String[] split(String regex)
	C:替换功能
		String类的public String replaceAll(String regex,String replacement)
	D:获取功能
		Pattern和Matcher
			将给定的正则表达式编译为一个模式对象
			Pattern p = Pattern.compile("a*b");
			通过模式对象得到匹配器对象
			Matcher m = p.matcher("aaaaab");
			
			find():查找存不存在
			group():获取刚才查找过的数据
Math
(1)针对数学运算进行操作的类
static double E e ,自然对数的基数。  
static double PI pi ,圆周长与其直径的比率。  

(2)常见方法
	A:绝对值
    static int abs() 
	B:向上取整
	static double ceil(double)
	C:向下取整
	static double floor(double) 
	D:两个数据中的大值
    static max()
	E:a的b次幂
    static pow(b,a)
	F:随机数
    static double random()
	G:四舍五入
    static round()
	H:正平方根
    static sqrt()
Random
(1)用于产生随机数的类
(2)构造方法:
	A:Random() 默认种子,每次产生的随机数不同,是当前的时间的毫秒值
	B:Random(long seed) 指定种子,每次种子相同,随机数就相同
(3)成员方法:
	A:int nextInt() 返回int范围内的随机数
	B:int nextInt(int n) 返回[0,n)范围内的随机数
System
(1)系统类,提供了一些有用的字段和方法
(2)成员方法(自己补齐)
	A:运行垃圾回收器
    static void gc()
	B:退出jvm
    exit()
	C:获取当前时间的毫秒值
	currentTimeMillis()
	D:数组复制
	arraycopy(Object src, int srcPos, Object dest, int 			destPos, int length)
BigInteger
(1)针对大整数的运算
(2)构造方法	
	A:BigInteger(String s)
(3)成员方法
	A:加
	public BigInteger add(BigInteger val)
	B:减
	public BigInteger subtract(BigInteger val)
	C:乘
	public BigInteger multiply(BigInteger val)
	D:除
	public BigInteger divide(BigInteger val)
	E:商和余数
	public BigInteger[] divideAndRemainder(BigInteger val)
BigDecimal
(1)浮点数据做运算,会丢失精度。所以,针对浮点数据的操作建议采用BigDecimal。(金融相关的项目)
(2)构造方法
	A:BigDecimal(String val)
(3)成员方法:
	A:加
	public BigDecimal add(BigDecimal augend)
	B:减
	public BigDecimal subtract(BigDecimal subtrahend)
	C:乘
	public BigDecimal multiply(BigDecimal multiplicand)
	D:除
	public BigDecimal divide(BigDecimal divisor)
	E:自己保留小数几位
	public BigDecimal divide(BigDecimal divisor,int scale,int roundingMode)商,几位小数,如何舍取
Date/DateFormat
(1)Date是日期类,可以精确到毫秒。
	A:构造方法
		Date()
		Date(long time)
	B:成员方法
		getTime()
		setTime(long time)
	C:日期和毫秒值的相互转换
	案例:你来到这个世界多少天了?
(2)DateFormat针对日期进行格式化和针对字符串进行解析的类,但是是抽象类,所以使用其子类SimpleDateFormat
	A:SimpleDateFormat(String pattern) 给定模式
		yyyy-MM-dd HH:mm:ss
	B:日期和字符串的转换
		a:Date -- String
			format()
			
		b:String -- Date
			parse()
Calendar
(1)日历类,封装了所有的日历字段值,通过统一的方法根据传入不同的日历字段可以获取值。
(2)如何得到一个日历对象呢?
	Calendar rightNow = Calendar.getInstance();
	本质返回的是子类对象
(3)成员方法
	A:根据日历字段得到对应的值=
	获取年,月,日
	int year = rightNow.get(Calendar.YEAR[MONTH][DATE]);
	
	B:根据日历字段和一个正负数确定是添加还是减去对应日历字段的值
	public void add(int field, int amount)
    根据日历的规则,将指定的时间量添加或减去给定的日历字段
	C:设置日历对象的年月日注意month从0开始
	public void set(int year, int month, int date, int hourOfDay, int minute, int second) 

集合框架

在这里插入图片描述

Collection
(1)集合的由来?
	我们学习的是Java -- 面向对象 -- 操作很多对象 -- 存储 -- 容器(数组和StringBuffer) -- 数组
	而数组的长度固定,所以不适合做变化的需求,Java就提供了集合供我们使用。
(2)集合和数组的区别?
	A:长度区别
		数组固定
		集合可变
	B:内容区别
		数组可以是基本类型,也可以是引用类型
		集合只能是引用类型
	C:元素内容
		数组只能存储同一种类型
		集合可以存储不同类型(其实集合一般存储的也是同一种类型)
(3)集合的继承体系结构?
	由于需求不同,Java就提供了不同的集合类。这多个集合类的数据结构不同,但是它们都是要提供存储和遍历功能的,
	我们把它们的共性不断的向上提取,最终就形成了集合的继承体系结构图。
	
	Collection
		|--List
			|--ArrayList
			|--Vector
			|--LinkedList
		|--Set
			|--HashSet
			|--TreeSet
(4)Collection的功能概述(自己补齐)
	A:添加功能
	boolean add(E e) 确保此集合包含指定的元素
    boolean addAll(Collection<? extends E> c) 将指定集合中的所有元素添加到此集合

	B:删除功能
	void clear() 删除所有元素
	boolean remove(Object o) 从该集合中删除指定元素的单个实例(如果存在)  
	boolean removeAll(Collection<?> c) 删除指定集合中包含的所有此集合的元素,只要有一个移除就算移除
	default boolean removeIf(Predicate<? super E> filter) 删除满足给定谓词的此集合的所有元素 

	C:判断功能
	boolean contains(Object o) 如果此集合包含指定的元素,则返回 true
	boolean containsAll(Collection<?> c) 如果此集合包含指定 集合中的所有元素,则返回true
	boolean isEmpty() 如果此集合不包含元素,则返回 true  

	D:获取功能
	Iterator<E> iterator() 返回此集合中的元素的迭代器 

	E:长度功能
	int size() 返回此集合中的元素数 

	F:交集
	boolean retainAll(Collection<?> c) 仅保留此集合中包含在指定集合中的元素 

	G:把集合转数组
	Object[] toArray() 返回一个包含此集中所有元素的数组。  
	<T> T[] toArray(T[] a 返回包含此集合中所有元素的数组; 返回的数组的运行时类型是指定数组的运行时类型 
(5)Collection集合的遍历
	A:把集合转数组(了解)
	B:迭代器(集合专用方式)
(6)迭代器
	A:是集合的获取元素的方式。
	B:是依赖于集合而存在的。
	C:迭代器的原理和源码。
		a:为什么定义为了一个接口而不是实现类?
		b:看了看迭代器的内部类实现。
(7)Collection集合的案例(遍历方式 迭代器)
	集合的操作步骤:
		A:创建集合对象
		B:创建元素对象
		C:把元素添加到集合
		D:遍历集合
List
(1)List是Collection的子接口
	特点:有序(存储顺序和取出顺序一致),可重复。
(2)List的特有功能:(自己补齐)
	A:添加功能
	boolean add(E e)
	void add(int index, E element) 指定位置插入
	B:删除功能
	Object remove(int index):根据索引删除元素,返回被删除的元素
	void clear()删除所有
	C:获取功能
	Object get(int index):获取指定位置的元素
	D:迭代器功能
	ListIterator listIterator():List集合特有的迭代器
	E:修改功能
	Object set(int index,Object element):根据索引修改元素,返回被修饰的元素
(3)List集合的特有遍历功能
	A:由size()和get()结合。
	B:代码演示
				//创建集合对象
				List list = new ArrayList();					

				//创建并添加元素
				list.add("hello");
				list.add("world");
				list.add("java");
				
				//遍历集合
				Iterator it = list.iterator();
				while(it.hasNext()) {
					String s =(String) it.next();
					System.out.println(s);
				}
				System.out.println("----------");
				
				for(int x=0; x<list.size(); x++) {
					String s =(String) list.get(x);
					System.out.println(s);
				}
(4)列表迭代器的特有功能:
	可以逆向遍历,但是要先正向遍历,所以无意义,基本不使用。
(5)并发修改异常
	A:出现的现象
		迭代器遍历集合,集合修改集合元素
	B:原因
		迭代器是依赖于集合的,而集合的改变迭代器并不知道。
	C:解决方案
		a:迭代器遍历,迭代器修改(ListIterator)
			元素添加在刚才迭代的位置
		b:集合遍历,集合修改(size()和get())
			元素添加在集合的末尾
(6)常见数据结构
	A:栈 先进后出
	B:队列 先进先出
	C:数组 查询快,增删慢
	D:链表 查询慢,增删快
(7)List的子类特点
	ArrayList
		底层数据结构是数组,查询快,增删慢。
		线程不安全,效率高。
	Vector
		底层数据结构是数组,查询快,增删慢。
		线程安全,效率低。
	LinkedList 
		底层数据结构是链表,查询慢,增删快。
		线程不安全,效率高。
		
	到底使用谁呢?看需求?
	分析:
		要安全吗?
			要:Vector(即使要,也不使用这个,后面再说)
			不要:ArrayList或者LinkedList
				查询多;ArrayList
				增删多:LinkedList
				
	什么都不知道,就用ArrayList。
(8)List集合的案例(遍历方式 迭代器和普通for)
	A:存储字符串并遍历
	B:存储自定义对象并遍历
List的子类
(1)List的子类特点
	ArrayList:
		底层数据结构是数组,查询快,增删慢
		线程不安全,效率高
	Vector:
		底层数据结构是数组,查询快,增删慢
		线程安全,效率低
	LinkedList:
		底层数据结构是链表,查询慢,增删快
		线程不安全,效率高
(2)ArrayList
	A:没有特有功能需要学习
	B:案例
		a:ArrayList存储字符串并遍历
		b:ArrayList存储自定义对象并遍历
(3)Vector
	A:有特有功能
		a:添加
			public void addElement(E obj)		--	add()
		b:获取
			public E elementAt(int index)		--	get()
			public Enumeration<E> elements()	--  iterator()
	B:案例
		a:Vector存储字符串并遍历
		b:Vector存储自定义对象并遍历
(4)LinkedList
	A:有特有功能	
		a:添加
			addFirst()头插入
			addLast()
		b:删除
			removeFirst()
			removeLast()
		c:获取
			getFirst()
			getLast()
	B:案例
		a:LinkedList存储字符串并遍历
		b:LinkedList存储自定义对象并遍历
(5)案例:
	A:去除集合中的多个字符串的重复元素
		如果字符串的内容相同,即为重复元素
	B:去除集合中的多个自定义对象的重复元素
		如果自定义对象的成员变量值都相同,即为重复元素
	C:用LinkedList模拟一个栈数据结构的集合类,并测试。
		你要定义一个集合类,只不过内部可以使用LinkedList来实现。
泛型
(1)泛型概述
	是一种把明确类型的工作推迟到创建对象或者调用方法的时候才去明确的特殊的类型。
(2)格式:
	<数据类型>
	注意:该数据类型只能是引用类型。
(3)好处:
	A:把运行时期的问题提前到了编译期间
	B:避免了强制类型转换
	C:优化了程序设计,解决了黄色警告线问题,让程序更安全
(4)泛型的前世今生
	A:泛型的由来
		Object类型作为任意类型的时候,在向下转型的时候,会隐含一个转型问题
	B:泛型类
	C:泛型方法
	D:泛型接口
	E:泛型高级通配符
		? 
		? extends E
		? super E
(5)我们在哪里使用呢?
	一般是在集合中使用。
增强for循环(for each循环)
(1)是for循环的一种
(2)格式:
	for(元素的数据类型 变量名 : 数组或者Collection集合的对象) {
		使用该变量即可,该变量其实就是数组或者集合中的元素。
	}
(3)好处:
	简化了数组和集合的遍历
(4)弊端
	增强for循环的目标不能为null。建议在使用前,先判断是否为null。
静态导入
(1)可以导入到方法级别的导入
(2)格式:
	import static 包名....类名.方法名;
(3)注意事项:
	A:方法必须是静态的
	B:如果多个类下有同名的方法,就不好区分了,还得加上前缀。
		所以一般我们并不使用静态导入,但是一定要能够看懂。
可变参数
(1)如果我们在写方法的时候,参数个数不明确,就应该定义可变参数。
(2)格式:
	修饰符 返回值类型 方法名(数据类型... 变量) {}
	
	注意:
		A:该变量其实是一个数组名
		B:如果一个方法有多个参数,并且有可变参数,可变参数必须在最后
(3)Arrays工具类的一个方法
	asList()把数组转成集合。
	注意:这个集合的长度不能改变。
Set
(1)Set集合的特点
	无序,唯一
(2)HashSet集合
	A:底层数据结构是哈希表(是一个元素为链表的数组)
	B:哈希表底层依赖两个方法:hashCode()和equals()
	  执行顺序:
		首先比较哈希值是否相同
			相同:继续执行equals()方法
				返回true:元素重复了,不添加
				返回false:直接把元素添加到集合
			不同:就直接把元素添加到集合
	C:如何保证元素唯一性的呢?
		由hashCode()和equals()保证的
	D:开发的时候,代码非常的简单,自动生成即可。
	E:HashSet存储字符串并遍历
	F:HashSet存储自定义对象并遍历(对象的成员变量值相同即为同一个元素)
(3)TreeSet集合
	A:底层数据结构是红黑树(是一个自平衡的二叉树)
	B:保证元素的排序方式
		a:自然排序(元素具备比较性)
			让元素所属的类实现Comparable接口
		b:比较器排序(集合具备比较性)
			让集合构造方法接收Comparator的实现类对象
(4)案例:
	A:获取无重复的随机数
	B:键盘录入学生按照总分从高到底输出
Collection集合总结
Collection
	|--List	有序,可重复
		|--ArrayList
			底层数据结构是数组,查询快,增删慢。
			线程不安全,效率高
		|--Vector
			底层数据结构是数组,查询快,增删慢。
			线程安全,效率低
		|--LinkedList
			底层数据结构是链表,查询慢,增删快。
			线程不安全,效率高
	|--Set	无序,唯一
		|--HashSet
			底层数据结构是哈希表。
			如何保证元素唯一性的呢?
				依赖两个方法:hashCode()和equals()
				开发中自动生成这两个方法即可
			|--LinkedHashSet
				底层数据结构是链表和哈希表
				由链表保证元素有序
				由哈希表保证元素唯一
		|--TreeSet
			底层数据结构是红黑树。
			如何保证元素排序的呢?
				自然排序
				比较器排序
			如何保证元素唯一性的呢?
				根据比较的返回值是否是0来决定
Collection集合使用方法
唯一吗?
	是:Set
		排序吗?
			是:TreeSet
			否:HashSet
	如果你知道是Set,但是不知道是哪个Set,就用HashSet。
		
	否:List
		要安全吗?
			是:Vector
			否:ArrayList或者LinkedList
				查询多:ArrayList
				增删多:LinkedList
	如果你知道是List,但是不知道是哪个List,就用ArrayList。

如果你知道是Collection集合,但是不知道使用谁,就用ArrayList。

如果你知道用集合,就用ArrayList。
在集合中常见的数据结构
ArrayXxx:底层数据结构是数组,查询快,增删慢
LinkedXxx:底层数据结构是链表,查询慢,增删快
HashXxx:底层数据结构是哈希表。依赖两个方法:hashCode()和equals()
TreeXxx:底层数据结构是二叉树。两种方式排序:自然排序和比较器排序
Map

在这里插入图片描述

(1)将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。 
(2)Map和Collection的区别?
	A:Map 存储的是键值对形式的元素,键唯一,值可以重复。夫妻对
	B:Collection 存储的是单独出现的元素,子接口Set元素唯一,子接口List元素可重复。光棍
	C:Map集合的数据结构值针对键有效,跟值无关,Collection则是针对元素
(3)Map接口功能概述(自己补齐)
	A:添加功能
	V put(K key, V value) 
	如果键第一次存储,则直接存储元素,返回null
	如果不是第一次,则更新值,然后返回上一次的值
	B:删除功能
	void clear()
	V remove(Object key) 根据键删除键值对元素,并返回值 
	C:判断功能
	boolean containsKey(Object key)判断是否包含指定的键
	boolean containsValue(Object value) 值 
	boolean isEmpty()  
	D:获取功能
	Set<Map.Entry<K,V>> entrySet() 
	返回此地图中包含的映射的Set视图 
	V get(Object key) 
    返回指定键所映射的值
    Set<K> keySet()  
    返回此地图中包含的键的Set视图
    Collection<V> values()  
    获取值的集合
	E:长度功能
	int size():返回键值对数
(4)Map集合的遍历
	A:键找值
		a:获取所有键的集合
		b:遍历键的集合,得到每一个键
		c:根据键到集合中去找值
	
	B:键值对对象找键和值
		a:获取所有的键值对对象的集合
		b:遍历键值对对象的集合,获取每一个键值对对象
		c:根据键值对对象去获取键和值
		
	代码体现:
		Map<String,String> hm = new HashMap<String,String>();
		
		hm.put("it002","hello");
		hm.put("it003","world");
		hm.put("it001","java");
		
		//方式1 键找值
		Set<String> set = hm.keySet();
		for(String key : set) {
			String value = hm.get(key);
			System.out.println(key+"---"+value);
		}
		
		//方式2 键值对对象找键和值
		Set<Map.Entry<String,String>> set2 = hm.entrySet();
		for(Map.Entry<String,String> me : set2) {
			String key = me.getKey();
			String value = me.getValue();
			System.out.println(key+"---"+value);
		}
(5)HashMap集合的练习
	A:HashMap<String,String>
	B:HashMap<Integer,String>
	C:HashMap<String,Student> 
	D:HashMap<Student,String>
(6)TreeMap集合的练习		
	A:TreeMap<String,String>
	B:TreeMap<Student,String>
Collections
(1)是针对集合进行操作的工具类,都是静态方法
(2)面试题:Collection和Collections的区别
	A:Collection 是单列集合的顶层接口,有两个子接口List和Set
	B:Collections 是针对集合进行操作的工具类,可以对集合进行排序和查找等
(3)常见的几个小方法:
	A:public static <T> void sort(List<T> list)
	排序
	B:public static <T> int binarySearch(List<?> list,T key)
	二分查找
	C:public static <T> T max(Collection<?> coll)
	
	D:public static void reverse(List<?> list)
	
	E:public static void shuffle(List<?> list)
	随机置换

异常

(1)程序出现的不正常的情况。
(2)异常的体系
	Throwable
		|--Error	严重问题,我们不处理。
		|--Exception
			|--RuntimeException	运行期异常,我们需要修正代码
			|--非RuntimeException 编译期异常,必须处理的,否则程序编译不通过
(3)异常的处理:
	A:JVM的默认处理
		把异常的名称,原因,位置等信息输出在控制台,但是呢程序不能继续执行了。
	B:自己处理
		a:try {
  			可能出现问题的代码;
  		}catch(异常名 变量) { 
  			针对问题的处理;
  		}finally {
  			释放资源;
  		}
		假如遇到不知名的异常,则可以用父类接收
		如 catch(Exception e),一般放在其他已知异常的后面
		多个异常
		多个catch或者catch(Exception1 | Exception2 name)
			自己编写处理代码,后面的程序可以继续执行
		b:throws
		把自己处理不了的,在方法上声明,告诉调用者,这里有问题
			格式:
				throws 异常名(可以跟多个)
				格式必须跟在方法的括号后面 
				
		c:throw
			抛出的是一个对象
		
面试题
	A:编译期异常和运行期异常的区别?
		编译期异常 必须要处理的,否则编译不通过
		运行期异常 可以不处理,也可以处理
	B:throw和throws是的区别
		throw:
			在方法体中,后面跟的是异常对象名,并且只能是一个
			throw抛出的是一个异常对象,说明这里肯定有一个异常产生了
		throws:
			在方法声明上,后面跟的是异常的类名,可以是多个
			throws是声明方法有异常,是一种可能性,这个异常并不一定会产生
(4)异常中需要了解的方法
	public String getMessage():异常的消息字符串
	public String toString():返回异常的简单描述
	printStackTrace()获取异常类名和异常信息,以及异常出现在程序中的位置
	printStackTrace(PrintStream s)

(5)finally关键字及其面试题
	A:finally用于释放资源,它的代码永远会执行。特殊情况:在执行到finally之前jvm退出了
	B:异常处理的变形
		try...catch...finally
		try...catch...
		try...catch...catch...
		try...catch...catch...fianlly
		try...finally
(6)自定义异常
	继承自Exception或者RuntimeException,只需要提供无参构造和一个带参构造即可
(7)异常的注意实现
	A:父的方法有异常抛出,子的重写方法在抛出异常的时候必须要小于等于父的异常 
	B:父的方法没有异常抛出,子的重写方法不能有异常抛出
	C:父的方法抛出多个异常,子的重写方法必须比父少或者小

I/O

File
(1)IO流操作中大部分都是对文件的操作,所以Java就提供了File类供我们来操作文件
	File:文件和目录(文件夹)路径名的抽象表示形式
(2)构造方法
	A:File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例
	File file = new File("e:\\demo\\a.txt");
	B:File(File parent, String child) 从父抽象路径名和子路径名字符串创建新的 File实例
	File file = new File("e:\\demo","a.txt");
	C:
	File file = new File("e:\\demo");
	  File file2 = new File(file,"a.txt");
(3)File类的功能(自己补齐)
	A:创建功能
	boolean createNewFile()
	boolean mkdir()
	boolean mkdirs()
	创建由此抽象路径名命名的目录,包括任何必需但不存在的父目录=
	B:删除功能
	boolean delete()
	注意:删除不走回收站
	C:重命名功能
	boolean renameTo(File dest)(注意是对象)
	如果两个文件名路径相同的话就是重命名操作,不同则是剪切加重命名
	D:判断功能
	boolean isDirectory() 路径
	boolean isFile() 文件
	boolean exists() 
	boolean canRead()
	boolean canWrite()
	boolean isHidden()
	E:获取功能
	String getAbsolutePath()绝对路径
	String getPath()
	String getName()
	long length()
	long lastModified()上次修改的时间
	F:高级获取功能
	String[] list()
	返回一个字符串数组,命名由此抽象路径名表示的目录中的文件和目录
	File[] listFiles()
	返回一个抽象路径名(文件对象)数组,表示由该抽象路径名表示的目录中的文件
	G:过滤器功能
	String[] list(FilenameFilter filter) 
返回一个字符串数组,命名由此抽象路径名表示的目录中满足指定过滤器的文件和目录 
	File[] listFiles(FileFilter filter) 
	返回一个抽象路径名数组,表示由此抽象路径名表示的满足指定过滤器的目录中的文件和目录。  
	File[] listFiles(FilenameFilter filter) 
	返回一个抽象路径名数组,表示由此抽象路径名表示的满足指定过滤器的目录中的文件和目录。  
IO流
(1)IO用于在设备间进行数据传输的操作	
(2)分类:
	A:流向
		输入流	读取数据
		输出流	写出数据
	B:数据类型
		字节流	
				字节输入流
				字节输出流
		字符流
				字符输入流
				字符输出流
	注意:
		a:如果我们没有明确说明按照什么分,默认按照数据类型分。
		b:除非文件用windows自带的记事本打开我们能够读懂,才采用字符流,否则建议使用字节流。
(3)FileOutputStream写出数据
用于写入诸如图像数据的原始字节流。 对于写入字符流,请考虑使用FileWriter
	构造方法
	FileOutputStream(File file)
	FileOutputStream(String name)
	字节流写数据的方式
	void write(byte[] b) 将 b.length个字节从指定的字节数组写入此文件输出流。  
	void write(byte[] b, int off, int len) 
将 len字节从位于偏移量 off的指定字节数组写入此文件输出流。  
	void write(int b) 
将指定的字节写入此文件输出流。  

	A:操作步骤
		a:创建字节输出流对象
		b:调用write()方法 
		c:释放资源	
	B:代码体现:
		FileOutputStream fos = newFileOutputStream("fos.txt"); 
		fos.write("hello".getBytes());
		fos.close();
		
	C:要注意的问题?
		a:创建字节输出流对象做了几件事情?
		b:为什么要close()?
		c:如何实现数据的换行?
		写入换行符字节流
		fos.write("\n".getbytes())
		d:如何实现数据的追加写入?
		FileOutputStream(File file, boolean append) 
		创建文件输出流以写入由指定的 File对象表示的文件。  
 		如果第二个值为true的话则从文本末追加
		FileOutputStream(String name, boolean append) 
		创建文件输出流以指定的名称写入文件
        如果第二个值为true的话则从文本末追加

(4)FileInputStream读取数据
	构造方法
	FileInputStream(File file)   
	FileInputStream(String name)
	读取字节的方式
	int read() 
	从该输入流读取一个字节的数据。  
	int read(byte[] b) 
	从该输入流读取最多 b.length个字节的数据为字节数组。  
	int read(byte[] b, int off, int len) 
	从该输入流读取最多 len字节的数据为字节数组。  

	A:操作步骤
		a:创建字节输入流对象
		b:调用read()方法
		c:释放资源
		
	B:代码体现:
		FileInputStream fis = new FileInputStream("fos.txt");
		
		//方式1读取中文时可能会出问题  
		int by = 0;
		while((by=fis.read())!=-1) {
			System.out.print((char)by);
		}
		
		//方式2
		byte[] bys = new byte[1024];
		int len = 0;
		while((len=fis.read(bys))!=-1) {
			System.out.print(new String(bys,0,len));
		}
		
		fis.close();
(5)IO流分类
	字节流:
		InputStream
			FileInputStream
			BufferedInputStream
		OutputStream
			FileOutputStream
			BufferedOutputStream
	
	字符流:
		Reader
			FileReader
			BufferedReader
		Writer
			FileWriter
			BufferedWriter
(6)字节缓冲区流
	A:BufferedOutputStream
	构造方法
	BufferedOutputStream(OutputStream out) 
	创建一个新的缓冲输出流,以将数据写入指定的底层输出流。  
	BufferedOutputStream(OutputStream out, int size) 
	创建一个新的缓冲输出流,以便以指定的缓冲区大小将数据写入指定的底层输出流。  
	BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("file.txt"))
	
	B:BufferedInputStream
	BufferedInputStream(InputStream in) 
创建一个 BufferedInputStream并保存其参数,输入流 in ,供以后使用。  
	BufferedInputStream(InputStream in, int size) 
创建 BufferedInputStream具有指定缓冲区大小,并保存其参数,输入流 in ,供以后使用。  
	操作类似
字符流
(1)字节流操作中文数据不是特别的方便,所以就出现了转换流。
   转换流的作用就是把字节流转换字符流来使用。
(2)转换流其实是一个字符流
	字符流 = 字节流 + 编码表
(3)编码表
	A:就是由字符和对应的数值组成的一张表
	B:常见的编码表
		ASCII
		ISO-8859-1
		GB2312
		GBK
		GB18030
		UTF-8
	C:字符串中的编码问题
		编码
			String -- byte[]
			String(byte[] bytes,String charsetName)
			通过指定的字符集编码字节数组
		解码
			byte[] -- String
			byte[] getBytes(string charsetName)
			通过指定的字符集解码字节数组
(4)IO流中的编码问题
	A:OutputStreamWriter
		OutputStreamWriter(OutputStream os):默认编码,GBK
		OutputStreamWriter(OutputStream os,String charsetName):指定编码。
	B:InputStreamReader
		InputStreamReader(InputStream is):默认编码,GBK
		InputStreamReader(InputStream is,String charsetName):指定编码
	C:编码问题其实很简单
		编码只要一致即可
(5)字符流
	Reader
		|--InputStreamReader
			基本方法
			int read();
			int read(char[] chs)
			|--FileReader
				和上面一样
		|--BufferedReader
			特殊方法
			String readLine()
			
	Writer
		|--OutputStreamWriter
            基本方法
            void write(int/char[]/String)
			记得flush()刷新缓冲
			|--FileWriter
			和上面一样
		|--BufferedWriter
			特殊方法void newLine() 根据系统来决定换行符
IO流小结
IO流
	|--字节流
		|--字节输入流
			InputStream
				int read():一次读取一个字节
				int read(byte[] bys):一次读取一个字节数组
			
				|--FileInputStream
				|--BufferedInputStream
		|--字节输出流
			OutputStream
				void write(int by):一次写一个字节
				void write(byte[] bys,int index,int len):一次写一个字节数组的一部分
				
				|--FileOutputStream
				|--BufferedOutputStream
	|--字符流
		|--字符输入流
			Reader
				int read():一次读取一个字符
				int read(char[] chs):一次读取一个字符数组
				
				|--InputStreamReader
					|--FileReader
				|--BufferedReader
					String readLine():一次读取一个字符串
		|--字符输出流
			Writer
				void write(int ch):一次写一个字符
				void write(char[] chs,int index,int len):一次写一个字符数组的一部分
				
				|--OutputStreamWriter
					|--FileWriter
				|--BufferedWriter
					void newLine():写一个换行符
					
					void write(String line):一次写一个字符串
数据操作流
(1)可以操作基本类型的数据
(2)流对象名称	
	DataInputStream
	DatainputStream(inputStream in)
	同理,和下面一样
	void readInt(Int)
	DataOutputStream
	构造方法:DataOutputStream(OutputStream out) 
	可读写基本数据类型
	void writeInt(int )
		 writeFloat(float )
内存操作流
(1)有些时候我们操作完毕后,未必需要产生一个文件,就可以使用内存操作流。
(2)三种
	A:ByteArrayInputStream,ByteArrayOutputStream
        可以不必close()
        ByteArrayOutputStream:
        构造:ByteArrayOutputStream([int size])创建一个新的byte数组输出流,可指定大小
        主要方法:byte[] toByteArray()
        void write()写入一个字节
		ByteArrayInputStream:
		构造:ByteArrayInputStream(byte[] buf)
		主要方法:int read()读一个字节
		
	B:CharArrayReader,CharArrayWriter
	类似
	C:StringReader,StringWriter
	类似
打印流
(1)字节打印流
   PrintStream
   字符打印流
   PrintWriter
   
(2)特点:
	A:只操作目的地,不操作数据源
	B:可以操作任意类型的数据
	void print(anytype)
	C:如果启用了自动刷新,在调用println(),printf(),format方法的时候,能够换行并刷新
	new PrintWriter(Write out,boolean autoflush)
	D:可以直接操作文件
		问题:哪些流可以直接操作文件呢?
		FileInputStream
		FileOutputStream
		FileReader
		FileWriter
		PrintStream
		PrintWriter
(3)复制文本文件
	版本一 BufferedReader br = new BufferedReader(new FileReader("a.txt"));
	PrintWriter pw = new PrintWriter(new FileWriter("b.txt"),true);
	
	String line = null;
	while((line=br.readLine())!=null) {
		pw.println(line);
	}	
	pw.close();
    br.close();
标准输入输出流
(1)System类下面有这样的两个字段
	in 标准输入流
	out 标准输出流
(2)三种键盘录入方式
	A:main方法的args接收参数
	B:System.in通过BufferedReader进行包装
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	C:Scanner
		Scanner sc = new Scanner(System.in);
(3)输出语句的原理和如何使用字符流输出数据
	A:原理
		System.out.println("helloworld");
		
		PrintStream ps = System.out;
		ps.println("helloworld");
	B:把System.out用字符缓冲流包装一下使用
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
随机访问流
(1)支持对文件的访问和写入
(2)可以按照文件指针的位置写数据和读数据。
	RandomAccessFile(File file, String mode) 
	创建一个随机访问文件流从File参数指定的文件中读取,并可选地写入文件。  
	RandomAccessFile(String name, String mode) 
	创建随机访问文件流,以从中指定名称的文件读取,并可选择写入文件。  

(3)案例:
	A:写数据
	void writeInt()/writeChar()
	B:读数据
	void readInt/readChar()
	C:获取和改变文件指针的位置
	long getFilePointer()
	void seek(long pos)
合并流
(1)把多个输入流的数据写到一个输出流中。
(2)构造方法:
	A:SequenceInputStream(InputStream s1, InputStream s2) 
	B:SequenceInputStream(Enumeration<? extends InputStream> e) 实现多个文件合并到一个文件里
	Enumeration 是Vector的一个方法elements()返回类型
	实现方法
	Vector<InputStream> v = new Vector<InputStream>
	InputStream is1 = new InputStream("1.txt")
	InputStream is2 = new InputStream("2.txt")
	InputStream is3 = new InputStream("3.txt")
	v.add(is1)
	v.add(is2)
	v.add(is3)
	Enumeration<InputStream> en = v.elements()  
	SquenceInputStream sis = new SquenceInputStream(en)
序列化流
(1)可以把对象的基本数据类型和图形入文本文件或者在网络中传输
ObjectInputStream

ObjectOutputStream
构造方法
	ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"))
成员方法
	void writeObject(Object obj) 
	将指定的对象写入ObjectOutputStream 
(2)如何实现序列化呢?
	让被序列化的对象所属类实现序列化接口
	使用序列化接口,启用序列化功能
	implements Serializable

	该接口是一个标记接口。没有功能需要实现。
(3)注意问题:
	把数据写到文件后,在去修改类会产生一个问题。
		因为实现了序列化会有一个标记UID,表明它经过序列化
	如何解决该问题呢?
		在类文件中,给出一个固定的序列化id值。
		而且,这样也可以解决黄色警告线问题
	不想序列化成员变量如何处理(默认都会)
		private transient int age
(4)面试题:
	什么时候序列化?
	如何实现序列化?
	什么是反序列化?
Properties
(1)是一个集合类,Hashtable的子类,不是泛型类
 表示一组持久的属性。 Properties可以保存到流中或从流中加载。 属性列表中的每个键及其对应的值都是一个字符串
(2)特有功能
	A:public Object setProperty(String key,String value)
		调用hashtable的put方法
	B:public String getProperty(String key)
	C:public Set<String> stringPropertyNames()
(3)和IO流结合的方法 
	
	void load(InputStream inStream) 
		从输入字节流读取属性列表(键和元素对)
		把键值对形式的文本文件内容加载到集合(必须是properties)中
	void load(Reader reader) 
		以简单的线性格式从输入字符流读取属性列表(关键字和元素对)。  		
	把集合中的数据存储到文本文件中
	void store(OutputStream out, String comments) 
        将此属性列表(键和元素对)写入此 Properties表中,以适合于使用 load(InputStream)方法加载到 Properties表中的格式输出流。  
	void store(Writer writer, String comments) 
        将此属性列表(键和元素对)写入此 Properties表中,以适合使用 	load(Reader)方法的格式输出到输出字符流
        把集合中的数据存储到文件

(4)案例:
	A:根据给定的文件判断是否有键为"lisi"的,如果有就修改其值为100
	B:写一个程序实现控制猜数字小游戏程序不能玩超过5次
NIO
(1)JDK4出现的NIO,对以前的IO操作进行了优化,提供了效率。但是大部分我们看到的还是以前的IO,采用内存映射的方式,
(2)一些类
	Buffer
	Channels
(3)JDK7的NIO的使用	
	Path:路径接口
	Paths:通过静态方法返回一个路径,类
		static Path get(URI uri)
	Files:提供了常见的功能
		复制文本文件
            static long copy(Path source, OutputStream out) 
            将文件中的所有字节复制到输出流 
		把集合中的数据写到文本文件
            public static Path write(Path path,
                         Iterable<? extends CharSequence> lines,
                         Charset cs,
                         OpenOption... options)
                  throws IOException
            相当于
            Files.write(path, lines, StandardCharsets.UTF_8, options);  

多线程

概念,使用方法和注意事项
(1)多线程:一个应用程序有多条执行路径
	进程:正在执行的应用程序
	线程:进程的执行单元,执行路径
	单线程:一个应用程序只有一条执行路径
	多线程:一个应用程序有多条执行路径
	
	多进程的意义?
		提高CPU的使用率
	多线程的意义?
		提高应用程序的使用率
	
	Java程序的运行原理及JVM的启动是多线程的吗?
	A:Java命令去启动JVM,JVM会启动一个进程,该进程会启动一个主线程。
	B:JVM的启动是多线程的,因为它最低有两个线程启动了,主线程和垃圾回收线程。
(2)Java不能直接调用系统功能,但是可以调用c或者c++的程序
(3)多线程的实现方案
	A:继承Thread类
	将一个类声明为Thread的子类。 这个子类应该重写run类的方法Thread
    run()包含被多线程执行的代码
    使用start方法来开启线程并运行run方法,每个对象运行一个
    实现代码
    创建两个线程对象,调用start方法
    	MyThread mt1 = new MyThread();
		MyThread mt2 = new MyThread();
		mt1.start();
		mt2.start();
	B:实现Runnable接口
	自定义类实现Runnable接口
	重写run方法
	创建该自定义类的对象
	创建Thread的对象并把上一个对象作为参数传递
(4)线程的一些操作
	获取线程名 
		Thread类中的方法getName()
	设置线程名称 
		setName()
		通过构造方法赋值,必须在自定义类中写构造方法
	返回当前正在执行的线程对象
		static Thread currentThread()
	线程的调度
		a:分时调度
		b:抢占式调度 (Java采用的是该调度方式)
	获取和设置线程优先级
		a:默认是5
		b:范围是1-10,10最大
		c:方法
		获取:int getPriority()
		设置:void setPriority(int newPriority)
(5)线程的控制(常见方法)
	A:休眠线程
	public static void sleep(long millis) 毫秒
	B:加入线程
	public final void join() 等待该线程终止,即先执行这个线程
	C:礼让线程
	public static void yield() 暂停当前执行的线程对象。先执行其他
	D:后台线程
	public final void setDaemon(boolean on)
	将此线程标记为daemon线程或用户线程。 当运行的唯一线程都是守护进程线程时,Java虚拟机将退出
	E:终止线程
	public final void stop()不安全,弃用
	public void interrupt()终止线程的状态,并抛出一杯异常
(6)线程的生命周期

在这里插入图片描述

(7)多线程安全问题的原因(也是以后判断一个程序是否有线程安全问题的依据)
	A:是否有多线程环境
	B:是否有共享数据
	C:是否有多条语句操作共享数据
(8)同步解决线程安全问题
	同步的特点
		多个线程,使用同一个对象
	好处:解决了安全问题
	弊端:因为要判断是否有锁,所以比较耗费资源,降低效率
	A:同步代码块
		synchronized(对象) {
			需要被同步的代码;
		}


		锁必须是同一把锁!这里的锁对象可以是任意对象。
		
	B:同步方法
		把同步加在方法上。
		public synchronized void function()
		这里的锁对象是this
		
	C:静态同步方法
		把同步加在方法上。
		这里的锁对象是当前类的字节码文件对象(反射再讲字节码文件对象)
(9)回顾以前的线程安全的类
	A:StringBuffer
	B:Vector
	C:Hashtable
	D:如何把一个线程不安全的集合类变成一个线程安全的集合类
		用Collections工具类的方法即可。
		如:
		List<E> ls = Collections.synchronizedList(new ArrayList<E>)
多线程的锁
(1)JDK5以后的针对线程的锁定操作和释放操作
	Lock锁
	Lock接口
		void lock()创建锁
		void unlock()释放锁
	实现子类
		Lock lo = new ReentrantLock()
(2)死锁问题的描述和代码体现
	两个及以上现场在争夺资源过程中,发生的一种相互等待的现象
(3(线程间通信问题
	代码改进:
		A:最基本的版本,只有一个数据。
		B:改进版本,给出了不同的数据,并加入了同步机制
		C:等待唤醒机制改进该程序,让数据能够实现依次的出现
			wait()
			notify()
			notifyAll() (多生产多消费)
		D:等待唤醒机制的代码优化。把数据及操作都写在资源类中
(4)线程组
ThreadGroup 类
Thread(ThreadGroup group, Runnable target, String name) 
分配一个新的 Thread对象,使其具有 target作为其运行对象,具有指定的 name作为其名称,属于 group引用的线程组。 
利用线程组可同时操作线程组里所有的线程
(5)线程池
创建线程池
ExecutorService pool = Executors.newFixedThreadPool(int nThreads)
提交线程
pool.submit(new Runnable())
结束线程池
pool.shutdown()

(5)定时器
Timer
void schedule(TimeTask task,long delay)
void schedule(TimeTask task,long delay,long period)
TimerTask 
abstract void run()
boolean cancel()取消计时器任务
设计模式
(1)面试对象的常见设计原则
	单一
	开闭
	里氏
	依赖注入
	接口
	迪米特
(2)设计模式概述和分类
	A:经验的总结
	B:三类
		创建型
		结构型
		行为型
(3)改进的设计模式
	A:简单工厂模式
	B:工厂方法模式
	C:单例模式(掌握)
		a:饿汉式
		b:懒汉式
(4)Runtime
	JDK提供的一个单例模式应用的类。
	还可以调用dos命令。

网络编程

(1)网络编程:用Java语言实现计算机间数据的信息传递和资源共享
(2)网络编程模型
(3)网络编程的三要素
	A:IP地址
	B:端口
	C:协议
		UDP:数据打包,有限制,不连接,效率高,不可靠
		TCP:建立数据通道,无限制,效率低,可靠
(4)InetAddress
	没有构造方法
		A:成员全部是静态的(Math,Arrays,Collections)
		B:单例设计模式(Runtime)
        C:类中有静态方法返回该类的对象
    方法
    	InetAddress getByName(hostname);获取一个对象
    	String getHostName()
    	String getHostAddress()
    
(5)Socket机制
	socket: 包含IP地址和端口
	A:通信两端都应该有Socket对象
	B:所有的通信都是通过Socket间的IO进行操作的
(6)UDP协议发送和接收数据
	发送:
		创建UDP发送端的Socket对象
		DatagramSocket ds = new DatagramSocket();
		创建数据并把数据打包
		byte[] bytes = "Hello".getBytes();
		InetAddress ia = InetAddress.getByName("127.0.0.1"); 
		DatagramPacket pocket = new DatagramPacket(bytes,bytes.length,ia,10086);
		发送数据
		ds.send(pocket);
		释放资源
		ds.close();
		
	接收:
		创建UDP接收端的Socket对象
		DatagramSocket ds = new DatagramSocket(10086);
		
		创建数据包用于接收数据
		byte[] bytes = new byte[1024]
		DatagramPacket dp = new DatagramPacket(bytes,bytes.length)
		接收数据
		ds.recieve(dp);
		解析数据包
		String ip = dp.getAddress().getHostAddress
		String s = new String(dp.getData(),0,dp.getLength())
		释放资源
(7)TCP协议发送和接收数据(掌握 自己补齐代码)
	发送:
		创建TCP客户端的Socket对象
		Socket s = new Socket("127.0.0.1",12345);
		获取输出流,写数据
		OutputStream os = s.getOutputStream();
		os.write("Hello friend".getBytes());
		释放资源
		s.close();
	接收:
		创建TCP服务器端的Socket对象
		ServerSocket ss = new ServerSocket(12345);
		监听客户端连接                                                 Socket s = ss.accept();
		获取输入流,读取数据
		byte[] bys = new byte[1024];
		int len = is.read(bys);
		String str = new String(bys,0,len);
		String ip = s.getInetAddress().getHostAddress();
		System.out.println(ip+"--"+str);
		释放资源
		s.close();

反射

(1)类的加载及类加载器
	加载:
	将class文件读入内存,并为之创建一个Class对象
	任何类被使用时系统都会建立一个Class对象
	连接:
	验证 是否有正确的内部结构,并和其他类协调一致
	准备 负责为类的静态成员分配内存,并设置默认初始化值
	解析 将类的二进制数据中的符号引用替换为直接引用
	初始化:
	 
(2)反射:
	通过字节码文件对象,去使用成员变量,构造方法,成员方法
	
(3)反射的使用
	A:通过反射获取构造方法并使用
	B:通过反射获取成员变量并使用
	C:通过反射获取成员方法并使用
	
(4)反射案例
	A:通过反射运行配置文件的内容
	B:通过反射越过泛型检查
	C:通过反射给任意的一个对象的任意的属性赋值为指定的值
	
(5)动态代理
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值