Purpose
Interview preparation is convenient for your follow-up interview review. It may not be very useful. Here is a simple personal study record.
resource
A learning video about high-frequency interview questions at Station B
Core knowledge points
4 dimensions of comparison:
- structure
- random access speed
- insertion and deletion
- CPU cache, locality principle
Conclusion:
- ArrayList
① Based on arrays, it is a linked memory space
② Fast random access (according to subscript access)
③ Tail insertion/deletion performance is good, other part insertion/deletion will involve moving elements, performance will be reduced
④ CPU cache can be used, locality principle - LinkedList
① Based on a doubly linked list, no continuous memory is required
② Random access is slow (need to traverse along the linked list)
③ Head and tail insertion and deletion performance is high (intermediate insertion may not be as good as ArrayList, the main time is wasted in finding elements)
④ Occupies a lot of memory
Self-verifying source code
test random access
private static void randomAccess(List<Integer> list1, LinkedList<Integer> list2, int mid) {
StopWatch sw = new StopWatch("测试随机访问");
sw.start("测试随机访问: ArrayList");
list1.get(mid);
sw.stop();
sw.start("测试随机访问: LinkedList");
list2.get(mid);
sw.stop();
System.out.println(sw.prettyPrint());
}
Conclusion: Random access to ArrayList is excellent, directly obtained through subscripts, while LinkedList needs to traverse elements
StopWatch '测试随机访问': running time = 13501 ns
---------------------------------------------
ns % Task name
---------------------------------------------
000004000 030% 测试随机访问: ArrayList
000009501 070% 测试随机访问: LinkedList
test head insertion
private static void addFirst(List<Integer> list1, LinkedList<Integer> list2) {
StopWatch sw = new StopWatch("测试头部插入");
sw.start("ArrayList: ");
list1.add(0, 100);
sw.stop();
sw.start("LinkedList: ");
list2.addFirst(100);
sw.stop();
System.out.println(sw.prettyPrint());
}
Conclusion: Inserting the head into LinkedList has good performance, and there is no need to move elements.
StopWatch '测试头部插入': running time = 15301 ns
---------------------------------------------
ns % Task name
---------------------------------------------
000011301 074% ArrayList:
000004000 026% LinkedList:
test middle insertion
private static void addMiddle(List<Integer> list1, LinkedList<Integer> list2, int mid) {
StopWatch sw = new StopWatch("测试中间插入");
sw.start("ArrayList: ");
list1.add(mid, 100);
sw.stop();
sw.start("LinkedList: ");
list2.add(mid, 100);
sw.stop();
System.out.println(sw.prettyPrint());
}
Conclusion: Generally, ArrayList is better, and LinkedList will take a lot of time to find elements.
StopWatch '测试中间插入': running time = 10500 ns
---------------------------------------------
ns % Task name
---------------------------------------------
000001299 012% ArrayList:
000009201 088% LinkedList:
test tail insertion
private static void addLast(List<Integer> list1, LinkedList<Integer> list2) {
StopWatch sw = new StopWatch("测试尾部插入");
sw.start("ArrayList: ");
list1.add(100);
sw.stop();
sw.start("LinkedList: ");
list2.add(100);
sw.stop();
System.out.println(sw.prettyPrint());
}
Conclusion: Pretty much.
StopWatch '测试尾部插入': running time = 3900 ns
---------------------------------------------
ns % Task name
---------------------------------------------
000002301 059% ArrayList:
000001599 041% LinkedList:
Locality Principle, Space Occupancy Test
Conclusion: LinkedList takes up more space.