java基础总结
一java运行机制
高级编程语言的运行方式
编译型编程语言: 源文件 --- 编译器 --- 机器码文件(发布) --- 执行
无法跨平台,运行效率高
解释型编程语言: 源文件(发布)--- 解释器 --- 机器码直接执行(逐行解释执行)
跨平台,运行效率低
先编译后解释:源文件 --- 编译器 --- 字节码文件(发布) --- 解释器 --- 执行(os)
java运行机制
源文件(.java) --- 编译器 --- 字节码文件(.class -- .jar) --- 解释器 --- jvm --- os
运算符写法:
① a++ :先获取变量a的值作为表达式的结果,再对a进行自加
② ++a :先对a进行自加,在获取a的值作为表达式的结果
三目运算符(三元运算符)
语法: boolean表达式 ? 值1 :值2
规则:当boolean值为true时,整个表达式的结果为值1,反之为值2
循环结构
1. 概念:
1)依据条件,重复并且有规律的执行一段代码
2)组成:循环起始条件 循环条件 循环计数器的变化
二循环分类
1)while循环 【 开发重点 】
① 语法: while( boolean值 --- 循环条件 ){
循环体
}
② 执行机制:
先判断循环条件
--- true : 进入循环体执行代码,循环体执行结束回到boolean值位置,继续判
断条件是否为true
--- false :则终止while循环语法结构,执行后续代码
③ 注意: 善用“死循环”
④ 执行特点: 先判断 在执行 ,循环体执行 0 ~ n
⑤ 使用场景:
--- 一段代码被多次重复执行
--- 代码中存在数字的递增或者递减
2)do...while 循环 【了解】
① 语法:
do{
循环体
}while( 循环条件 ) ;
② 执行机制:
先执行一次循环体,执行结束判断循环条件
--- true成立,则再次执行循环体,执行结束,再次判断
--- false不成立,则结束do...while语法结构
③ 执行特点:
先执行 在判断 , 循环体执行 1 ~ n 次
④ while和do..while的区别
--- while先判断在执行 do..while 先执行在判断
--- 普通功能二者没有区别,任选(建议while)
--- 在循环条件不满足时有区别,while一定不会执行循环体,do..while至少执行
一次循环体
3)for循环【开发重点】
① 语法:
for( 循环起始条件 ;循环条件 ;变量的变化 ){
循环体
}
② 执行机制
第一次循环:先执行“循环起始条件”,在判断“循环条件”
--- true:则开始执行循环体,执行“变量的变化”
--- false:不进入循环体
第二次循环:直接执行循环条件,判断此时条件是否满足
---true:执行循环体,变量变化
--- false:退出循环结构
第三次:照此类推
③ 执行特点: 先判断,在执行 ; 循环体会被执行 0~n次
④ 使用选择:
--- 确定次数的循环一般选择用for结构
--- 不确定次数循环一般选择用while结构 (死循环)
3. 循环控制语句 --- break continue
1)break :出现在循环结构里,表示 跳出/终止 循环结构的执行
2)continue:跳出当次循环体,执行下一次循环
3)break和continue的区别
① break除了用在循环结构里,还可以用在switch...case
② break跳出整个语法结构,continue跳出一次循环
4)了解 return --- 从当前函数返回(终止函数的运行)
三循环嵌套、
1)概念:在一个循环结构里,嵌入了另外一个循环结构
2)语法:
for(外层循环){
for(内层循环){
内层循环体
}
}
3)执行机制: 先做外层循环,在执行外层循环体时,在进入内层循环执行,内层
循环执行结束,对外层循环的变量做自加,再次判断外层循环条件。
以此类推
4)使用场景:打印图形时
--- 外层循环控制“行” ,内层循环控制“列”
5)循环控制语句在循环嵌套中的使用
--- continue默认退出的是本层当次循环(退出当次内层循环)
--- break 默认退出本层循环
6)Label标签:
可以为循环定义名字,break跳出时通过名字指定跳出哪一层循环结构
四函数(方法)
1. 概念:是由一组可以完成特定功能的代码组成的整体,可以通过函数名重复使用代码
定义语法: public static void 函数名( 参数表 ) { 函数体 }
形参相当于函数的“局部变量”,只能在函数内部使用(通过参数名使用) 在函数调用时,通过传入的实参赋值
数组
1. 概念:一次性定义多个“相同”类型的变量的语法结构,数组可以存储多个相同类型
的数据,并且对这些数据统一操作
元素:数组里每一个变量(数据)都称之为“元素”
数组名 = new 数据类型[ 元素个数 ] ;
声明的同时分配空间
数据类型[ ] 数组名 = new 数据类型【长度】;
分配空间的同时初始化元素
数据类型[] 数组名 = new 数据类型[]{ 值1,值2 ,。。。。。。}
直接初始化数组
数据类型[] 数组名 = { 值1,值2,。。。。。。}
注意:这条语句必须定义在一行,不能分开写;
1. 数组类型 变量 属于 “引用类型”
数组一旦声明定义成功,则里面每一个元素都会被赋予“初始值”
整数(byte short int long)默认初始值为 0
2)浮点(double float)默认初始值为0.0
3)char默认初始值为‘\u0000’
4)boolean默认初始值为 false
5)String(代表了引用类型)默认初始值为null
变量赋值
1)简单类型变量之间赋值,赋的是“具体的数据”(值)
2)数组变量之间赋值,赋的是地址(变量里存放的地址)
扩容做法
使用System.arraycopy() void
int [] n= {6,2,3};
int []c = new int[n.length*2];
System.arraycopy(n, 0, c, 0, n.length);
int [] d = java.util.Arrays.copyOf(a, a.length*2);
n=d
五面向对象
概念:一切客观存在的事物都是对象。
对象有什么:特征(这个对象有什么)和行为(这个对象能干什么)。
特征:属性(变量)
行为:方法(函数)
程序中的对象代表现实中的对象,解决现实生活中的问题。
2.什么是类
概念:类是模版,从一组相同或者类似的对象中进行共性的抽取,保留关注的部分。
3.类和对象
类:规定了对象具有哪些属性和方法。
对象:是类的实例。
4.如何创建对象?
语法:类名 引用名 = new 类名();
为属性赋值:引用明.属性名 = 值;
调用方法:引用名.方法名();
六重载
概念:在一个类中有多个相同名称的方法。
要求:
1>方法名相同
2>参数列表不同(类型,顺序,个数)
3>与访问修饰符和返回值类型无关
6.实例变量和局部变量的区别?
局部变量 实例、成员变量
定义位置 方法内 类中方法外
默认值 无(先赋值再使用) 有,同数组一样
作用范围 定义行到代码块结束 本类中都有效
命名冲突 不能重名 不能重名,局部变量和实例变量可以冲突,访问时,局部变量优先
七构造方法
概念:类中的一个特殊方法。
作用:用于创建对象。
要求:
1>方法名和类名相同
2>没有返回值类型
注意:
1>构造不能手动调用。
2>如果类中没有显示定义构造方法,编译器默认提供无参构造。
创建对象的步骤(3):
1>内存中分配对象空间
2>初始化属性
3>执行构造方法中的代码
[4>使用引用指向对象空间]
构造方法重载作用:
为属性赋值
八this(引用)
概念:当前对象。
用法:
1>this.属性 :防止局部变量和实例变量命名冲突
2>this.方法名() :调用本来中的方法
3>this()或者this(实参) : 防止冗余代码,调用其他构造完成对部分属性进行赋 值
注意:
当在一个构造方法中使用this调用本类中其他构造,调用语句必须放在第一行
九封装
概念:属性私有化,提供getXXX和setXXX方法。
作用:保证数据的安全
十继承
概念:类与类之间特征和行为的一种赠与或获得。(了解)
语法:class 子类 extends 父类{}
父类的选择:(了解)
重合点越多,越接近直接父类
重合点越少,越接近Object类
特点:java只能单继承,不能多基层,但可以多级继承,形成继承体系结构
继承好处:提高代码的复用性和可扩展性。
不可继承:
1>父类的构造方法
2>父类的private修饰的成员
3>父子类不在同一个package中,父类default修饰的成员
十一访问修饰符
本类 同包 不同包父子类 其他
private √
默认 √ √
protected √ √ √
public √ √ √ √
十二覆盖
概念:当父类方法无法满足子类需求,子类中可定义和父类相同的方法,这叫覆盖(Override)
要求:
1>返回值类型 方法名 参数列表一致
2>访问修饰符要么和父类相同要么更宽
注意:子类覆盖父类方法后,优先执行子类覆盖后的方法。
面试题:Overload和Override?
十三super:父类的引用
super.方法名(): 调用父类中的方法
super.属性:调用父类中的属性
super():调用父类无参构造
super(实参):调用父类有参构造
注意:
子类中每一个构造方法中,都隐式存在super()。
如果构造中没有显示书写super(),编译器默认提供。
同一个构造中super()或者super(实参)和this()或者this(实参)不能同时出现
构造方法不支持递归调用
十四多态
概念:父类引用指向子类对象。
举例: Animal a = new Dog();
注意:
1>二者之间必须存在继承关系
2>使用父类引用只能调用父类中所声明的属性和方法,不能直接调用子类中独有的成员
多态中的覆盖
如果子类覆盖了父类的方法,使用父类引用调用时,优先执行子类中覆盖后的方法,子类中如果没有,那么执行父类中的方法。
多态的应用
1>使用父类作为方法的形式参数实现多态,接收参数的范围更广泛
2>使用父类作为方法的返回值类型实现多态
多态的优点
1>屏蔽子类间的使用差异
2>降低耦合度
向上转型(装箱):使用父类引用存储子类对象
向下转型(拆箱):将父类引用中所保存的真实子类对象转换成本身类型
instanceof:判断引用中所保存的真实类型是什么
语法:引用 instanceof 数据类型
返回布尔类型(true,false)
十五static
实例属性:每个对象都拥有自己独立的属性,任何对象对其修改,不会影响其他对象
静态属性:全类共享,只有一份,共享给多个对象,任何对象对其修改,会影响其他对象
什么是静态:(背)
1.静态(static),能够修饰属性和方法
2.不需要创建对象可直接通过类名访问
3.全类共享,只有一份,不会因创建多个对象而产生多份
4.静态属性(类属性) 静态方法(类方法)
静态方法访问方式:
同一个类中有两个静态方法,A方法调用B方法怎么调用?
在A方法中直接写B方法的名称
在不同类中静态方法怎么调用?
类名.方法名
静态的注意事项:(背)
1>静态方法中可以直接访问静态成员
2>静态方法中不能直接访问非静态成员
3>静态方法中不能使用this和super
4>静态方法能被继承,没有多态,方法不能被重写
5>静态代码块在类加载时会执行且只执行一次
类加载:当JVM首次使用这个类时,一定要先加载到内存中。
类加载时机:(背)
创建对象
创建子类对象
调用静态属性
调用静态方法
Class.forName("路径");
动态代码块:
语法:{}
执行地位:初始化属性后,执行构造方法中代码之前
静态代码块:
语法:static{}
执行地位:静态属性之后,创建对象之前
十六abstract(抽象)
修饰类:表示抽象类,不能独立创建对象。(背)
抽象类作用:被子类继承,提供共性的属性和方法(背)
作为引用,强制使用多态
抽象的总结:(背)
1>使用abstract修饰类,表示抽象类,不能new对象
2>抽象类可以声明引用
3>使用abstract修饰方法,表示抽象方法,只有声明,没有
实现
4>有抽象方法的类一定是抽象类
5>抽象类中不一定有抽象方法
6>子类继承抽象类,要么覆盖父类中所有抽象方法,要么声明为抽象类
十七final:最终
修饰:(背)
修饰类:无法被继承
修饰方法:无法被覆盖
修饰变量:只能赋值一次(常量)
修饰实例变量(实例常量):没有默认值,赋值时机初始化、动态代码块、构造方法(如果使用构造方法赋值,需要在每一个构造方法中都要有赋值语句)
修饰静态实例变量(静态实例常量):没有默认值,赋值时机初始化,静态代码块
修饰变量:值不能改变
修饰引用:引用中存储的地址不能改变
注意:private abstract:不能同时出现
abstract final:不能同时出现
public static final:可以声明静态常量
十八接口
接口和抽象类异同:(背)
相同:
1>编译之后都会生成对应的字节码文件
2>不能创建对象
3>可以声明引用
4>可以使用Object类定义的方法
不同:
1>接口中只能定义公开静态常量,隐式存在public staic final
2>接口中只能定义公开抽象方法,隐式存在public abstract
3>接口中没有构造方法
接口概念:接口是一种能力和约定。
应用:java为单继承,当父类中方法种类无法满足子类的需求,可以通过接口来扩宽子类的能力
特点:接口可以多实现
任何类实现接口必须覆盖接口中的抽象方法,否则必须声明为抽象类
接口多态:接口引用指向实现类对象,只能调用接口中所声明的方法。
类与类:单继承(背)
类与接口:多实现
接口与接口:多继承
接口的好处:(背)
1>更自然的使用多态
2>降低耦合性
3>更容易搭建框架
4>更容易更换具体实现
5>设计与实现分离
十九内部类
概念:在一个类中定义一个完整的类。
特点:
1>编译后可以形成独立的字节码文件。
2>内部类可以访问外部类的私有成员,不破坏封装
3>内部类为外部类提供必要的功能组件
内部类的分类:(背)
1>成员内部类
2>静态内部类
3>局部内部类
4>匿名内部类
成员内部类:
1>可以访问外部类的私有成员,不破坏封装
2>当外部类、和内部类实例变量重名时,优先访问内部类
3>访问外部类属性和方法
外部类名.this.属性 外部类名.this.方法()
4>成员内部类不能定义静态成员
静态内部类
1>不依附外部类对象,可直接创建静态内部类对象或者访问静态内部类中的静态成员
2>静态内部类只能直接访问外部类的静态成员
局部内部类:
定义位置:方法内部
作用范围:局部内部类的作用范围和创建对象的范围仅限于当前方法
局部内部类无法访问当前方法的局部变量,需要加final修饰
匿名内部类:
和局部内部类所有的特征都一样。
语法:必须继承一个类或者实现一个接口
创建对象:只能创建一个对象
优点:代码少
缺点:可读性差
二十Object:
任何类都会直接或者间接继承Object,所有的对象都可以使用Object类中的方法
Object类型的引用可以接收任何对象
getClass():返回引用中存储的真实类型 ,即class +包名+ 类名
应用:判断两个引用中存储的真实类型是否一致
hashCode():返回该对象的哈希吗值。
相同的对象返回的哈希码值一定是相同的,尽量保证不同对象返回不同哈希码值。
toString():返回该对象的字符串表示形式(包名+类名+@+十六进制的哈希值)
应用:覆盖toString(),将所有的属性值拼接为字符串进行返回。
Object:
equals():默认比较地址,覆盖后比较内容
equals覆盖的要求:
1>判断两个对象地址是否相同
2>判断对象是否为null
3>判断两个对象类型是否一致(getClass)
4>强制转换
5>比较对象的各个属性值
==和equals的区别?
==可以比较基本和引用类型。
比较基本类型比较的是数值是否相同
比较引用类型比较的是地址是否相同
equals:只能比较引用类型
默认比较地址,覆盖后比较两个对象的内容是否相同
finalize:
用于垃圾回收。(面试题:final finally finalize)
二一包装类:
概念:基本数据类型对应的引用数据类型。
基本类型 包装类类型(背)
byte Byte
short Short
int Integer
long Long
float Float
double Double
boolean Boolean
char Character
Byte、Short、Integer、Long、Float、Double六个包装类共性属性:
MAX_VALUE:最大值
MIN_VALUE:最小值
共性的构造方法:
Byte:
Byte(byte value)
Byte(String s)
Short:
Short(short value)
Short(String s)
Integer:
Integer(int value)
Integer(String s)
....
四个整数的包装类共性方法:
byteValue():得到基本数据类型byte的值 Integer i = new Integer(12); int i1 = i.intValue();
ShortValue():得到基本数据类型short的值
intValue():得到基本数据类型int的值
longValue():得到基本数据类型long的值
static byte parseByte(String s):字符串转换成byte
static short parseShort(String s):字符串转换成short
static int parseInt(String s):字符串转换成int (掌握) int i= Integer.parseInt(s);
static long parseLong(String s):字符串转换成long
Byte:(掌握)
static Byte valueOf(byte b):将byte转成Byte
static Byte valueOf(String s):将字符串转成Byte
Short:
static Short valueOf(short b):将short转成Short
static Short valueOf(String s):将字符串转成Short Integer ii = Integer.valueOf(s);
.....
整数缓冲区:(背)
java预先创建256个对象存在数组中。
为什么有缓存:进行复用
1.5版本(背)
自动装箱:将基本类型转换为包装类类型(Byte b = (byte)100 )
自动拆箱:将包装类类型转换为基本类型
Byte b = new Byte("123");
byte b2 = b;
二二String:
概念:由多个字符组成的一串数据。
构造方法:(掌握)
String():无参构造(为了创建对象)
String(byte[] bytes):将byte数组转成字符串
String(byte[] bytes, int index, int length):将字节数组的一部分转成字符串
String(char[] value):将字符数组转成字符串
String(char[] value, int offset, int count):将字符数组的一部分转成字符串
字符串特点:(背)
1>字符串字面值是Stirng的实例
2>字符串一旦创建,值不能改变(看图)
面试题:
String s = "abc" 和 String s2 = new String("abc")区别?(看图)
前者创建对象
后者创建两个对象
字符串判断功能:
boolean contains(String s):判断字符串中是否包含指定字符串
boolean endsWith(String suffix):判断是否以指定字符串结尾
boolean startsWith(String prefix):判断是否以指定字符串开头
boolean equals(String s):判断两个字符串的内容是否相同 (区分大小写)(掌握)
boolean equalsIgnoreCase(String anotherString):判断两个字符串的内容是否相同(不区分 大小写)
boolean isEmpty():判断字符串是否为空
字符串获取功能
char charAt(int index):返回指定索引处的字符(掌握)
String concat(String str):字符串的拼接
int indexOf(String str):获取指定字符串的第一次出现的索引
int indexOf(String str, int fromIndex):获取指定字符串在指定索引之后第一次出现的位置
int lastIndexOf(String str):获取指定字符串最后一次出现的索引
int length():返回此字符串的长度(掌握)
String substring(int beginIndex):截取指定位置的字符串(掌握)
截取包括指定的位置 String s = ss.substring(1);包括下标1,实质为end
String substring(int start, int end):截取从start开始到end结束之间的字符串(包括start 不 包括end)
String toString():返回对象的字符串表示形式
字符串的转换功能
byte[] getBytes():字符串转字节数组
char[] toCharArray():字符串转字符数组
String toLowerCase():字符串转小写
String toUpperCase():字符串转大写
static String valueOf(char c):字符转字符串
static String valueOf(char[] data):字符数组转字符串
替换功能: String replace(String s, String s2)
分割: String[] split(String regex):分割其实代表的是去除特定的字符串返回字符串数组
去除两端空格: String trim()
二三StringBuffer:
概念:可变长字符串,线程安全,效率低。
StringBuffer():无参构造和有参构造
添加功能:
StringBuffer append(String s):追加元素(返回本身)
StringBuffer insert(int index, String str):在指定的索引位置插入指定的字符串
删除功能:
StringBuffer delete(int start, int end):从start开始到end之间所有元素删除(包含start不包含end)
StringBuffer deleteCharAt(int index):删除指定索引下的字符
反转功能:
StringBuffer reverse()
二四StringBuilder:
概念:一个可变长的字符串,线程不安全,效率高。
面试题:String和StringBuffer和StringBuilder?
String内容长度不可变
StringBuffer和StringBuilder:内容长度可变
StringBuffer:线程安全,效率低。
StringBuilder:线程不安全,效率高
二五BigDecimal:能够保存精确的小数。
构造方法
BigDecimal(String val):将字符串转成BigDecimal类型
成员方法:
BigDecimal add(BigDecimal augend):加法
BigDecimal subtract(BigDecimal bd)减法运算
BigDecimal multiply(BigDecimal bd)乘法运算
BigDecimal divide(BigDecimal divisor):除法
BigDecimal remainder(BigDecimal bd)取余
二六集合:
数组和集合的区别?(背)
长度的区别:
数组一旦创建长度不可变
集合长度可变
存储的元素数据类型
数组能够存储基本数据类型和引用数据类型
集合只能存储引用类型
Collection:Collection 层次结构 中的根接口
一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。(背)
添加功能: boolean add(Object e):添加元素 boolean addAll(Collection c):添加一个集合的元素
删除功能: boolean remove(Object o):删除指定的第一个元素 void clear():删除所有元素
获取功能:int size():得到集合中元素的个数
转换功能: Object[] toArray():将集合转成数组
判断功能:boolean isEmpty():判断集合中是否为空(集合中为空得到true , 否则false)
集合的使用步骤:
集合的使用步骤:
1>创建集合对象
2>添加元素
3>遍历(迭代器遍历)
1>>得到迭代器对象
2>>判断是否有下一个元素
3>>如果有就获取
List接口
概念:List:有序(存入和取出的顺序一致),元素可重复。(背)
List独有的方法:
void add(int index, Object element):在指定的索引位置插入指定的元素
Object get(int index):获取指定索引位置的元素
Object remove(int index):删除指定索引位置的元素并返回删除的内容
Object set(int index, E element):替换指定索引位置的元素
List接口三个实现类:
ArrayList:
底层数组实现,查询快,增删慢
线程不安全,效率高
Vector:
底层数组实现,查询快,增删慢
线程安全,效率低
LinkedList:
底层链表实现,查询慢,增删快
线程不安全,效率高
Vector:
void addElement(Object obj):添加元素 -- add()
void removeElementAt(int index):删除指定索引位置的元素 --remove()
void setElementAt(Object obj, int index):修改指定位置的元素
LinkedList:
添加:
void addFirst(E e): 将指定元素插入此列表的开头。
void addLast(E e):将指定元素添加到此列表的结尾
获取: E getFirst(): 返回此列表的第一个元素 E getLast():返回此列表的最后一个元素
删除: E removeFirst():移除并返回此列表的第一个元素。 E removeLast(): 移除并返回此列表的最后一个元素。
泛型:保证集合的安全,强制集合所存储的类型一致。
格式:<引用类型>
泛型的好处:
1>避免强制类型转换
2>运行期问题提前到了编译期
3>解决了黄线警告
泛型类:格式:修饰符 class 类名<参数类型>
泛型方法:格式 : 修饰符 <类型> 返回值类型 方法名(形参列表){}
泛型接口:interface 接口名<类型>
泛型高级通配符:
?:任意类型
? extends E:向下限定E及其子类
? super E:向上限定E及其父类
ConcurrentModificationException:并发修改异常。
* 原因:
迭代器依赖于集合存在,迭代器遍历表示将集合中的数据拷贝一份进行遍历,迭代器遍历过程中,集合添加了元素,而迭代器不知道。
HashSet:底层哈希表,它不保证 set 的迭代顺,特别是它不保证该顺序恒久不变。
如何保证唯一:哈希表
哈希表:hashcode()+equals()
HashSet添加元素的方法底层依靠两个方法:hashcode()+equals()
首先判断对象的哈希值是否相同
相同:执行equals()
比较内容是否相同
相同:不存
不同:存储
注意:使用HashSet 存储自定义对象,自定义类必须覆盖hashcode和equals
hashcode要求:尽量不同对象返回不同哈希码值
equals要求:比较两个对象的内容是否相同
TreeSet:
特点:排序,不重复。 排序:自然排序
自定义类必须实现Comparable接口,覆盖当中的compareTo方法
比较器排序
通过构造方法创建Comparator的实现类(可以通过匿名内部类的方式)
LinkedHashSet:具有可预知迭代顺序。
底层哈希表和链表
哈希表:保证元素唯一
链表:保证元素有序
Map:存储键值对,键不能重复,值可以重复。
Map和Collection的区别?
Map是双列集合,存储键值对(夫妻对),Map键不能重复,值可重复。
Collection是单列集合,存储元素(光棍),子接口List可重复,子接口Set不能重复
方法:
添加功能:
V put(K key, V value):添加键值对
返回值: 该键第一次存储返回null
第二次存储会返回上一次该键所对应的值
删除功能:
void clear():清除集合中所有键值对
V remove(Object key):根据键删除此键值对,返回该键对应的
判断功能:
boolean containsKey(Object key):判断是否包含指定的键
boolean containsValue(Object value):判断是否包含指定的值
boolean isEmpty():判断是否为空
获取功能:
V get(Object key):根据键获取值
int size():获取集合的长度
Set<K> keySet():获取所有的键
Collection<V> values():获取所有的值
Set<Map.Entry<K,V>> entrySet():得到所有的键值对
K getKey():返回与此项对应的键。
V getValue():返回与此项对应的值。
遍历思路:
1>得到所有的键 keyset()
2>遍历键的集合,得到每一个键
3>根据键获取值 get()
思路:
1>得到所有的键值对
2>遍历键值对所在的集合,得到每一组键值对
3>根据键值对获取键和值
HashMap键存储自定对象
保证唯一需要在自定义类中覆盖hashCode和equals
TreeMap:存储自定义对象完成排序
想要完成排序必须实现Comparable接口完成自然排序
二七异常
异常:程序出现了不正常的情况。
异常的分类:
程序中的异常:Throwable
严重问题:Error
一般问题:Exception
运行时异常:不解决,代码不够严谨
编译时异常:必须解决,否则编译不通过无法运行
java异常的默认处理:
jvm会将异常名和出现的原因,出现的位置信息在控制台显示,只要出现问题程序就结束。
异常处理方式:
1.try...catch...finally
2.throws:抛出
格式:
try{
可能出现问题的代码
}catch(异常类名 变量名){
解决问题的方式
}}finally{
释放资源(io流 和 数据库)
}
注意:
1.try里面的代码越少越好
2.catch中必须有内容,哪怕一个简单的输出语句
try代码块中如果出现异常,jvm会自动进行抛出,然后和对应的catch匹配,匹配成功就会执行catch中的代码,执行完毕后try...catch...结束,继续执行后续代 注意:
1>能明确的异常尽量明确 2>多个catch应该处于并列关系,如果出现子父级别的异常,父类一定在最后一个catch中
异常中需要了解的方法:
String getMessage():返回异常的消息字符串
String toString():异常类名的全路径+: +getMessage()方法
void printStackTrace():产生异常的位置+toString()
异常处理的另一种方式:throws:抛出
格式:throws 异常类名1,异常类名2......
位置:只能写在方法声明的括号后面
注意:
在主方法中尽量不要throws
方法上抛出编译时异常,调用者必须处理,否则编译不通过无法运行
方法上抛出运行时异常,调用者无需处理,也可以处理
throw:用在方法中,表示主动抛出某个异常
格式:
throw 异常对象
throws: 使用在方法声明的后面,能够一次抛出多个异常类名 调用者处理
throw: 使用在方法中,一个只能抛出一个异常对象 方法内部进行处理
finally:异常处理的一部分,主要用于io流和数据库释放资源 注意:finally代码块中的内容一定会执行。
try...catch...finally
面试题:final,finalize,finally的区别?
final:
修饰类:类不能被继承
修饰方法:方法不能被覆盖
修饰变量:表示该变量为常量只能赋值一次
finally:
异常处理的一部分,主要用于io流和数据中,用于释放资源
finalize:Object类中的一个方法,用于垃圾回收。
try...catch...finally的变成格式?
try...catch...
try...catch...catch
try...catch...finally
try...catch...catch...finally
try...finally
自定义异常类:
1.继承RuntimeException
2.继承Exception
子父类存在方法覆盖,如果父类的方法没有抛出任何异常,子类方法内部出现异常只能try...catch..
子父类存在方法覆盖,如果父类方法抛出异常,子类方法只能抛出和父类相同的或者该异常的子类
二八File
File:文件和目录路径名的抽象表示形式。
构造方法:
File(String pathname):根据一个路径得到file对象
File(String parent, String child):根据一个目录+文件名得到一个file对象
File(File parent, String child):根据一个file+文件名得到一个file对象
创建功能:
boolean createNewFile():创建文件
boolean mkdir():创建单级目录
boolean mkdirs():创建多级目录
boolean delete():删除文件或者文件夹
注意:
java删除不走回收站
删除目录,此目录中不能存在文件或者文件夹
boolean renameTo(File dest):重命名
注意:
如果在同一个目录下:改名
如果不同目录下:改名并剪切
判断功能:
boolean exists():是否存在
boolean isFile():是否是文件
boolean isDirectory():是否是文件夹
获取功能:
String getAbsolutePath():获取绝对路径
String getName():获取文件或文件夹名
String getParent():获取父级目录
long length():获取长度
long lastModified():获取最后一次修改时间
String[] list():获取当前目录下所有文件和文件夹的名称数组
File[] listFiles(): 获取当前目录下所有文件和文件夹的File数组
IO流
FileOutPutStream构造方法:
FileOutputStream(File file):通过一个File对象得到字节输出流对象
FileOutputStream(String name):通过一个路径得到字节输输出流对象
字节输出流使用步骤:
A.创建字节输出流对象
B.写数据
C.释放资源
FileOutputStream fos = new FileOutputStream("a.txt");
fos.write("helloio".getBytes());
fos.close();
字节输入流:
1.创建字节输入流对象
2.读数据
3.释放资源
FileInputStream构造方法:
FileInputStream(String name):根据路径得到字节输入流对象
FileInputStream(File file):根据file对象得到字节输入流对象\
创建字节输出对象做了几件事情?
1.通知系统创建文件
2.创建了fos对象
3.将fos指向a.txt
为什么要close()?
1.将流对象变为垃圾,垃圾回收器就可以进行回收。
2.通知系统释放和该文件相关的资源
字节输出流写数据的三个方法:
void write(int b):写一个字节
void write(byte[] b):写一个字节数组
void write(byte[] b, int off, int len):写字节数组的一部分
如何换行?
写入换行符windows:\r\n Linux:\n Mac:\r
如何实现数据的追加:
FileOutputStream(String name, boolean append):最后一个参数为true表示追加
读数据:
int read():从此输入流中读取一个数据字节。
代码:
FileInputStream fis = new FileInputStream("a.txt");
int by = 0;
while((by = fis.read()) != -1){
System.out.print((char)by);
}
fis.close();
Corejava笔记 第二十天
二九字符流:
为什么出现字符流:字节流操作中文出现乱码
字符流 = 字节流+编码表
InputStreamReader构造方法:
InputStreamReader(InputStream in):创建一个使用默认字符集的 InputStreamReader。
InputStreamReader(InputStream in, String charsetName):创建使用指定字符集的InputStreamReader。
读取方法:
int read():读取单个字符
int read(char[] cbuf):将字符读入数组
OutputStreamWriter(OutputStream out, String charsetName):创建使用指定字符集的OutputStreamWriter。
写数据的方法:
void write(int c):写入单个字符。
void write(char[] cbuf):写入字符数组。
void write(char[] cbuf, int off, int len):写入字符数组的某一部分。
void write(String str):写入字符串。
void write(String str, int off, int len):写入字符串的某一部分。
close()和flush()的区别?
close():先刷新,后关流
flush():只刷新
OutputStreamWriter和InputStreamReader(可以设置编码)简单书写方式:
FileWriter FileReader(无法设置编码)
BufferedWriter(高效字符输出流)和BufferedReader(高效字符输入流)
void newLine():换行
String readLine():读取一个文本行
一次复制一行:
String s = null;
while((s = br.readLine()) != null){
System.out.println(s);
}
操作基本数据类型的流:
DataInputStream:
DataInputStream(InputStream in)
DataOutputStream:
DataOutputStream(OutputStream out)
注意:写入的数据类型顺序要和读取一致。
打印流:
PrintStream:字节打印流
PrintWriter:字符打印流
特点:只能写不能读
序列化流(能够将对象写入文件, 实现import java.io.Serializable接口
构造方法:
ObjectOutputStream(OutputStream out)
方法:
void writeObject(Object obj):将指定的对象写入 ObjectOutputStream
反序列化流(能够从文件中读取对象):ObjectInputStream
构造方法:
ObjectInputStream(InputStream in)
方法:
Object readObject():读取对象
Corejava笔记 第二十一天
三十多线程:
实现多线程的第一种方式:
1.自定义类继承Thread类
2.重写run()方法
3.创建线程对象
4.启动线程
面试题:
为什么重写run()?
不是所有的代码都需要被多线程执行,run()方法中的代码表示需要被多线程执行
run()和start()区别?
run():run方法中存放的是需要被多线程执行的代码,直接调用相当于调用普通方法
start():启动线程,由jvm调用run()
如何启动一个线程?
start()
Thread类中的方法:
String getName():返回该线程的名称
void setName(String s):设置线程名称
static void sleep(long millis):休眠 线程的休眠
void join():等待本线程终止
static Thread currentThread():返回对当前正在执行的线程对象的引用
获取主方法所在的线程名称 Thread.currentThread().getName()
出现线程安全问题的因素:
1.多线程环境
2.是否有共享数据
3.是否有多条语句操作共享数据
回想我们的程序是否满足以上三点:
1.多线程环境
2.是否有共享数据
3.是否有多条语句操作共享数据
java提供了:同步机制
语法:synchronized (对象) {
需要同步的代码
}
1.对象是什么 任意对象
2.需要同步的代码有哪些? 多条语句操作的共享数据
注意:同步关键就在对象上,如同锁的功能,多个线程应该使用同一把锁。
同步方法:将synchronized声明在方法上,返回值类型之前。
线程同步的好处:数据安全
线程同步的坏处:效率低
线程安全-- 同步 -- 效率低
线程不安全 -- 异步 -- 效率高