- 什么是java:
是一种面向对象的高级编程语言
- java的组成:
javase/j2se(java标准版),javaee/j2ee(java企业版)(13几种技术)
- java的应用:
internet程序(b/s)和桌面应用程序(c/s) browser
- 记事本开发程序的步骤
①编写:编写源文件Test.java 编译javac Test.java
②编译:字节码Test.class 运行java Test
③运行:运行结果
- java的基本机构
- 注意四点:
①类名的首字母要大写,要保证类名与文件名一样
②所有的括号要成对出现,遇到大括号的开始要缩进,大括号的结束要与其对应大括号的开始最前端对齐
③所有标点符号都是英文的
④每行只能放一句代码,每句以分号结束
- 用记事本开发程序的三步走
①编写
②编译
③运行
- 打印
System.out.print(); 只打印
System.out.println(); 打印+换行
- 转义:反斜杠必须双引号
制表位
换行
- 注释:
单行注释 ://注释内容 添加和取消:ctrl+/
段落注释: 添加:ctrl+shift+/ 取消:ctrl+shift+/
1. java 数据类型分为两大类 基本数据类型, 引用类型
2. 基本数据类型有 8 中 数值型 [byte , short , int , long , float ,double] char , boolean ]
3. 引用类型 [类,接口, 数组]
注:
Math.abs( num1 - num2) 此方法运用于两个浮点数之间比较如果小于一定精度就可以认为两个数相同。因为两个浮点数如果出现乘除关系会出现以下情况:
此时可以用到 Math.abs 方法
char可以直接存放一个数;但是当输出时并不会直接输出数字:(这时控制台出现的a是97代表的是字符a)
也可以反向操作:比如:定义一个char为一个字符在输出语句上加上(int)可以输出对应的数字
数据类型char 只能用单引号
在Java中char的本质是一个数对应输出时输出unicode码对应的字符
存取 true 和 false 不能用0和1代替这点和c语言不同
自动类型转换:(图中箭头所指可自动转换)例如:double = 80;输出80.0
细节:
当我们把精度(容量)大的数据类型赋值给精度(容量)小的数据类型时就会报错,反之就会自动转换
byte 类型 char 类型 short类型 三种类型之间不会自动转换。
把精度大的赋给精度小的就会造成进度损失。
char可以保存int的常量值不能保存int的变量值
byte short char 三者相互计算时会自动转换成 int 型
基本数据类型可以转换成字符串类型String只需要加 +“”
将字符串的数字提取出来进行计算
根据索引将字符串的首位提取出来,必须用char接收(必须确定String里面存放的内容可以提取;比如存放的是字符“hello”就会抛出异常;所以说使用charAt提取时必须保证里面的是可以提取出的数值。
➗ 的使用
% 取余数 (取模)
在 % 的本质,看一个公式: a % b = a - a/b * b (此时的a/b取整数不看余数)
例如: 10 % 3 = 10 - 10/3 * 3 整体算下来 等于1
-10 % 3 = -10 - (-10)/3 * 3 = -1
10 % -3 = 10 - 10/(-3) * (-3) = 1
++ 的使用 :(重点:i++和 ++i)
i++作为独立语句使用时 和++i的效果一样
作为表达式使用时候:
i++ :先赋值后自增
++i :先自增后赋值
-- 一样的道理同++ 还有 *
关系运算符:
&& 和 & (只要有一个false结果就是false 两个只要有一个是false if语句里面的代码就不会被执行)
&& 短路,如果第一个条件为false后面的不在判断(不再执行后面的代码)
& 逻辑,如果第一个条件为false后面的会继续判断(执行后面的代码)
| 和 || (只要有一个为真结果就为真 if判断时用只要两者有一个为真if里面的代码就会被执行)
同上的不同是:( | | )如果第一个条件为真则后面的不会再执行(整体为真);效率高
( | )如果第一个条件为真则后面依旧会执行(第二个为真则整体真,为假则整体假)
! 取反(真变假 假变真) 真假互换
^ 异或 当两者不同时结果为 T 否则为 F
+= : A= A+B
-= :A= A-B
/= : A= A/B
%= : A = A%B
复合赋值运算会进行类型转换
条件表达式? 表达式1: 表达式2;
运算规则:
1. 如果条件表达式为true,运算后的结果是表达式1;
2. 如果条件表达式为false,运算后的结果是表达式2;
口诀: [一灯大师:一真大师]
例如:
图中为三元运算符用法;若红色方框内成立则为真,整体为true 执 黄色方框
若红色方框内不成立则为假,整体为false 执行蓝色方框
一定要注意
这时会先把num1的值赋给num3然后num1再自增
二进制(BIN):0,1 ,满2 进1.以0b 或0B 开头。
八进制(OCT):0-7 ,满8 进1. 以数字0 开头表示。
十进制(DEC ):0-9 ,满10 进1。
十六进制(HEX):0-9 及A(10)-F(15),满16 进1. 以0x 或0X 开头表示。此处的A-F 不区分大小写。
进制转换:(分三组)
第一组:
- 二进制转十进制
- 八进制转十进制
- 十六进制转十进制
规则:从最低位(右边)开始,将每个位上的数提取出来,乘以16 的(位数-1)次方,然后求和。
案例:请将0x23A 转成十进制的数
0x23A = 10 * 16^0 + 3 * 16 ^ 1 + 2 * 16^2 = 10 + 48 + 512 = 570
总结:几进制转十进制;将每个位上的数提取出来,乘以几的(位数-1)次方,然后求和。
第二组:
- 十进制转二进制
规则:将该数不断除以2,直到商为0 为止,然后将每步得到的余数倒过来,就是对应的二进制。
- 十进制转八进制
规则:将该数不断除以8,直到商为0 为止,然后将每步得到的余数倒过来,就是对应的二进制。
- 十进制转十六进制
规则:将该数不断除以16,直到商为0 为止,然后将每步得到的余数倒过来,就是对应的二进制。
总结:十进制转几进制;将该数不断除以几,直到商为0 为止,然后将每步得到的余数倒过来,就是对应的几进制。
第三组
- 二进制转八进制
规则:从低位开始,将二进制数每三位一组,转成对应的八进制数即可。
- 二进制转十六进制
规则:从低位开始,将二进制数每四位一组,转成对应的十六进制数即可。
第四组
- 八进制转二进制
将八进制数每1 位,转成对应的一个3 位的二进制数即可
- 十六进制转二进制
规则:将十六进制数每1 位,转成对应的4 位的一个二进制数即可。
程序是自上而下执行的,中间没有任何判断和跳转。
1) 单分支 if
2) 双分支 if-else
3) 多分支 if-elseif -....-else
对象:具体到某一个事物(实体)的时候,看的见,摸的着
类:从相同类型的一组对象中抽象出来的共同特征和行为,看不见摸不着
对象是类的实体
类是对象的类型
类和对象:多个是类,单个理解对象,类无属性值,对象是有属性值
定义类
public class 类名{
成员变量(属性)
数据类型 变量名
...
成员方法(行为)
public void 方法名(){
}
...
}
创建对象
类名 对象名=new 类名();
对象的使用
对象名.属性
方法
作用
用法
charAt()
返回指定索引位置的字符
concat()
在字符串的后面追加
equals()
equals属于object的方法 通常用于比较对象
在字符串里比较内容是否相等
equalsIgnoreCase()
将此 String 与另一个 String 比较,不考虑大小写。
indexOf()
返回指定字符在此字符串中第一次出现处的索引。
lastIndexOf()
从后往前寻找,与上一个相同
substring(2,3)
字符串截取,从2截到3
前包后不包,
、
length()
返回在字符串长度
compareTo()
按字典顺序比较两个字符串。
如果第一个字符和参数的第一个字符不等,结束比较,返回第一个字符的ASCII码差值。
split()
根据给定正则表达式的匹配拆分此字符串。
按,分开
trim()
返回字符串的副本,忽略前导空白和尾部空白。
isEmpty()
判断字符串是否为空。
contains()
判断是否包含指定的字符系列。
返回Boolean类型
replace()
String replace(char oldChar, char newChar)
oldChar :要替换的字符
newChar :替换成的字符
toUpperCase()
使用默认语言环境的规则将此 String 中的所有字符都转换为大写
toLowerCase()
使用默认语言环境的规则将此 String 中的所有字符都转换为小写
5.2.1. 包的本质
5.2.2. 包的作用:
5.2.3. 包的基本语法
5.2.4. 包的命名规则
5.2.5. 常用包
一个包下,包含很多的类,java 中常用的包有:
1) java.lang.* //lang 包是基本包,默认引入,不需要再引入.
2) java.util.* //util 包,系统提供的工具包, 工具类,使用 Scanner
3) java.net.* //网络包,网络开发
4) java.awt.* //是做 java 的界面开发,GUI
5.3.1. 基本介绍:
java 提供四种访问控制修饰符号,用于控制方法和属性(成员变量)的访问权限(范围)
1) 公开级别:用 public 修饰,对外公开
2) 受保护级别:用 protected 修饰,对子类和同一个包中的类公开
3) 默认级别:没有修饰符号,向同一个包的类公开.
4) 私有级别:用 private 修饰,只有类本身可以访问,不对外公开
5.3.2. 4种访问修饰符的范围
1
访问级别
访问修饰符
本类
同包
子类
不同包
2
公开
public
√
√
√
√
3
受保护
protected
√
√
√
×
4
默认
没有修饰符
√
√
×
×
5
私有
private
√
×
×
×
5.3.3. 访问修饰符的细节
5.4.1.1. 返回值使用细节:
- 一个方法最多有一个返回值 [思考,如何返回多个结果 返回数组 ]
- 返回类型可以为任意类型,包含基本类型或引用类型(数组,对象)
- 如果方法要求有返回数据类型,则方法体中最后的执行语句必须为return 值;而且要求返回值类型必须和return的值类型一致或兼容
- 如果方法是void,则方法体中可以没有return语句,或者 只写 return
返回值类型与方法名前面的类型保持一致;
只能返回一个返回值,如果想要返回多个返回值,可以用数组
5.5.1. 递归的规则
递归调用的过程中,每递归一次,就会创建一个新的栈空间,直到最后一次递归执行完毕,依次返回。
- 静态的不能访问非静态的,非静态的可以调用静态的
- static静态的 只能修饰类成员,一但修饰了类成员,类成员属于类,不属于对象
作用:区分类和对象必须分清类和对象
- 被 static 修饰的成员属于类,类成员、静态成员 通过【类.成员】调用
- 不被 static 修饰的成员属于对象,对象成员,非静态成员 通过【成员.成员】调用
- 静态成员可以被所有对象共享
6.1.1. 基本介绍
面向对象编程有三大特征:封装、继承和多态。
6.1.2. 封装介绍
6.1.3. 封装的理解和好处
6.1.4. 封装的实现步骤 (三步)
6.1.5. 构造器:
6.2.1. 为什么需要继承?
6.2.2. 继承基本介绍和示意图
继承可以解决代码复用,让我们的编程更加靠近人类思维.当多个类存在相同的属性(变量)和方法时,可以从这些类中
抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends 来
声明继承父类即可。画出继承的示意图
6.2.3. 继承的基本语法
有共同属性和方法的类;可以再建一个类将这些相同的属性和方法提取到另一个新的类里面,让其他类直接继承这个类就可以了
6.2.4. 继承给编程带来的便利
- 代码的复用性提高了
- 代码的扩展性和维护性提高了
6.2.5. 继承的的细节问题
- 子类继承了所有的属性和方法,非私有的属性和方法可以在子类直接访问, 但是私有属性和方法不能在子类直接访问,要通过父类提供公共的方法去访问
- 子类必须调用父类的构造器, 完成父类的初始化
- 当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会去调用父类的无参构造器,如果父类没有提供无参构造器,则必须在子类的构造器中用super 去指定使用父类的哪个构造器完成对父类的初始化工作,否则,编译不会通过(怎么理解。)
也就是说父类中如果定义了带参构造器,没有写无参构造器,那么父类默认存在的(一个类不用写默认带无参构造器)无参构造器将会被定义的带参构造器覆盖掉,那么此时 子类中必须要使用super指明使用哪个构造器。
- 如果希望指定去调用父类的某个构造器,则显式的调用一下: super(参数列表)
- super 在使用时,必须放在构造器第一行(super 只能在构造器中使用)
- super() 和this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器
- java 所有类都是Object 类的子类, Object 是所有类的基类.
- 父类构造器的调用不限于直接父类!将一直往上追溯直到Object 类(顶级父类)
- 子类最多只能继承一个父类(指直接继承),即java 中是单继承机制。
思考:如何让A 类继承B 类和C 类? 【A 继承B, B 继承C】
- 不能滥用继承,子类和父类之间必须满足is-a 的逻辑关系
6.2.6. 继承的内存布局:
案例中:grandPa类 被 father类继承 father被son继承
如果son调用一个自己没有的属性,那么就会向继承的父类以及爷爷类寻找一直到object类;
① 如果他的父亲类有此属性,则返回
② 如果他父亲和爷爷都有,但父亲的属性是私有的不能访问,那么他不会继续向上寻找而是直接报错!!!
6.2.7. super 关键字
6.2.7.1. 概念
super 代表父类的引用,用于访问父类的属性、方法、构造器
6.2.7.2. 基本语法
在调用方法时:
方法名() 会先在本类寻找
-
-
- 本类找到直接用
- 本类找不到,向上寻找,找到了不能访问(私有的)直接报错
- 向上寻找,一直到object都没有找到,提示方法不存在
-
super.方法名()
会直接在父类中开始向上寻找,也就是省略了上面的
属性 和 this.属性
-
-
- 先找本类,如果有,则调用
- 如果没有,则找父类(如果有,并可以调用,则调用)
- 如果父类没有,则继续找父类的父类,整个规则,就是一样的,直到对象(Object)类提示:如果查找属性的过程中,找到了,但是不能访问,则报错,无法访问如果查找属性的过程中,没有找到,则提示属性不存在
-
super.属性 也是从父类开始寻找,其他规则一样
6.2.7.3. super 的使用细节和带来的便利
6.2.7.4. super 和 this 的比较
6.2.8. 方法重写/覆盖(override)
6.2.8.1. 概念:
6.2.8.2. 注意事项和使用细节
方法重写也叫方法覆盖,需要满足下面的条件
6.2.8.3. 重写 和 重载 (二者毫无关系)
6.3.1. 基本概念:
方法或对象具有多种形态。是面向对象的第三大特征,多态是建立在封装和继承基础之上的。
6.3.2. 多态的具体表现:
6.3.3. 多态的注意细节:
- 多态的前提是:两个对象(类)存在继承关系
- 多态的向上转型
//(1)可以调用父类中的所有成员(需遵守访问权限)
//(2)但是不能调用子类的特有的成员
//(#)因为在编译阶段,能调用哪些成员,是由编译类型来决定的
//(4)最终运行效果看子类(运行类型)的具体实现, 即调用方法时,按照从子类(运行类型)开始查找方法
//,然后调用,规则我前面我们讲的方法调用规则一致。
eg:
- 多态向下转型
- 属性没有重写之说!属性的值看编译类型
- instanceOf 比较操作符,用于判断对象的运行类型是否为 XX 类型或 XX 类型的子类型
6.3.4. java 的动态绑定机制
假如 B 继承 A类,在代码执行过程中,遇见调用方法的时候,会首先到绑定的运行类(等号的右边new 出来的)去寻找这个方法,如果在本类中并没有找到这个方法,那么就去父类中寻找这个方法,父类中有这个方法直接调用,如果在父类的这个方法体中还有调用别的方法的,还会首先在子类中寻找也就是B类中寻找,这便是Java的绑定机制;(只有方法🈶绑定机制,属性是没有绑定机制的。)
7.1.1. hashCode
老韩的 6 个小结:
- 提高具有哈希结构的容器的效率!
- 两个引用,如果指向的是同一个对象,则哈希值肯定是一样的!
- 两个引用,如果指向的是不同对象,则哈希值是不一样的
- 哈希值主要根据地址号来的!, 不能完全将哈希值等价于地址。
- 案例演示[HashCode_.java]: obj.hashCode() [测试:A obj1 = new A(); A obj2 = new A(); A obj3 = obj1]
- 后面在集合,中 hashCode 如果需要的话,也会重写, 在讲解集合时,老韩在说如何重写 hashCode()
7.1.2. toString()
- 默认返回:全类名+@+哈希值的十六进制,【查看 Object 的 toString 方法】 子类往往重写 toString 方法,用于返回对象的属性信息
- 重写 toString 方法,打印对象或拼接对象时,都会自动调用该对象的 toString 形式.
- 当直接输出一个对象时,toString 方法会被默认的调用, 比如 System.out.println(monster); 就会默认调用 monster.toString()也就是说,如果在类中没有改写 toString 会输出 全类名+@+哈希值的十六进制。
7.1.3. finalize 方法
- 当对象被回收时,系统自动调用该对象的 finalize 方法。子类可以重写该方法,做一些释放资源的操作
- 什么时候被回收:当某个对象没有任何引用时,则 jvm 就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来 销毁该对象,在销毁该对象前,会先调用 finalize 方法。
- 垃圾回收机制的调用,是由系统来决定(即有自己的 GC 算法), 也可以通过System.gc() 主动触发垃圾回收机制
7.1.1. 为什么要断点调试
7.1.2. 断点调试的介绍:
7.1.3. 断点调试快捷键
跳入(跳入方法内)
F8
逐行执行代码
F9
resume,执行到下一个断点
shift+F8:
跳出方法
7.2.1. 概念:
接口它是一个特殊的抽象类,特殊:接口中所有的方法都是抽象方法,而且接口中所有的属性都是静态常量。而且接口弥补了抽象类的单继承的缺点。--干爹。
7.2.2. 接口的定义语法:
接口和抽象类一样也是无法创建类对象。 需要让其他类来实现该接口。类在实现接口时需要把接口中所有的抽象方法重写。
7.2.3. 接口和接口之间
- 一个接口可以继承多个接口。
- 一个类实现了接口后是否还能继承别的类
7.2.4. 接口和抽象类之间的区别
- 相同: 接口和抽象类都无法创建对象,他们都是用于作为父亲。用于多态的实现。
- 不同:
-
- 接口没有构造方法,抽象有构造方法。
- 抽象类中可以没有抽象方法,而接口中都是抽象方法。[1.8以前]
- 抽象类中可以有普通属性,而接口中所有的属性都是静态常量。
- 一个类可以实现多个接口,但是只能继承一个抽象类。
概念:万事万物皆为对象,基本类型。为了满足这种需求,为基本数据类型提供了包装类。类中会包含想要的功能方法。有这些方法我就可以对基本类型进行操作了。"123"-->整型123.
**int-->Integer**(特殊)
byte-->Byte
short-->Short
long-->Long
double--->Double
float--->Float
boolean-->Boolean
**char--->Character**(特殊)
7.3.1. 自动装箱
装箱: 把基本数据类型转化为包装类的过程--装箱
7.3.2. 自动拆箱
拆箱:把包装类转换为基本数据类型
String StringBuffer StringBuilder 三个都可以操作字符串。
- String底层,每次变化都会生成一个新的字符串对象。安全的。
- StringBuffer和StringBuilder它字符串可以变,每次变化不会生成新的空间。
- StringBuffer它是线程安全的,因为它加了同步锁。
- 而StringBuilder它是线程不安全。效率高。
一般我们使用StringBuffer就可以
sort
排序
copyOf(数组,newLength)
复制并扩容
binarySearch()
二分查找(必须是排好序的数组)
fill
填充
equals方法
- 调用的toString方法。默认来自Object类。如果打印对象想显示自己的属性信息可以重写toString
toString方法
- Object类中equals方法本地比较的还是两个对象的引用地址。
hashcode方法。
- 两个对象的hashcode相同,他们一定是同一个对象
两个对象的hashcode相同,equals一定相同吗
==:它可以比较基本类型和引用类型。比较基本类型比较的是值,而比较引用 类型比较的引用地址。
equals: 它只能比较引用类型。如果没有重写Object类中的equals方法它比较的 还是引用地址。如果想比较值则需要重写equals
7.8.1. static
7.8.2. final
可以修饰 : 类,方法,变量
在某些情况下:
- 当不希望类被继承时候使用 final 修饰(给父类加 final ,在 class 前加)
- 当不希望某个方法被重写使用 final 修饰(给 方法名前加 加 final ,)
- 当不希望某个局部变量被修改的时候,用 final 修饰
- 用abstract 关键字来修饰一个类时,这个类就叫抽象类访问修饰符 abstract 类名{
- 用abstract 关键字来修饰一个方法时,这个方法就是抽象方法访问修饰符 abstract 返回类型 方法名(参数列表);//没有方法体
- 抽象类的价值更多作用是在于设计,是设计者设计好后,让子类继承并实现抽象类
- 抽象类,是考官比较爱问的知识点,在框架和设计模式使用较多
- 抽象类不能被实例化[举例]
- 抽象类不一定要包含abstract方法。也就是说,抽象类可以没有abstract方法[举例]
- 一旦类包含了abstract方法,则这个类必须声明为abstract[说明]
- abstract 只能修饰类和方法,不能修饰属性和其它的。[说明]
- 什么是异常?
异常就是程序在运行时出现的意外情况而导致程序无法正常往下执行[终止了]
- 为什么需要异常处理?
异常的目的就是想让程序继续执行。
- 异常处理的方式?
java 提供了两种处理异常的方式:
①第一种: try{可能发生异常的代码}catch(异常类型 对象){捕获异常}finally{异常的出口 }
②抛出异常throws
3.1、try -- catch 方式:
3.1.1、处理多种异常
try后面可以根多个catch捕获。不同的catch捕获不同的异常。但是这样会先的比较麻烦。
这些异常都有一个公共的父类根类是Throwable. Throwable下有两个子类
①Exception: 异常类,我们程序员可以处理的异常。一般使用该异常就了。
②Error: 错误类。这种异常程序员无法处理。比如内存溢出。
根据多态,再异常捕获时可以使用Exception异常来捕获
注意:如果使用到多个 catch 时候范围大的放后面,范围小的放前面
3.2、抛出 throws 异常
把异常抛出,使用方法名()后面.抛给了方法的调用者。
如果我们抛出的异常为RuntimeException下的异常。不要强制调用者处理
- throw关键字.
我们前面讲解的异常,都是程序自己产生的异常对象。 我们也可以自己定义异常对象。并把该异常对象抛出
- finally 关键字
使用异常处理中,作为最终执行的代码。不管有没有异常都会执行finally中代码。
后期==使用再资源关闭中==。不论是否执行了return,finally也会被执行
注意:try{}可以finally单独使用。try{}finally{}//没有捕获异常
- 自定义异常-----了解
当系统提供的异常类型无法满足客户需求时,程序员可以自己定义异常类型。目的可以达到见名知意
- IO流中的File文件对象
在java jdk关于对文件【目录和文件】的操作都封装到File类。该类中包含了文件的各种属性以及操作方法。该类放在jdk--java.io包下
根据流的方向分为: 输入流 输出流
根据流的内容分为: 字节流 字符流
以字节的方式读取文件中的内容。读取到程序中【内存中】。
字节输入流的父类InputStream,它里面包含操作字节的方法,
它也是一个抽象类,最常见的子类:FileInputStream
步骤 ① 创建对象:
② 读取:
字符流它只能复制文本内容---无法复制文本之外的内容:比如视频,音频,图片 word
操作java类对象。把java类对象写入到文件中,或者从文件中读取写入的java对象。
序列化: 把内存中的java对象写入到文件中的过程--序列化。
反序列化: 把文件中的对象读取到内存中---反序列化。
ObjectInputStream 和 ObjectOutputStream
9.6.1. 对象的写入
先创建一个学生类
值得注意的是:序列化和反序列化,都有将这个对象实现 Serializable 接口
序列化过程: 借助ObjectOutputStream流 调用writeObject() 注意: 该类必须实现序列化接口Serializable
9.6.2. 总结图:
集合的体系结构:
概念:它是单值集合的根==接口==,如果想使用Collection集合中的功能,需要创建该接口的子类。以ArrayList为例. 集合既然是容器,无外乎包含的功能就是增加,删除,修改元素,查询元素。
10.1.1. 增加: add()
10.1.2. 移除 remove() removeAll()
10.1.3. 查找
查找需遍历:遍历的两种方式:
10.1.4. 清空集合: clear()
Collection它是所有单值集合的根接口,它下面有两个子接口。List和Set.
List: 有序允许元素重复。
Set: 无序不可重复
10.2.1. List ( 增加 删除 修改 查找 遍历集合)
特点: 无序,不可重复。
属于List的子类,具备list的特点之外,还具备自己的
特点: 它的底层使用数组,查询效率快,
缺点: 中间:插入和删除慢--因为设计到元素的位移.
它也属于 List 的子类,他的底层使用链表;特点:增删速度快,查询速度慢!!
观察: 创建集合时<E> 他就是泛型标志, 限制集合中元素的类型。
如果没有指定泛型,那么集合中可以存放任意类型的对象Object
当然如果指定了泛型,集合就只能存放泛型指定好的类型。
HashSet它和Set接口中的方法一样。 底层元素不允许重复,而且无序。底层按照Hashcode以及Equals方法判断元素是否重复的。
流程: 先执行hashcode方法,如果hashcode值不同,则认为 不同元素,而且不会执行equals方法了,
如果hashcode相同,则执行equals方法,如果equals也相同则认为相同元素。
//元素不允许重复:
按照hashcode以及equals来判断。 先判断hashcode是否相同,如果hashcode不同,则认为不同的元素 不会执行equals方法。如果hashcode相同,判断equals是否相同(也可以在对象的抽象类中改写 hashcode 方法和 equals 方法 定义新的规则判断)
它是Set的子类,它的底层使用的是红黑二叉树。它里面的元素 会自动排序。
假如里面要存对象:(有一个 Student 类 里面有 get set 方法 全参无参构造方法,toString 方法)
此时控制台肯定报错因为无法排序,
我们往TreeSet中添加Student对象,出现了错误。由于字符串实现了Comparable接口,该接口是一个排序规则接口。 我们需要为Student类实现Comparable接口
解决方式有两种:
① 泛型里面写的类 也就是 Student 类去实现这个接口并改写排序规则:
② 使用定制排序
上面我们在创建Student类对象时,实现类排序规则的接口,如果你往TreeSet中添加的对象,是别人写好的类,没有实现排序规则的接口。如果别人写的类排序规则满足不了你的要求。比如按照字符串的长度排序。
Map 是一个键值对集合,map 集合中的元素有 key 和 value 组成 。底层实现类 Hash Map
工具类中所有的方法都是静态方法: 直接通过类名调用
- 动态添加元素: Collections.add ( list, 1,8,1,6,9,5,7 )
- 填充(将集合的所有元素都填充为一个数):Collections.fill(list,9)
- 洗牌(打乱):Collections.shuffle(list);
- 对集合排序(默认从小到大)Collections.sort(list);