一、是什么
集合就是存放多个数据的对象。容器类。
集合最基础的祖师爷接口Collection和Map。Collection是存放多个符合某些规则(List接口有序可重复、Set接口无序不可重复、Queue接口先进先出)的数据,每个位置只有一个元素;Map存放多个键值对数据,每个位置是一个键值对,键唯一,值可不唯一。
Iteartor接口被所有集合类实现,用于遍历集合。
二、有什么用
存放多个具有共同属性的对象,并提供对大量对象快速的增删改查。
三、怎么用
3.1、List集合的遍历
Iterator:迭代输出,是使用最多的输出方式。
ListIterator:是Iterator的子接口,专门用于输出List中的内容。
foreach输出:JDK1.5之后提供的新功能,可以输出数组或集合。
for循环
3.2、List接口的实现类
ArrayList:基于数组实现,查询快,增删需要挪动后面的所有元素,慢。50%扩容。
LinkedList:基于链表实现,增删快,查询需要移动指针,慢。
Vector:ArrayList的线程安全版。内部所有方法都实现了同步,效率低。100%扩容。
Stack:继承自Vector,只不过将最后一个元素作为栈顶元素,add()、push()、peek()和pop()都是对栈顶(最后一个元素)进行操作。后进先出。
HashSet:基于数组和链表存储Set集合。内部结构和HashMap类似,元素作为entry的key,value为一个静态Object对象。链表存放的元素不可重复。非线程安全。集合元素值可唯一null。
LikedHashSet:基于数组和双向链表存储Set集合。记录了元素插入的顺序。访问全部元素时效率高。非线程安全。
TreeSet:实现了SortedSet接口。内部元素时经过了默认升序排序的。
EnumSet:转为枚举涉及的集合类,元素时某个特定枚举的枚举值,有序,不可null。
EnumSet内部以向量的形势存储,结构紧凑高效,效率最高。HashSet次之,查询添加效率高。LinkedHashSet因为要维护双向链表,效率略差,但是记录了插入顺序。TreeSet效率最低。
3.3、Map的遍历
keySet:将所有的key放到set集合中,然后用Iteraator迭代遍历。因为是set,所以取出来的key集合乱序。迭代一次需要遍历两遍,效率比第二种方式低。一次是取出所有的key,一次是取出key对应的value。
entrySet:将所有的映射关系(entry)放到set集合中,用Iterator迭代遍历。
3.4、Map接口的实现类
HashMap:基于链表(红黑树,链表长度大于8会将链表转化成红黑树)和数组实现,将key的hashcode带入散列函数,得出此entry对象(一组键值对)对应的数组下标,然后将此entry对象插入数组下标对应链表的头。非线程安全。key不可null,value可null。
Hashtable:内部结构和HashMap类似。继承自Dictionary类,内部所有方法都是经过同步的,效率低,线程安全。key、value均不可null。
LikedHashMap:基于双向链表和数组实现,内部结构和HashMap类似。记录了插入顺序,遍历时可以做到先进先被遍历。
ConcurrentHashMap:内部结构和HashMap类似。基于分离的锁实现了线程安全,对数组(桶)进行了分段,每次对段内的元素进行操作时就对段加锁,而不是整个对象进行加锁,可以让多个线程对不同段的元素同时进行操作,效率比Hashtable高。
TreeMap:实现SortMap接口,实现了内部元素按key的升序(可自定义排序规则)排列。key不可null。非线程安全。
IdentifyHashMap:和HashMap类似,只有两个元素的key完全相等时,才判断key相等。
WeakHashMap:和HashMap类似,只不过HashMap的entry.key保留对他引用对象的强引用,即HashMap不被销毁,key所引用的对象永远不会被回收,value也不会被自动删除。WeakHashMap则正好相反。
四、深入研究方向
4.1、List,Set,Queue,Map底层实现、扩容实现
4.2、IdentifyHashMap的实际应用场景是什么
4.3、快速失败特性
五、面试点
5.1、HashMap,HashTable,ConcurrentTable的底层结构和扩容机制。
5.2、尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象(接口)编程。
5.3、set中比较两个元素是否重复的机制:先比较hashcode,等,再==