Java中的List你真的会用吗?

开发 开发工具
List是Java中比较常用的集合类,关于List接口有很多实现类,本文就来简单介绍下其中几个重点的实现ArrayList、LinkedList和Vector之间的关系和区别。

List是Java中比较常用的集合类,关于List接口有很多实现类,本文就来简单介绍下其中几个重点的实现ArrayList、LinkedList和Vector之间的关系和区别。

[[245148]]

List

 

List 是一个接口,它继承于Collection的接口。它代表着有序的队列。当我们讨论List的时候,一般都和Set作比较。

List中元素可以重复,并且是有序的(这里的有序指的是按照放入的顺序进行存储。如按照顺序把1,2,3存入List,那么,从List中遍历出来的顺序也是1,2,3)。

Set中的元素不可以重复,并且是无序的(从set中遍历出来的数据和放入顺序没有关系)。

下面是Java中的集合类的关系图。从中可以大致了解集合类之间的关系

 

ArrayList、 LinkedList 和 Vector之间的区别

 

从上图可以看出,ArrayList、 LinkedList 和 Vector都实现了List接口,是List的三种实现,所以在用法上非常相似。他们之间的主要区别体现在不同操作的性能上。后面会详细分析。

ArrayList

ArrayList底层是用数组实现的,可以认为ArrayList是一个可改变大小的数组。随着越来越多的元素被添加到ArrayList中,其规模是动态增加的。

LinkedList

LinkedList底层是通过双向链表实现的。所以,LinkedList和ArrayList之前的区别主要就是数组和链表的区别。

数组中查询和赋值比较快,因为可以直接通过数组下标访问指定位置。

链表中删除和增加比较快,因为可以直接通过修改链表的指针(Java中并无指针,这里可以简单理解为指针。其实是通过Node节点中的变量指定)进行元素的增删。

所以,LinkedList和ArrayList相比,增删的速度较快。但是查询和修改值的速度较慢。同时,LinkedList还实现了Queue接口,所以他还提供了offer(), peek(), poll()等方法。

Vector

Vector和ArrayList一样,都是通过数组实现的,但是Vector是线程安全的。和ArrayList相比,其中的很多方法都通过同步(synchronized)处理来保证线程安全。

如果你的程序不涉及到线程安全问题,那么使用ArrayList是更好的选择(因为Vector使用synchronized,必然会影响效率)。

二者之间还有一个区别,就是扩容策略不一样。在List被***次创建的时候,会有一个初始大小,随着不断向List中增加元素,当List认为容量不够的时候就会进行扩容。Vector缺省情况下自动增长原来一倍的数组长度,ArrayList增长原来的50%。

 

ArrayList 和 LinkedList的性能对比

 

使用以下代码对ArrayList和LinkedList中的几种主要操作所用时间进行对比:

  1. ArrayList<Integer> arrayList = new ArrayList<Integer>(); 
  2. LinkedList<Integer> linkedList = new LinkedList<Integer>(); 
  3.  
  4. // ArrayList add 
  5. long startTime = System.nanoTime(); 
  6.  
  7. for (int i = 0; i < 100000; i++) { 
  8.     arrayList.add(i); 
  9. long endTime = System.nanoTime(); 
  10. long duration = endTime - startTime; 
  11. System.out.println("ArrayList add:  " + duration); 
  12.  
  13. // LinkedList add 
  14. startTime = System.nanoTime(); 
  15.  
  16. for (int i = 0; i < 100000; i++) { 
  17.     linkedList.add(i); 
  18. endTime = System.nanoTime(); 
  19. duration = endTime - startTime; 
  20. System.out.println("LinkedList add: " + duration); 
  21.  
  22. // ArrayList get 
  23. startTime = System.nanoTime(); 
  24.  
  25. for (int i = 0; i < 10000; i++) { 
  26.     arrayList.get(i); 
  27. endTime = System.nanoTime(); 
  28. duration = endTime - startTime; 
  29. System.out.println("ArrayList get:  " + duration); 
  30.  
  31. // LinkedList get 
  32. startTime = System.nanoTime(); 
  33.  
  34. for (int i = 0; i < 10000; i++) { 
  35.     linkedList.get(i); 
  36. endTime = System.nanoTime(); 
  37. duration = endTime - startTime; 
  38. System.out.println("LinkedList get: " + duration); 
  39.  
  40.  
  41.  
  42. // ArrayList remove 
  43. startTime = System.nanoTime(); 
  44.  
  45. for (int i = 9999; i >=0; i--) { 
  46.     arrayList.remove(i); 
  47. endTime = System.nanoTime(); 
  48. duration = endTime - startTime; 
  49. System.out.println("ArrayList remove:  " + duration); 
  50.  
  51.  
  52.  
  53. // LinkedList remove 
  54. startTime = System.nanoTime(); 
  55.  
  56. for (int i = 9999; i >=0; i--) { 
  57.     linkedList.remove(i); 
  58. endTime = System.nanoTime(); 
  59. duration = endTime - startTime; 
  60. System.out.println("LinkedList remove: " + duration); 

结果:

  1. ArrayList add:  13265642 
  2. LinkedList add: 9550057 
  3. ArrayList get:  1543352 
  4. LinkedList get: 85085551 
  5. ArrayList remove:  199961301 
  6. LinkedList remove: 85768810 

 

 

他们的表现的差异是显而易见的。在添加和删除操作上LinkedList更快,但在查询速度较慢。

 

如何选择

 

如果涉及到多线程,那么就选择Vector(当然,你也可以使用ArrayList并自己实现同步)。

 

如果不涉及到多线程就从LinkedList、ArrayList中选。 LinkedList更适合从中间插入或者删除(链表的特性)。 ArrayList更适合检索和在末尾插入或删除(数组的特性)。

【本文是51CTO专栏作者Hollis的原创文章,作者微信公众号Hollis(ID:hollischuang)】

戳这里,看该作者更多好文

责任编辑:武晓燕 来源: 51CTO专栏
相关推荐

2020-06-04 14:15:55

Java中BigDecimal函数

2023-12-01 11:13:50

JavaTreeSet

2016-05-04 10:36:42

iossdwebimage开发

2022-09-22 14:55:31

前端JavaScripthis

2022-09-26 13:10:17

JavaScriptthis

2018-12-21 11:24:55

Java时间处理编程语言

2021-11-26 08:07:16

MySQL SQL 语句数据库

2020-12-18 08:59:51

苹果iCloud储存照片

2019-07-25 12:46:32

Java高并发编程语言

2023-11-01 13:48:00

反射java

2021-09-08 07:49:35

Dubbo连接控制

2023-04-28 07:49:13

Javawaitsleep

2018-04-27 15:30:53

Java三目运算符

2021-05-21 12:36:16

限流代码Java

2024-03-06 08:15:03

@Autowired注入方式Spring

2022-01-17 07:32:34

Java参数方法

2022-07-26 00:00:22

HTAP系统数据库

2014-04-17 16:42:03

DevOps

2020-04-17 14:25:22

Kubernetes应用程序软件开发

2021-09-06 10:42:18

Linux命令服务器
点赞
收藏

51CTO技术栈公众号