1、List 和 Set 的区别
一:区别概述
1:List:可重复,有序,数组或者链表存储
2:Set:不可重复,无序,使用ma存储
二:ArrayList
2.1:通过数组的方式进行存储:查询快,增删慢的特点,但是他的效率高
2.2:初始化过程中若知道数组的大约范围,建议制定长度;若不指定长度,默认初始化大小为10;
2.3:关注ArrayList两个属性
size 和 elementData,其中size可以理解为数组长度,elementData理解为容量大小;
比如,List a =new ArrayList(20); a.add("1"); 其中size = 1;elementData的长度为20
2.4:扩容问题:
每次使用add方法时,会触发扩容方法,当容量不够时候,进行扩容:
扩容时步骤:
1:将size+1,和现在的elementData长度比较比较
2:若小于现有容量,则不扩容;
3:若大于现有容量,则
3 .1:备份原数组;
3.2:扩容为原来大小的1.5倍
3.2:通过Arrays.copyOf(elementData, newCapacity)方法返回扩容后的数据。
2.5:删除(remove)
a:传空参数的情况是全删呀!!!
b:主要使用了一个方法:fastRemove(int index),每次remove都是进行一次数组拷贝,remove 后size会变化
2.6 迭代
方式1:Iterator迭代器
方式2:foreach
错误方式:
错误方式分析:
a: ArrayList extents AbstractList,AbstractList类有一个变量modCount,记录数组的变化次数;
每次对数组进行增删操作时候,都会进行modCount++;
b:Iteratoriterator = a.iterator(); 是实例化一个AbstractList的内部类Itr;实例化时,初始化expectedModCount =modCount;
每次使用next方法时,会调用checkForComodification(),这个方法是比较expectedModCount和modCount;若不相等,就报错。
c:正确案例中,用了内部类Itr的remove方法,这个方法最后会强制expectedModCount=modCount;
d:错误案例中,使用了ArrayList类的remove,只会减小modCount,不会强制expectedModCount=modCount;所以删除一次后,expectedModCount<modCount,不会通过校验,失败。
三:LinkedList (直接抄的博客的)
a:是由node节点组成的双向链表,没有初始化容量,不存在扩容概念;
b:node节点的结构如下
c:每当有新数据添加的时候,会将元素添加到链表的最后位置,并将元素的prev 指向前一个元素,前一个元素的next指向需要添加的元素;