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是二分查找,必须在有序的集合

