- 如果一个对象中引用了另一个对象,如Student里面引用了Skill。那么浅拷贝拷贝的时候实际上拷贝的时原来的Skill,并没有新建。修改时会将原来的和拷贝后的都修改。
- 深拷贝需要同时让Skill类实现clone接口,并重写方法。并且Student类里面的clone方法要重写,调用skill的clone方法赋值给student的skill。
- System.copyarray(int[] source,int start,int[] target , int start,int num)
第一个参数表示源数组,第二个为原数组的起始位置,第三个为目标数组,第四个为目标数组的起始位置,第五个为个数。 - list.toArray返回的是object数组,不能强转。list.toArray(T) 返回的是参数中的类型
- 实现了RandomAccess接口随机访问速度快,如ArrayList。而LinkList没有实现,随机访问很慢。但是顺序访问都差不多
- add方法只有当list的空间不够了才会扩容1.5倍,够的话不会扩容。
- 并发异常:当实际修改次数和预期修改次数不一样会产生并发异常。而预期修改次数cursor只会赋值一次。每次对list进行操作都会修改实际修改次数。所以当迭代的时候如果对list进行了修改那么下次迭代就会产生并发异常。
- 并发异常的特殊情况:当对list操作时remove并且remove的是倒数第二个数据时就不会产生并发异常,因为他hasnext时,list的size和光标的位置相等,因此删除不会进入下一次迭代。
- 我们应该使用迭代器的remove方法
- 迭代器的romove方法修改了预期修改次数curso
面试题
- arraylist是如何扩容的?
每次数据不够时扩容1.5倍。小于10是扩容到10 - 大量的添加元素导致的扩容频繁,性能低如何解决?
利用有参的构造方法,参数是容量。这样就不用频繁的扩容。 - ArrayList插入或者删除元素一定比LinkedList慢吗?
由于ArrayList底层是数组,需要创建一个新的数组,然后移动位置、拷贝等,导致速度慢。LinkedList底层是链表。删除和get的时候先判断删除的索引大于中间节点还是小于,然后从后往前找或者从前往后找。两个不一定哪个慢。 - ArrayList是不是线程安全的?
不是
线程安全的Vector 可代替它。但是效率低。
或者使用Collections工具类把list变成一个线程安全的集合:Collections.synchronizedList(list); - 如何复制某个ArrayList到另一个ArrayList
- 使用clone方法
- 使用ArrayList构造方法
- 使用addAll方法
- 已知成员变量集合存储N多用户名称,在多线程的环境下,使用迭代器在读取集合数据的同时如何保证还可以正常的写入数据?
并发修改异常
CopyOnWriteArrayList
读写分离的集合
- ArrayList和LinkedList区别
- ArrayList
- 基于动态数组的数据结构
- 对于随机访问的get和set,ArrayList要优于LinkedList(实现了RandomAccess接口)
- 对于随机操作的add和remove,ArrayList不一定比LinkedList慢(ArrayList不是每次都需要创建新数组)
- LinkedList
- 基于链表的数据结构
- 对于顺序操作,LinkedList不一定比ArrayList慢
- 对于随机访问LinkedList效率低
题目说到,插入删除和随机访问次数差不多
我觉得还是要分两种情况的
第一种情况, 插入和删除是在数据后面+随机访问数据
这种情况下,肯定是使用ArrayList会提供比较好的性能。
访问速度本身快、加上插入删除数据又是性能不比LinkedList慢。
第二种情况, 插入和删除是在数据的前面和中间+随机访问数据
这种情况下,建议使用LinkedList对象。
抛开随机访问数据的速度不说,由于ArrayList的数据结构,导致ArrayList在新增数据位置前面和中间的时候需要移动数组中插入位置之后的的所有元素,这样的开销相比访问数据的开销无疑是巨大的。而又因为LinkedList是基于双链表实现的,插入、删除操作是最快的。