image.png

    List可替代数组,是动态的
    image.png

    image.png
    image.png

    /
    1.List接口框架
    |——Collection接口:单列集合,用来存储一个一个的对象
    |——list接口:存储有序的、可重复的数据。 —->“动态”数组,替换原来的数组
    |——ArrayList
    |——LinkedList
    |——Vector

    2.ArrayList的源码分析:
    2.1 JDK 7的情况下:
    ArrayList list = new ArrayList();//底层创建了长度是10的Object[]数组elementData
    list.add(123);//elementData[0] = new Integer(123);

    list.add(11);//如果此次的添加导致底层elementData数组容量不够,则扩容。
    默认情况下,扩容为原来容量的1.5倍,同时需要将原有的数组中的数据复制到新的数组中。

    结论:建议开发中使用带参的构造器:ArrayList list = new ArrayList(int capacity)(capacity:容量,默认为50)

    2.2 JDK 8中ArrayList的变化:
    ArrayList list = new ArrayList(); //底层Object[] elementData初始化为{}。并没有创建长度为10的数组

    list.add(123);//第一次调用add()时,底层才创建了长度为10的数组,并将数据123添加到elementData[0]

    后续的添加和扩容操作与JDK 7无异。

    2.3 小结:
    JDK 7中的ArrayList的对象的创建类似于单例的饿汉式
    JDK 8中的ArrayList的对象的创建类似于单例的懒汉式,延迟了数组的创建,节省内存。


    3.LinkedList的源码分析:
    LinkedList list = new LinkedList();内部声明了Node类型的first和last属性,默认值为null
    list.add(123);//将123封装到Node中,创建了Node对象。

    其中,Node定义为:体现了LinkedList的双向链表的说法

    4.Vector的源码分析:JDK7和JDK8中通过Vector()构造器创建对象时,底层都创建了长度为10的数组
    在扩容方面,默认扩容为原来的数组长度的2倍。

    *

    5.list接口中的常用方法
    /

    1.void add(int index,Object ele):在index位置插入ele元素
    2.Boolean addAll(int index,Collection eles):从index位置开始讲eles中的所有元素添加进来
    3.Object get(int index):获取指定index位置的元素
    4.int indexOf(Object obj):返回obj在集合中首次出现的位置
    5.int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
    6.Object remove(int index):移除指定index位置的元素,并返回此元素
    7.Object set(int index,Object ele):设置指定index位置的元素为ele
    8.List subList(int fromIndex,int toIndex):返回从fromIndex到toIndex位置的子集合

    **
    面试题:ArrayList、LinkedList、Vector三者的异同?

    同:三个类都是实现了List接口,存储数据的特点相同:存储有序的、可重复的数据

    不同: ArrayList:作为List接口的主要实现类 ;线程不安全的,效率高;底层使用Object[] elementData存储
    —->JDK1.2定义的

    LinkedList: 对于频繁的插入、删除操作,使用此类比效率比ArrayList高;底层使用双向链表存储

    Vector:作为List接口的古老实现类;线程安全的,效率低;底层使用Object[]存储
    —-> JDK1.0定义的
    *

    总结:常用方法
    增:add(Object obj)
    删:remove(int index) / remove(Object obj)
    改:set(int index,Object ele)
    查:get(int index)
    插:add(int index,Object ele)
    长度:size()
    遍历:① Iterator迭代器
    ② 增强for循环
    ③ 普通的循环

    1. package com.atguigu.java1;
    2. import org.junit.Test;
    3. import java.util.ArrayList;
    4. import java.util.Iterator;
    5. import java.util.LinkedList;
    6. import java.util.List;
    7. /**
    8. * 1.List接口框架
    9. * |----Collection接口:单列集合,用来存储一个一个的对象
    10. * |----list接口:存储有序的、可重复的数据。 --->“动态”数组,替换原来的数组
    11. * |----ArrayList
    12. * |----LinkedList
    13. * |----Vector
    14. *
    15. * 2.ArrayList的源码分析:
    16. * 2.1 JDK 7的情况下:
    17. * ArrayList list = new ArrayList();//底层创建了长度是10的Object[]数组elementData
    18. * list.add(123);//elementData[0] = new Integer(123);
    19. * ...
    20. * list.add(11);//如果此次的添加导致底层elementData数组容量不够,则扩容。
    21. * 默认情况下,扩容为原来容量的1.5倍,同时需要将原有的数组中的数据复制到新的数组中。
    22. *
    23. * 结论:建议开发中使用带参的构造器:ArrayList list = new ArrayList(int capacity)(capacity:容量,默认为50)
    24. *
    25. * 2.2 JDK 8中ArrayList的变化:
    26. * ArrayList list = new ArrayList(); //底层Object[] elementData初始化为{}。并没有创建长度为10的数组
    27. *
    28. * list.add(123);//第一次调用add()时,底层才创建了长度为10的数组,并将数据123添加到elementData[0]
    29. * ...
    30. * 后续的添加和扩容操作与JDK 7无异。
    31. *
    32. * 2.3 小结:
    33. * JDK 7中的ArrayList的对象的创建类似于单例的饿汉式
    34. * JDK 8中的ArrayList的对象的创建类似于单例的懒汉式,延迟了数组的创建,节省内存。
    35. *
    36. *
    37. * 3.LinkedList的源码分析:
    38. * LinkedList list = new LinkedList();内部声明了Node类型的first和last属性,默认值为null
    39. * list.add(123);//将123封装到Node中,创建了Node对象。
    40. *
    41. * 其中,Node定义为:体现了LinkedList的双向链表的说法
    42. *
    43. * 4.Vector的源码分析:JDK7和JDK8中通过Vector()构造器创建对象时,底层都创建了长度为10的数组
    44. * 在扩容方面,默认扩容为原来的数组长度的2倍。
    45. *
    46. *
    47. *
    48. *
    49. * 面试题:ArrayList、LinkedList、Vector三者的异同?
    50. *
    51. * 同:三个类都是实现了List接口,存储数据的特点相同:存储有序的、可重复的数据
    52. *
    53. * 不同: ArrayList:作为List接口的主要实现类 ;线程不安全的,效率高;底层使用Object[] elementData存储
    54. * --->JDK1.2定义的
    55. *
    56. * LinkedList: 对于频繁的插入、删除操作,使用此类比效率比ArrayList高;底层使用双向链表存储
    57. *
    58. * Vector:作为List接口的古老实现类;线程安全的,效率低;底层使用Object[]存储
    59. * ---> JDK1.0定义的
    60. *
    61. *
    62. *
    63. * 5.list接口中的常用方法
    64. *
    65. * @author Dxkstart
    66. * @create 2021-05-19 20:32
    67. */
    68. public class ListTest {
    69. /*
    70. 1.void add(int index,Object ele):在index位置插入ele元素
    71. 2.Boolean addAll(int index,Collection eles):从index位置开始讲eles中的所有元素添加进来
    72. 3.Object get(int index):获取指定index位置的元素
    73. 4.int indexOf(Object obj):返回obj在集合中首次出现的位置
    74. 5.int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
    75. 6.Object remove(int index):移除指定index位置的元素,并返回此元素
    76. 7.Object set(int index,Object ele):设置指定index位置的元素为ele
    77. 8.List subList(int fromIndex,int toIndex):返回从fromIndex到toIndex位置的子集合
    78. 总结:常用方法
    79. 增:add(Object obj)
    80. 删:remove(int index) / remove(Object obj)
    81. 改:set(int index,Object ele)
    82. 查:get(int index)
    83. 插:add(int index,Object ele)
    84. 长度:size()
    85. 遍历:① Iterator迭代器
    86. ② 增强for循环
    87. ③ 普通的循环
    88. */
    89. @Test
    90. public void test1() {
    91. LinkedList linkedList = new LinkedList();
    92. linkedList.add(123);
    93. linkedList.add(1283);
    94. linkedList.add(12);
    95. linkedList.add(153);
    96. System.out.println(linkedList);
    97. linkedList.add(2,"MM");
    98. System.out.println(linkedList);
    99. ArrayList list = new ArrayList();
    100. //1.void add(int index,Object ele):在index位置插入ele元素
    101. list.add("AA");
    102. list.add("BB");
    103. list.add("CC");
    104. list.add("DD");
    105. list.add("EE");
    106. list.add(2, "MM");//在第二个元素后面插入
    107. System.out.println(list);
    108. System.out.println("****************");
    109. //2.Boolean addAll(int index,Collection eles):从index位置开始将eles中的所有元素添加进来
    110. ArrayList list1 = new ArrayList();
    111. list1.add("GG");
    112. list1.add("PP");
    113. list1.add("GG");
    114. list.addAll(3, list1);//默认是从末尾插入
    115. System.out.println(list);
    116. System.out.println("****************");
    117. //3.Object get(int index):获取指定index位置的元素
    118. System.out.println(list.get(3));
    119. //4.int indexOf(Object obj):返回obj在集合中首次出现的位置
    120. System.out.println(list.indexOf("GG"));
    121. //5.int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
    122. System.out.println(list.lastIndexOf("GG"));
    123. //6.Object remove(int index):移除指定index位置的元素,并返回此元素
    124. System.out.println(list.remove(2));
    125. System.out.println(list);
    126. //7.Object set(int index,Object ele):设置指定index位置的元素为ele,替换原来的元素
    127. list.set(6, "UU");
    128. System.out.println(list);
    129. //8.List subList(int fromIndex,int toIndex):返回从fromIndex到toIndex位置的子集合
    130. // System.out.println(list.subList(1, 3));//左闭右开
    131. List list2 = list.subList(0, 7);
    132. System.out.println(list2);
    133. }
    134. @Test
    135. public void test2(){
    136. ArrayList list = new ArrayList();
    137. list.add("AA");
    138. list.add("BB");
    139. list.add("CC");
    140. list.add("DD");
    141. list.add("EE");
    142. //方式一:Iterator迭代器
    143. Iterator iterator = list.iterator();
    144. while (iterator.hasNext()){
    145. System.out.println(iterator.next());
    146. }
    147. System.out.println("**********");
    148. //方式二:增强for循环
    149. for(Object obj : list){
    150. System.out.println(obj);
    151. }
    152. System.out.println("**********");
    153. //方式三:普通的循环
    154. for(int i = 0;i < list.size();i++){
    155. System.out.println(list.get(i));//巧用查找
    156. }
    157. }
    158. }