ArrayList 底层是数组(最多占用1字节,8byte)
数组查询方便 时间复杂度 o(1),链表查询只能一个一个向右
链表插入方便,每次要new一个对象,数组插入要先从右往左位移
- 插入数据
十万以下,由于数组插入的麻烦,链表快于数组
十万以上,数组扩容越来越大的原因,速度快于链表(数组*1.5,链表++)
中间插入:linkList巨慢(每次都要要从头或尾遍历到中间)
插入一个字符
数组比链表慢得多
ArrayList
常用方法
下面是总结了一些比较常用的ArrayList类成员方法:
-
增加元素到链表中
-
boolean add(Element e)
增加指定元素到链表尾部. -
void add(int index, Element e)
增加指定元素到链表指定位置.
-
-
从链表中删除元素
-
void clear()
从链表中删除所有元素. -
E remove(int index)
删除链表中指定位置的元素. -
protected void removeRange(int start, int end)
删除链表中从某一个位置开始到某一个位置结束的元素。
-
-
获取链表中的元素
-
E get(int index)
获取链表中指定位置处的元素. -
Object[] toArray()
获取一个数组,数组中所有元素是链表中的元素.(即将链表转换为一个数组)
-
-
修改某个元素
E set(int index, E element)
将链表中指定位置上的元素替换成新元素。
-
搜索元素
-
boolean contains(Object o)
如果链表包含指定元素,返回true. -
int indexOf(Object o)
返回元素在链表中第一次出现的位置,如果返回-1,表示链表中没有这个元素。 -
int lastIndexOf(Object o)
返回元素在链表中最后一次出现的位置,如果返回-1,表示链表中没有这个元素。
-
-
检查链表是否为空
boolean isEmpty()
返回true表示链表中没有任何元素.
-
获取链表大小
int size()
返回链表长度(链表包含元素的个数).
-
并集
-
list.addAll(list2)
运行结果:A, B, B, C
-
-
无重复并集
list2.removeAll(list1)
list1.addAll(list2)
运行结果:A, B, C
-
交集
-
list1.retainAll(list2)
运行结果: B
-
-
差集
list1.removeAll(list2)
运行结果:*A
HashMap
使用
key-value
的结构通过hash函数生成
key
的引用查询时间复杂度
O(1)
hash冲突
hash计算可能出现相同值,hash地址被占用的了
解决方法
开放地址法,下一个冲突放到相邻
链地址法:冲突的地方多加一个链表,不会侵占其他位置,链表太长会影响性能
Hash函数的设计
-
能转换成int (所有类继承Object,运用它的hashCode方法直接解决)
-
要小于数组长度
扩容
填充因子
,扩容的比例值 达到3/4
- 由于要重新计算hash值,每一个都要,很损耗性能,但冲突的链表会散列开,提升性能
树
红黑树
优化了二叉树,单条线路多余三个值的时候,会将中间的值作为根节点提到上面去