List
List接口:存储的是有序的不唯一(可以重复)的数据
常用list有:ArrayList,LinkedList。
- ArrayList:底层是Object数组实现的:由于数组的地址是连续的,数组支持O(1)随机访问;数组在初始化时需要指定容量;数组不支持动态扩容,像ArrayList、Vector和Stack使用的时候看似不用考虑容量问题(因为可以一直往里面存放数据);但是它们的底层实际做了扩容;数组扩容代价比较大,需要开辟一个新数组将数据拷贝进去,数组扩容效率低;适合读数据较多的场合
- LinkedList:底层使用一个Node数据结构,有前后两个指针,双向链表实现的。相对数组,链表插入效率较高,只需要更改前后两个指针即可;另外链表不存在扩容问题,因为链表不要求存储空间连续,每次插入数据都只是改变last指针;另外,链表所需要的内存比数组要多,因为他要维护前后两个指针;它适合删除,插入较多的场景。
数组和链表的特性差异,本质是:连续空间存储和非连续空间存储的差异。
Set
HashSet存储的是无序的、唯一(不可重复)的数据。是一组key的集合,但不存储value。由哈希表支持(实际上是一个 HashMap集合)。HashSet集合不能保证的迭代顺序与元素存储顺序相同,保证元素唯一性的方式依赖于:hashCode()与equals()方法。
保证唯一性:
使用HashCode算法,获取对象在内存中存放的位置。如果没有,就会将对象存储这个位置。如果有(对象的hashCode一样),调用equals()方法,如果equals比较属性一样,不会添加后元素,否则会添加后元素。
自定义的对象:
如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。
Map
Map是一种以键值对存储数据的容器,以哈希表(hashtable)作为底层数据结构实现的,我们叫做HashMap。HashMap是借助了键值Key的hashcode值来组织存储,将键值对封装成一个Entry对象。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。