Java集合概述(二):List集合

本文深入解析Java中的List集合,涵盖其基本概念、常用方法及不同实现类的特点与应用场景,如ArrayList、LinkedList等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

List集合概述

上篇总结了Set集合,这回总结下List集合。。。。先来框架图:

一、List集合

List集合代表一个元素有序,可重复的集合,集合中每个元素都有对应的顺序索引。List接口中增加了一些根据索引操作元素的方法:

   void add(int index,E element )  在列表的指定位置插入该元素。

   boolean addAll(int index,Collection c)  将集合c包含的所有元素都插入到List集合的index处。

   Object get(int index)    返回集合index索引出的元素。

  。。。。。详见

1.ListIterator接口:List额外提供的一个listIterator()方法,提供了专门操作List的方法。

 ListIterator接口在Iterator的基础上增加了如下方法:

 boolean hasPrevious(): 返回该迭代器关联的集合是否还有上一个元素。

 Object previous(): 返回该迭代器的上一个元素。

 void add((E e): 在指定位置插入一个元素。

 示例:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import  java.util.*;
 
public  class  TestListIterator
{
     public  static  void  main(String[] args)
     {
         String[] books = {
             "我是帅哥" ,
             "帅哥是我"
         };
         List bookList =  new  ArrayList();
         for  ( int  i =  0 ; i < books.length ; i++ )
         {
             bookList.add(books[i]);
         }
         ListIterator lit = bookList.listIterator();
         while  (lit.hasNext())
         {
             System.out.println(lit.next());
             lit.add( "-------分隔符-------" );   //加入一个元素
         }
         System.out.println( "==========下面开始反向迭代===========" );
         while (lit.hasPrevious())
         {
             System.out.println(lit.previous());
         }
     }
}

 输出结果:

      我是帅哥
      帅哥是我
      ==========下面开始反向迭代===========
      -------分隔符-------
      帅哥是我
     -------分隔符-------
     我是帅哥                                       

输出完成 (耗时 0 秒) - 正常终止

2.ArrayList实现类和Vector实现类:

ArrayList和Vector是基于数组实现的list类,所以ArrayList和Vector封装了一个动态的,允许再分配的Object[]数组,不指定的话长度默认为10。ArrayList和Vector对象使用initialCapacity参数来设置该数组的长度,当向集合添加大量元素时,可以使用ensureCapac(int minCapacity)方法一次性的增加initialCapacity。

ArrayList和Vector在用法上几乎完全相同,但Vector比较古老,方法名比较长,最好是不使用。ArrayList是线程不安全的,Vector是线程安全的,但这个完全可以手动将一个ArrayList变成线程安全的。

ArrayList示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import  java.util.*;
 
public  class  TestList
{
     public  static  void  main(String[] args)
     {
         List books =  new  ArrayList();
         //向books集合中添加三个元素
         books.add( new  String( "轻量级J2EE企业应用实战" ));
         books.add( new  String( "Struts2权威指南" ));
         books.add( new  String( "基于J2EE的Ajax宝典" ));
         System.out.println(books);
         //将新字符串对象插入在第二个位置
         books.add( 1  new  String( "ROR敏捷开发最佳实践" )); //add是插入,插入到当前位置,当前的元素向后退,并没有覆盖!
         for  ( int  i =  0  ; i < books.size() ; i++ )
         {
             System.out.println(books.get(i));
         }
         System.out.println( "size:" +books.size());
         //删除第三个元素
         books.remove( 2 );
         System.out.println(books);
         //判断指定元素在List集合中位置:输出1,表明位于第二位
         System.out.println(books.indexOf( new  String( "ROR敏捷开发最佳实践" ))); //1
         //将第二个元素替换成新的字符串对象
         books.set( 1 new  String( "Struts2权威指南" ));
         System.out.println(books);
         //将books集合的第二个元素(包括)到第三个元素(不包括)截取称子集合
         System.out.println(books.subList( 1  2 ));
 
     }
}

  输出结果:

---------- java运行 ----------
[轻量级J2EE企业应用实战, Struts2权威指南, 基于J2EE的Ajax宝典]
轻量级J2EE企业应用实战
ROR敏捷开发最佳实践
Struts2权威指南
基于J2EE的Ajax宝典
size:4
[轻量级J2EE企业应用实战, ROR敏捷开发最佳实践, 基于J2EE的Ajax宝典]
1
[轻量级J2EE企业应用实战, Struts2权威指南, 基于J2EE的Ajax宝典]
[Struts2权威指南]

输出完成 (耗时 0 秒) - 正常终止

二、Queue集合

Queue用于模拟队列这种数据结构,先进先出。

Queue接口定义的方法如下:

 boolean add(E e):   将指定的元素插入此队列(如果立即可行且不会违反容量限制),在成功时返回 true,如果当前没有可用的空间,则抛出 IllegalStateException

 E element(): 获取队列头部元素,但不删除该元素。

 boolean offer(E e):  将指定的元素插入此队列,当使用有容量限制的队列时,此方法通常要优于 add(E)

 E peek():   获取但不移除此队列的头;如果此队列为空,则返回 null

 E poll(): 获取并移除此队列的头,如果此队列为空,则返回 null

E remove(): 获取并移除此队列的头。

1.PriorityQueue实现类

PriorityQueue是一个比较标准的队列实现类,之所以说比较标准,而不是绝对标准,是因为PriorityQueue保存队列元素的顺序并不是按加入队列的顺序,而是按队列元素的大小进行重新排序。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import  java.util.*;
 
public  class  TestPriorityQueue
{
     public  static  void  main(String[] args)
     {
         PriorityQueue pq =  new  PriorityQueue();
         //下面代码依次向pq中加入四个元素
         pq.offer( 6 );
         pq.offer(- 3 );
         pq.offer( 9 );
         pq.offer( 0 );
         //输出pq队列,并不是按元素的加入顺序排列,而是按元素的大小顺序排列
         System.out.println(pq);
         //访问队列第一个元素,其实就是队列中最小的元素:-3
         System.out.println(pq.peek());
     }
}

  输出结果:

---------- java运行 ----------
[-3, 0, 9, 6]
-3

输出完成 (耗时 0 秒) - 正常终止

2.Deque接口与ArrayQueue实现类

Deque接口是Queue接口的子接口,它代表一个双端队列,Deque接口里定义了一些双端队列的方法,允许从两端来操作队列的元素。

Void addFirst(Object e):将指定元素插入该双端队列的开头。

Void addLast(Object e):将指定队列插入该双端队列的末尾。

Iterator descendingIterator():返回该双端队列对应的迭代器,该迭代器将以逆向顺序来迭代队列中的元素。

Object getFirst(): 获取但不删除队列的第一个元素。

详细参考api

ArrayQueue是Deque接口的典型实现类,他是一个基于数组实现的双端队列,底部也是采用动态的、可重新分配的Object[]数组存储集合元素。

示例:把ArrayQueue当”栈“使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import  java.util.*;
 
public  class  ArrayDequeTest
{
     public  static  void  main(String[] args)
     {
         ArrayDeque stack =  new  ArrayDeque();
         //依次将三个元素push入栈
         stack.push( "java" );
         stack.push( "java EE" );
         stack.push( "Android" );
         System.out.println(stack);   //输出
         //访问第一个元素,但不将其pop出栈
         System.out.println(stack.peek()); //
         //
         System.out.println(stack);
         //pop出第一个元素
         System.out.println(stack.pop());
          //
         System.out.println(stack);
     }
}

  输出结果:

[Android, java EE, java]
Android
[Android, java EE, java]
Android
[java EE, java]

**在现在的程序中需要使用“栈”这种数据结构时,推荐使用ArrayDeque或LinkedList,而不是Stack。

3.LinkedList实现类

LinkedList实现了List接口和Deque接口(好像图上没有画出来。。。。。),因此他是一个List集合还可以被当成双端队列来使用。

 LinkedList与ArrayList,ArrayDeque的实现机制完全不同,ArrayList、ArrayDeque内部以数组的形式来保存集合中的元素,因此随机访问集合元素时有较好的性能;而LinkedList内部以链表的形式来保存集合中的元素,因此随机访问性能较差,但是插入、删除元素时非常快。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import  java.util.*;
 
public  class  TestLinkedList
{
     public  static  void  main(String[] args)
     {
         LinkedList books =  new  LinkedList();
         //将字符串元素加入队列的尾部
         books.offer( "Java" );
         //将一个字符串元素入栈
         books.push( "J2EE" );
         //将字符串元素添加到队列的头部
         books.offerFirst( "Android" );
         for  ( int  i =  0 ; i < books.size() ; i++ )
         {
             System.out.println(books.get(i));
         }
         //访问、并不删除队列的第一个元素
         System.out.println(books.peekFirst());
         //访问、并不删除队列的最后一个元素
         System.out.println(books.peekLast());
         //采用出栈的方式将第一个元素pop出队列
         System.out.println(books.pop());
         //下面输出将看到队列中第一个元素被删除
         System.out.println(books);
         //访问、并删除队列的最后一个元素
         System.out.println(books.pollLast());
         //下面输出将看到队列中只剩下中间一个元素:轻量级J2EE企业应用实战
         System.out.println(books);
 
     }
}

  输出结果:

Android
J2EE
Java
Android
Java
Android
[J2EE, Java]
Java
[J2EE]

**上面的代码分别示范了双端队列,栈的用法,所以LinkedList是一个功能非常强大的集合类。

4.各种线性表的性能分析:


示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import  java.util.*;
/**
  * Description:
  * <br/>Copyright (C), 2005-2008, Yeeku.H.Lee
  * <br/>This program is protected by copyright laws.
  * <br/>Program Name:
  * <br/>Date:
  * @author  Yeeku.H.Lee kongyeeku@163.com
  * @version  1.0
  */
public  class  TestPerformance
{
     public  static  void  main(String[] args)
     {
         //创建一个字符串数组
         String[] tst1 =  new  String[ 900000 ];
         //动态初始化数组元素
         for  ( int  i =  0 ; i <  900000 ; i++)
         {
             tst1[i] = String.valueOf(i);
         }
         
         ArrayList al =  new  ArrayList();
         //将所有数组元素加入ArrayList集合中
         long  start = System.currentTimeMillis();
         for  ( int  i =  0 ; i <  900000  ; i++)
         {
             al.add(tst1[i]);
         }
         System.out.println( "ArrayList集合添加元素的时间:"  + (System.currentTimeMillis() - start));
         LinkedList ll =  new  LinkedList();
         //将所有数组元素加入LinkedList集合中
         start = System.currentTimeMillis();
         for  ( int  i =  0 ; i <  900000  ; i++)
         {
             ll.add(tst1[i]);
         }
         System.out.println( "LinkedList集合添加元素的时间:"  + (System.currentTimeMillis() - start));
         //迭代访问ArrayList集合的所有元素,并输出迭代时间
         start = System.currentTimeMillis();
         for  (Iterator it = al.iterator();it.hasNext() ; )
         {
             it.next();
         }
         System.out.println( "迭代ArrayList集合元素的时间:"  + (System.currentTimeMillis() - start));
         //迭代访问LinkedList集合的所有元素,并输出迭代时间
         start = System.currentTimeMillis();
         for  (Iterator it = ll.iterator();it.hasNext() ; )
         {
             it.next();
         }
         System.out.println( "迭代LinkedList集合元素的时间:"  + (System.currentTimeMillis() - start));
         
     }
}

  示例:

  输出结果:

ArrayList集合添加元素的时间:446
LinkedList集合添加元素的时间:16
迭代ArrayList集合元素的时间:11
迭代LinkedList集合元素的时间:12

**可以看出LinkedList添加元素特别快,是ArrayList的几十倍,但遍历时不相上下。用foreach遍历LinkedList也比ArrayList快。

(博主试了一下,结果是迭代时LinkedList快很多


java中的集合到这里基本上总结完啦。。。

下篇会总结下操作集合的工具类:Collections,用它可以方便的把集合变成线程安全的。

转载出处:http://www.cnblogs.com/jycboy/p/javalist.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值