【Java集合】List

缺乏、安全感 2022-05-18 06:12 443阅读 0赞

从上篇博客,我们知道了Java集合框架分为Collection和Map,此篇博客开始,将对集合框架中的List,Set,Queue和Map分别总结,进一步学习Java集合。本篇博客从List出发。

一. List的定义

  1. List集合代表一个元素有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List集合允许加入重复元素,因为它可以通过索引来访问指定位置的集合元素。List集合默认按元素的添加顺序设置元素的索引。

二. List的实现

  1. 1. List listA=new ArrayList();
  2. 底层数据结构是数组,查询快,增删慢;线程不安全,效率高
  3. 2. List listB=new Vector();
  4. 底层数据结构是数组,查询快,增删慢;线程安全,效率低
  5. 3. List listC=new LinkedList();
  6. 底层数据结构是链表,查询慢,增删快;线程不安全,效率高

三. ArrayList和Vector

  1. ArrayListVector类都是基于数组实现的List类,其封装了一个动态的、允许再分配的Object\[\]数组。ArrayListVector对象使用initalCapacity参数来设置该数组的长度,当向ArrayListVector中添加元素超过了该数组的长度时,它们的initalCapacity会自动增加。
  2. (一)ArrayList包含三个构造函数方法,如下:
  3. 1. ArrayList() Constructs an empty list with an initial capacity of ten.
  4. 构造一个空数组,其初始容量默认为10.
  5. 2. ArrayList(Collection c) Constructs a list containing the elements of the specified collection, in the order they are returned by the collections iterator.
  6. 按照集合迭代器返回的顺序构造包含指定集合元素的列表。
  7. 3. ArrayList(int initialCapacity) Constructs an empty list with the specified initial capacity.
  8. 构造一个指定初始容量的空数组。
  9. 若调用add()方法,向一个数组中添加元素,会先调用ensureCapacityInternal()方法,该方法用来确保数组中是否还有足够容量。最后有个判断:如果剩余容量足够存放这个数据,则进行下一步,如果不够,则需要执行一个重要的方法:grow(int minCapacity) ,对数组进行扩容。
  10. 所以说,ArrayList是一个动态扩展的数组,Vector也同样如此。如果开始就知道ArrayListVector集合需要保存多少个元素,则可以在创建它们时就指定initalCapacity的大小,这样可以提高性能。
  11. 此外,ArrayList还提供了两个额外的方法来调整其容量大小:
  12. 1. void ensureCapacity(int minCapacity): 如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数。
  13. 2. void trimToSize():将此 ArrayList 实例的容量调整为列表的当前大小。
  14. (二)ArrayList支持3种遍历方式:
  15. 1. 通过迭代器遍历
  16. Integer value = null;
  17. Iterator iter = list.iterator();
  18. while (iter.hasNext()) {
  19. value = (Integer)iter.next();
  20. }
  21. 2. 随机访问,通过索引值去遍历:
  22. Integer value = null;
  23. int size = list.size();
  24. for (int i=0; i<size; i++) { value = (Integer)list.get(i); }
  25. 3. for循环遍历
  26. Integer value = null;
  27. for (Integer integ:list) {
  28. value = integ;
  29. }

遍历ArrayList时,使用随机访问(即,通过索引序号访问)效率最高,而使用迭代器的效率最低。

四. LinkedList

  1. LinkedList类是List接口的实现类——这意味着它是一个List集合,可以根据索引来随机访问集合中的元素。除此之外,LinkedList还实现了Deque接口,可以被当作成双端队列来使用,因此既可以被当成“栈”来使用,也可以当成队列来使用。
  2. LinkedList的实现机制与ArrayList完全不同。ArrayList内部是以数组的形式来保存集合中的元素的,因此随机访问集合元素时有较好的性能;而LinkedList内部以链表的形式来保存集合中的元素,因此随机访问集合元素时性能较差,但在插入、删除元素时性能比较出色。
  3. (一)LinkedList包含两个构造函数方法,如下:
  4. 1. LinkedList() Constructs an empty list.
  5. 构造一个空数组.
  6. 2. LinkedList(Collection c) Constructs a list containing the elements of the specified collection, in the order they are returned by the collections iterator.
  7. 按照集合迭代器返回的顺序构造包含指定集合元素的列表。
  8. LinkedList调用默认构造函数,创建一个链表。由于维护了一个表头,表尾的Node对象的变量。可以进行后续的添加元素到链表中的操作,以及其他删除,插入等操作。也因此实现了双向队列的功能,即可向表头加入元素,也可以向表尾加入元素.
  9. (二)LinkedList支持多种遍历方式:
  10. 1.通过迭代器遍历LinkedList
  11. 2通过快速随机访问遍历LinkedList
  12. 3.通过for循环遍历LinkedList
  13. 4.通过pollFirst()遍历LinkedList
  14. 5.通过pollLast()遍历LinkedList
  15. 6通过removeFirst()遍历LinkedList
  16. 7.通过removeLast()遍历LinkedList

其中采用逐个遍历的方式,效率比较高。采用随机访问的方式去遍历LinkedList的方式效率最低。

五. ArrayList和LinkedList性能对比

  1. ArrayList 是一个数组队列,相当于动态数组。它由数组实现,随机访问效率高,随机插入、随机删除效率低。ArrayList应使用随机访问(即,通过索引序号访问)遍历集合元素。
  2. LinkedList 是一个双向链表。它也可以被当作堆栈、队列或双端队列进行操作。LinkedList随机访问效率低,但随机插入、随机删除效率高。LinkedList应使用采用逐个遍历的方式遍历集合元素。
  3. 如果涉及到“动态数组”、“栈”、“队列”、“链表”等结构,应该考虑用List,具体的选择哪个List,根据下面的标准来取舍。
  4. 1. 对于需要快速插入,删除元素,应该使用LinkedList
  5. 2. 对于需要快速随机访问元素,应该使用ArrayList
  6. 3. 对于“单线程环境” 或者 “多线程环境,但List仅仅只会被单个线程操作”,此时应该使用非同步的类(如ArrayList)。对于“多线程环境,且List可能同时被多个线程操作”,此时,应该使用同步的类(如Vector)或支持并发的类。

六. ArrayList项目中的应用

  1. 之前在项目中遇到过一个需求,按规则分发人员,产品和测试理规则理了很久,而我开发时间其实很短,用编程语言来说,他们的规则,无非是我对几个list集合取并集,交集的操作,而这些操作,List都有实现的方法可直接用,allAll(),retainAll(),最后使用set去重。(set集合将在下篇博客进行详细总结)
  2. List<String> allEmployeesList = new ArrayList<>();
  3. //根据客户绑定的专线查询对应的员工,分发该询价单
  4. List<String> dispatchEmployees = companyLineService.dispatchEmployeeByCompanyLine(customerId, companyIdItem);
  5. logger.info("-------所有绑定该专线员工集合:" + dispatchEmployees);
  6. //查询对应服务品牌的员工
  7. List<String> dispatchBrandEmployees = companyLineService.dispatchEmployeeByBrand(brand, companyIdItem);
  8. logger.info("-------所有绑定该品牌员工集合:" + dispatchBrandEmployees);
  9. //查询所有在用的员工
  10. List<String> dispatchUsedEmployee = companyLineService.queryUsedEmployees(companyIdItem);
  11. logger.info("--------所有在用的员工集合:" + dispatchUsedEmployee);
  12. //专线员工集合
  13. allEmployeesList.addAll(dispatchEmployees);
  14. if (allEmployeesList.size() == 0) {
  15. //若未查询到绑定专线的员工,则将绑定品牌的集合合并
  16. allEmployeesList.addAll(dispatchBrandEmployees);
  17. }
  18. //若专线+品牌集合都不为空,则取两个集合的差集
  19. if (dispatchEmployees.size() > 0 && dispatchBrandEmployees.size() > 0) {
  20. allEmployeesList.addAll(dispatchEmployees);
  21. allEmployeesList.retainAll(dispatchBrandEmployees);
  22. }
  23. //如果专线+品牌的员工集合为空,则合并其他所有在用的员工集合
  24. if (allEmployeesList.size() == 0) {
  25. allEmployeesList.addAll(dispatchUsedEmployee);
  26. }
  27. //set去除list中的重复元素
  28. Set<String> set = new HashSet<>(allEmployeesList);
  29. logger.info("去重后的所有员工id集合:" + set);
  30. return set;

发表评论

表情:
评论列表 (有 0 条评论,443人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Java List集合

    目录 List集合 特点: 特有方法: 遍历: -------------------- List集合 特点: 有序:存和取得顺序一致 有索引:可以

    相关 Java List集合

    List是有序的collection,可以对列表中每个元素的插入位置进行精确的控制 List集合的特点: 有序,存进去是这样,取出来还是按照存进去的顺序取出

    相关 Java集合List

    从上篇博客,我们知道了Java集合框架分为Collection和Map,此篇博客开始,将对集合框架中的List,Set,Queue和Map分别总结,进一步学习Java集合。本篇

    相关 Java集合--List

    Java集合–List Java集合 作为一个Developer,Java集合类是我们在工作中运用最多的、最频繁的类。相比于数组(Array)来说,集合类的长度可变

    相关 JavaList集合

    List集合 作为Collection集合的一个子类,其特点 1)有序,可重复 2)有索引可以使用普通的for循环遍历。 List 接口在 iterator、add、r