一、Vector
常用API
向向量序列中添加元素
addElement(Object obj)
insertElementAt(Object obj, int index)
修改或删除向量序列中的元素
Void setElementAt(Object obj, int index)
boolean removeElement (Object obj)
Void removeElementAt (int index)
Void removeAllElements ()
查找向量序列中的元素Object elementAt(int index)
boolean contains (Object obj)
int indexOf (Object obj, int start_index)
int lastIndexOf (Object obj, int start_index)
底层是一个Object类型的数组,初始的默认长度为10,默认扩容的时候扩容为原来的2倍 ,如果自己指定扩容的长度,那么就是就容量加指定的,如果没有指定,就是旧容量的2倍。
线程安全,性能低
对照区别
ArrayList和LinkedList的区别:底层结构 优点 缺点
ArrayList和Vector的区别:底层结构 扩容方式 线程安全
二、Set
无序集合(输出的顺序与添加的顺序不一致),存入的元素在逻辑上没有位置编号,也不能依靠编号去操作元素
1、HashSet
常用API:
特点
输出是无序的:和存入顺序不一定一致
不能放入重复元素:两个对象用equals方法比较返回true,并且两个对象拥有相同的哈希码,也就是hashCode方法要有相同的返回值
可以放入null元素
HashSet的典型应用场景就是去除重复元素
底层存储结构:
HashSet的底层是一个HashMap,只是将HashMap中的值设置为一 个常量,用所有的键组成了一个HashSet
示例:
2、LinkedHashSet: HashSet的子类,底层有一个链表结构,按照添加顺序维护顺序 ,输出顺序和存入
顺序是一致的
3、TreeSet
常用api
特点
输出有序(排序输出)
不能放入null对象
不能放入重复对象(比较对象的大小,如CompareTo方法的返回值为0)
TreeSet的典型应用场景就是自带排序功能
自然排序
new TreeSet();
要求元素对应的类型实现Comparable接口,调用Treeset的无参数构造的时候采用自然排序的方式
比较器排序(Comparator):
new TreeSet(Comparator com);
单独实现一个比较器类,比较器类实现Comparator接口,重写compare(o1,o2)方法.然后创建Treeset的时候将比较器作为构造方法的参数传入,不要求元素类型实现Comparable接口
判断重复元素的依据
compareTo或者compare方法的返回值进行比较排序,方法如果返回0,认为两个对象是相等的,不会重复存储。
存储结构:TreeSet的底层是用TreeMap进行实现,TreeMap中所有的键构成了TreeSet.
三、Map
存放键值对
1.常用的API
Put(key,value)
get(key)
keySet():得到所有的键,返回Set
values():得到所有的值,返回Collection
entrySet():Set>,HashMap底层将每一个键值对封装为Entry类型的对象
containsKey(key):注意查找依据
containsValue(value)::注意查找依据
size():键值对的个数
remove(key):根据键移除键值对
api实例代码
HashMap特点
可以放入NULL值,NULL键
不能放入重复键(依靠equals和hashcode进行判断)
键是无序的(所有的键构成了一个hashSet)
底层结构:数组加链表|数组加红黑树,数组的默认容量为16,当数组的元素个数达到16*扩容因子(0.75)的进行扩容,扩容为原来的2倍之后,要重新进行hash运算,重新放置元素
HashMap put流程:
1. 根据键的hash码(调用键的hashcode方法)进行哈希运算(hash()),得到一个整数哈希值(不是数组的下标位置)`
2. 判断哈希表是否为空或者长度是否为0,如果是,要对数组进行初始化(初始化为16),如果否,进入3`
3. 根据1得到的哈希值计算数组索引(与运算(n - 1) & hash),得到一个和数组存储位置匹配的索引i(确定到桶的位置)`
4. 判断i号位置是否为null,如果null,就将键和值封装为一个Entry(Node)类型的对象进行插入,如果不为null,进入5`
5. 判断key是否存在(使用equals进行判断,在一个桶里面判断),如果存在,覆盖原有的值,如果不存在,进入6`
6. 判断i号位置是否为一个树结构,如果是一个树结构,在树中进行插入,如果不是树结构,进入7`
7. 为链表结构,对链表进行遍历,判断key是否存在,存在就覆盖,不存在就在链表中插入新的节点`
8. 链表中插入新节点后,如果i号位置的元素个数大于等于8且hash表的长度大于等于64,i号位置的所有元素转换为树结构,反之,新节点正常插入结束`
9. size++
10. 判断是否要进行扩容,如果需要扩容,就执行Resize()进行扩容
11. 结束
示例:
HashMap注意事项
为什么HashMap的长度为什么要设计成2的n次方?
提高效率:为了方便将去余运算转换为位运算 hash%长度== (n - 1) & hash尽量让计算到的位置均匀
为什么设计扩容因子
为了减少一个桶里元素碰撞的概率,本质就是不要让一个桶中的元素个数太多
根据key怎么找到值的(get(key))?
根据key的哈希码先找到桶的位置,然后再在一个桶中用equals方法进行比对键,找到对应的节点,获取其值。
为什么使用hash码相关的集合的时候,重写equals方法的时候建议也重写hashCode方法
如果equals返回true.但是哈希码不一样,有可能会放到不同的桶中,不同的桶中就存在了键重复的元素了,有漏洞,最终目的是为了让equals返回true的两个对象能放到一个桶中,保证键不重复
2、LinkedHashMap:输出顺序和存入顺序一致
3、TreeMap
按照键进行排序(无参数构造TreeMap(),自然排序,TreeMap(Comparator),按照自定义比较器
进行排序)
不能放入null键,可以放入null值
键不能重复(判断的依据是比较的大小如果相同,调用compareTo或者compare()方法返回值如果
为0,就认为是相同的对象)
底层为红黑树结构。
TreeMap的put流程如下:可以自己描述
示例:
4.Hashtable
四、迭代器
1、Iterable:接口,规定实现类或子接口必须要有提供迭代器的能力
iterator方法:返回迭代器对象
2、Iterator接口:迭代器的类型,迭代器使用Iterable接口中iterator方法返回的是Iterator类型 的对象
方法:hasNext next
实现该接口的实现类基本是各个集合中的内部类
迭代器的实现类是以不同集合中的内部类的形式存在的,因为集合的结构不同,对迭代器的具体实
现也不同。
支持删除行为:删除当前遍历到的元素(迭代器对象.remove()),迭代器在迭代的时候不支持集合本身
的修改行为(add|remove),否则,会引发 java.util.ConcurrentModificationException
为什么迭代器不支持集合本身结构修改行为:
modCount:集合的一个属性,每次修改add或者remove的时候,都会修改modCount的值,modCount
属性的属性值就代表了集合的修改次数
得到迭代器的时候会有一个modCount(代表集合结构修改的次数),在得到迭代器的时候会记录这个次
数, 如果在迭代过程中修改集合结构,modCount就变化了,和当时记录的modcount的数量就不一样
了,会引发ConcurrentModificationException。本质上是为了保证迭代器在迭代过程中集合的结构是
稳定的
1、java中迭代器的实现符合迭代器的设计模式
目前 java中的collection接口的集合都是符合迭代器设计模式的
抽象集合接口(Iterable(抽象接口))
集合的具体实现类实现Iterable(必须拥有给外界提供迭代器(Iterator)的能力)(ArrayList)
抽象迭代器接口(Iterator)
具体的迭代器实现类(实现Iterator,体现为不同集合中的内部类)
五、Collections
集合相关的而一个帮助类(List)
1、sort(List)方法的使用(含义:对集合进行排序)。Dog必须实现Comparable接口
2、sort(List,Comparator),自定义比较器排序
3、reverse(List)方法的使用(含义:反转集合中元素的顺序)。
4、binarySearch(List,Object)方法的使用(含义:查找指定集合中的元素,返回所查找元素的索引,要求
集合中的元素是Comparable类型,查找方式为按照排序之后的顺序再进行位置查找,找不到返回-1
5、copy(List m,List n)方法的使用(含义:将集合n中的元素全部复制到m中,并且覆盖相应索引的元素)。
6、fill(List list,Object o)方法的使用(含义:用对象o替换集合list中的所有元素)。