JAVA学习笔记 第八章
8.容器
8.1数据结构和算法
8.2集合
8.3Collection
访问集合中的元素
迭代器:
8.4List
List接口的常用遍历方式
8.5ArrayList
只有底层数组不够用才会进入扩容的方法,扩容的大小为原来的1.5倍,扩容时将旧数组拷贝到新数组中,然后原来地址指向新数组
小结:
8.6Vector
和ArrayList区别和联系
- 联系:底层都是数组的扩容,都具有数组的优点:查询效率高,缺点:增加删除元素效率低
- 区别:ArrayList扩容是原来数组的1.5倍、线程不安全、效率高,Vector底层扩容的长度为原数组的两倍、线程安全、效率低
8.7泛型
在JDK1.5之后开始使用泛型
8.7.1泛型的使用
如果不使用泛型,有缺点:一般存入集合的数组都是同一类型的,现在什么数据类型都能存入,不方便。
可以直接用Integer进行遍历
<>也称为钻石运算符
继承相关:
(1)父类指定泛型:
8.7.2泛型方法
8.7.3泛型参数存在继承关系
8.7.4通配符
8.7.5泛型继承受限
Object -> Person -> Student
8.8LinkedList
为什么有相同的方法:
在JDK版本更新后,为了增加程序的健壮性,将一些报错的问题解决了
遍历方式:
底层源码实现
8.9Iterable
8.9.1Iterable/Iterator()/Iterator
8.9.2ListIterator
并发修改异常,迭代器和list同时操作不可取
迭代和添加都是通过ListIterator操作的
且可以通过it.previous从后往前遍历
8.10Set
特点:唯一、无序(相对于List来说的,无序不等于随机)、没有跟索引相关的方法、遍历方法(迭代器、增强for循环)
8.10.1HashSet
【1】放入Integer数据
【2】放入String类型数据
【3】add方法返回值
返回的是true表示放入,返回false表示放入失败
【4】放入自定义数据类型的数据
不满足唯一无序的特点
重写HashCode和equals方法后
再运行之前的方法,发现结果没有重复的
8.10.2LinkedHashSet
8.10.3比较器
【1】int类型比较
int a = 1;
int b = 1;
System.out.println(a - b); //差值=0则相等 >0 <0
【2】String类型比较
String中实现Comparable接口,这个接口需要实现的compareTo抽象方法,String类型重写此方法
【3】比较double数据
double a = 9.2;
double b = 9.1;
System.out.println(((Double) a).comparaTo((Double) b));
【4】比较自定义数据
自定义类型中implements Comparable接口,实现comparaTo抽象方法
内部比较器:
外部比较器:
【5】内部比较器和外部比较器哪个好?
外部比较器,多态,扩展性好,
8.11TreeSet
【1】存入Integer数据
特点:数据是按照升序排序的,且唯一,(没有按照输入顺序排序)
【2】原理:底层结构是二叉树
【3】存入String类型数据
特点:也是唯一的,并且按照开头的字母的大小进行升序,内部也是实现了比较器
【4】自定义数据类型存入
使用外部比较器:
实际中利用外部比较器多,因为其扩展性好(多态)
【5】TreeSet底层的二叉树遍历是按照中序遍历进行的,结果是升序的
TreeSet底层调用的是TreeMap
8.12Map
【1】常用方法
发现lili只存了一个:
==比较地址是否相等,equals底层进行重写,具体的值比较属性值是否相等
keySet()获得Map中所有的key
【2】Map的特点:唯一、无序
【3】HashMap
【4】TreeMap
key的类型是String类型的:
key的类型是自定义数据类型:
需要自定义比较器
设定比较器之后,如果后面的信息不一样,年龄一样也会当成是一样的,只会添加其中一个
外部比较器:
8.13HashMap
原理:
构造器:
e!=null满足的话,发生哈希碰撞,先比较哈希值,后比较key是否是一个对象,key是一个对象的话,equals就不比较
如果不是同一个对象的话,会比较equals方法,
如果哈希值一样,equals方法比较的结果也一样,那么才会走这个if方法。
if方法内获取老的value,并返回,新的value替换旧的value,不替换key
如果放入的位置没有元素,直接走addEntry方法
计算哈希码
等价于h%length取余数,用&运算效率高
当数组的元素>threshold且在当前位置上的元素不为空,则进行扩容,扩容的大小为两倍
createEntry创建一个哈希对象,首先将下标元素的对象给e,封装对象将对象给table[bucketIndex],后将size元素数量+1
扩容:
创建一个新数组,通过transfer方法将老数组里的东西重新放到新数组里,再将新数组放到table
经典面试题:
8.14TreeMap
【2】源码
cmp返回的值是int类型的数据,根据这个值>0 <0继续往左找或者往右找,等于0则将新的value替换到旧的value,key不变
最后把节点放到对应的位置上,结点数量+1
结点类
8.15Collections工具类
构造器私有化,不支持创建对象
sort提供一个排序的方法,从小到大进行排序
binarySearch是二分查找,必须在有序的集合