zoukankan      html  css  js  c++  java
  • 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): 在指定位置插入一个元素。

     示例:

    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示例:

    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保存队列元素的顺序并不是按加入队列的顺序,而是按队列元素的大小进行重新排序。

    示例:

    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当”栈“使用

    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内部以链表的形式来保存集合中的元素,因此随机访问性能较差,但是插入、删除元素时非常快。

    示例:

    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

    不支持

    不支持

    不支持

    ArrayList/ArrayDeque

    以数组保存元素

    2

    2

    2

    2

    Vector

    以数组保存元素

    3

    3

    3

    3

    LinkedList

    链表保存元素

    4

    1

    1

    1

      示例:

    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快。

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

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

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

  • 相关阅读:
    《.NET内存管理宝典 》(Pro .NET Memory Management) 阅读指南
    《.NET内存管理宝典 》(Pro .NET Memory Management) 阅读指南
    《.NET内存管理宝典 》(Pro .NET Memory Management) 阅读指南
    使用Jasmine和karma对传统js进行单元测试
    《.NET内存管理宝典 》(Pro .NET Memory Management) 阅读指南
    《.NET内存管理宝典 》(Pro .NET Memory Management) 阅读指南
    nginx 基于IP的多虚拟主机配置
    Shiro 框架的MD5加密算法实现原理
    项目实战:Qt+OSG三维点云引擎(支持原点,缩放,单独轴或者组合多轴拽拖旋转,支持导入点云文件)
    实用技巧:阿里云服务器建立公网物联网服务器(解决阿里云服务器端口,公网连接不上的问题)
  • 原文地址:https://www.cnblogs.com/jycboy/p/javalist.html
Copyright © 2011-2022 走看看