最基本的Java集合框架---List

由于Collection接口是最基本的接口,通常情况下不被直接使用,因此通过其子接口List和Set对集合进行操作

List,Set接口对Collection接口进行了简单的扩充,要实现的功能基本没有太大的改变


List

List是一个接口,它继承于Collection接口,代表着有序的队列(元素有序并不是大小有序,而是类似于数组,具有顺序索引)。


常有的方法:

1.添加

boolean add(E e)                            向列表的尾部添加指定的元素
void add(int index, E element)        在列表的指定位置插入指定元素


2.移除

E remove(int index)                        移除列表中指定位置的元素

void clear( )                                     从列表中移除所有元素

补充:

List.remove

List没remove掉一个元素以后,后面的元素都会向前移动,此时如果执行i++,则刚移过来的元素没有被读取


3.查询

E get(int index)                              返回列表中指定位置的元素

boolean contains(Object o)           如果列表包含指定的元素,则返回 true

int size( )                                       返回列表中的元素数

E set(int index, E element)           用指定元素替换列表中指定位置的元素

ListIterator<E> listIterator( )         返回此列表元素的列表迭代器。



AbstractCollection是一个抽象类,Collection接口的唯一直接实现类

List的实现类AbstractList继承Abstractcollection。AbstractList实现List接口中除了size(),get(int  location)之外的函数。

AbstractSequentialList 是一个抽象类, 它继承于AbstractList。实现了链表中,根据index索引值操作链表的全部函数。

List的四个重要实现类

ArrayList  LinkedList  Vector  Stack

ArrayList    继承AbstractList,是一个数组队列,是实现List接口的动态数组,随机访问效率高,插入,删除效率低。

注意:Array List没有定义长度时,默认的初始长度为10,当长度不够用时会以“原始容量*3/2+1"进行扩容。Array List线程是不安全的,多线程情况下不要使用。

Vector(向量类)继承AbstractList,是一个矢量队列,和ArrayList类似,可实现自动增长的对象数组

Array List线程不安全        Vector是线程安全的
ArrayList适合于单线程      Vector适合于多线程

注意:ArrayList实现不是同步的。如果多个线程同时访问一个ArrayList实例,而其中至少一个线程从结构上修改了列表,那么它必须保持外部同步。所以为了保证同步,最好的办法是在创建时完成,以防止意外对列表进行不同步的访问:

        List list = Collections.synchronizedList(new ArrayList(...)); 

ArrayList提供了三个构造函数:

     ArrayList():默认构造函数,提供初始容量为10的空列表。

     ArrayList(int initialCapacity):构造一个具有指定初始容量的空列表。

     ArrayList(Collection<? extends E> c):构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。

ArrayList主要方法实例
  1. import java.util.ArrayList;  
  2. import java.util.Iterator;  
  3. public class MyArrayList {  
  4.    
  5.  public static void main(String []args){  
  6.     
  7.   ArrayList list1 = new ArrayList();    
  8.   list1.add("one");  
  9.   list1.add("two");  
  10.   list1.add("three");  
  11.   list1.add("four");  
  12.   list1.add("five");  
  13.   list1.add(0,"zero");    
  14.   System.out.println("<--list1中共有>" + list1.size()+ "个元素");    
  15.   System.out.println("<--list1中的内容:" + list1 + "-->");  
  16.     
  17.   ArrayList list2 = new ArrayList();  
  18.   list2.add("Begin");  
  19.   list2.addAll(list1);  
  20.   list2.add("End");  
  21.   System.out.println("<--list2中共有>" + list2.size()+ "个元素");    
  22.   System.out.println("<--list2中的内容:" + list2 + "-->");  
  23.     
  24.   ArrayList list3 =  new ArrayList();  
  25.   list3.removeAll(list1);  
  26.   System.out.println("<--list3中是否存在one: "+ (list3.contains("one")? "是":"否")+ "-->");  
  27.     
  28.   list3.add(0,"same element");  
  29.   list3.add(1,"same element");  
  30.   System.out.println("<--list3中共有>" + list3.size()+ "个元素");    
  31.   System.out.println("<--list3中的内容:" + list3 + "-->");  
  32.   System.out.println("<--list3中第一次出现same element的索引是" + list3.indexOf("same element") + "-->");  
  33.   System.out.println("<--list3中最后一次出现same element的索引是" + list3.lastIndexOf("same element") + "-->");  
  34.     
  35.     
  36.   System.out.println("<--使用Iterator接口访问list3->");  
  37.   Iterator it = list3.iterator();     
  38.   while(it.hasNext()){               //迭代器
  39.   String str = (String)it.next();  
  40.    System.out.println("<--list3中的元素:" + list3 + "-->");  
  41.   }  
  42.     
  43.   System.out.println("<--将list3中的same element修改为another element-->");  
  44.   list3.set(0,"another element");  
  45.   list3.set(1,"another element");  
  46.      System.out.println("<--将list3转为数组-->");  
  47.     // Object []  array =(Object[]) list3.toArray(new   Object[list3.size()] );  
  48.      Object [] array = list3.toArray();  
  49.      for(int i = 0; i < array.length ; i ++){  
  50.       String str = (String)array[i];  
  51.       System.out.println("array[" + i + "] = "+ str);        
  52.      }       
  53.        
  54.      System.out.println("<---清空list3->");  
  55.      list3.clear();  
  56.      System.out.println("<--list3中是否为空: " + (list3.isEmpty()?"是":"否") + "-->");  
  57.      System.out.println("<--list3中共有>" + list3.size()+ "个元素");   
  58.     
  59.   //System.out.println("hello world!");  
  60.  }  


LinkedList  继承AbstractSequentialList,是一个双向链表,可以被当作堆栈,队列或双端队列进行操作,随机访问效率低,插入,删除高。

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable

  从这段代码中我们可以清晰地看出LinkedList继承AbstractSequentialList,实现List、Deque、Cloneable、Serializable。其中AbstractSequentialList提供了 List 接口的骨干实现,从而最大限度地减少了实现受“连续访问”数据存储(如链接列表)支持的此接口所需的工作,从而以减少实现List接口的复杂度。Deque一个线性 collection,支持在两端插入和移除元素,定义了双端队列的操作。

transient Entry<E> header=new Entry<E>;
transient int size=0;
两个基本属性   size----LinkedList的大小

                         header----链表的表头
                        
                         Entry----节点对象
内部类:Entry

   双向链表节点所对应的数据结构,Entry为LinkedList的内部类,定义了存储的元素。
   属性:当前节点所包含的值,上一个节点,下一个节点。

LinkedList的主要方法实例

import java.util.LinkedList;
public class Linked {
 public static void main(String[] args) {
      testLinkedListAPIs();
 }
 private static void testLinkedListAPIs() {
  String val=null;
  LinkedList<String> llist=new LinkedList<String>();
  llist.add("1");
  llist.add("2");
  llist.add("3");
  llist.add(1, "4");
  System.out.println("Test addFirst(),removeFirst(),getFirst()");
  llist.addFirst("10");
  System.out.println(llist);
  System.out.println(llist.removeFirst());
  System.out.println(llist.getFirst());
  String[] arr=llist.toArray(new String[0]);
  for(String str:arr)
   System.out.println(str);
 }
 
}

Stack继承Vector   栈     先进后出

ArrayList和LinkedList之间的效率对比实例

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
import java.util.Vector;
public class CollectionDeom{
 static final int count=100000;
 static LinkedList linkedList=new LinkedList();
 static ArrayList arrayList=new ArrayList();
 static Vector vector=new Vector();
 static Stack stack=new Stack();
 public static void main(String[] args) {
  System.out.println();
  insertByPosition(stack);
  insertByPosition(vector);
  insertByPosition(linkedList);
  insertByPosition(arrayList);
  readByPosition(stack);
  readByPosition(vector);
  readByPosition(linkedList);
  readByPosition(arrayList);
  deleteByPosition(stack);
  deleteByPosition(vector);
  deleteByPosition(linkedList);
  deleteByPosition(arrayList);
 
 }
 private static void deleteByPosition(List list) {
 long starttime=System.currentTimeMillis();
 for(int i=0;i<count;i++)
  list.remove(0);
  long endtime=System.currentTimeMillis();
  long interval=endtime-starttime;
  System.out.println(getListName(list)+" "+count+" "+interval);
}
private static void readByPosition(List list) {
 long starttime=System.currentTimeMillis();
 for(int i=0;i<count;i++) {
  list.get(i);
 }
 long endtime=System.currentTimeMillis();
 long interval=endtime-starttime;
 System.out.println(getListName(list)+" "+count+" "+interval);
 
}
private static String getListName(List list) {
  if(list instanceof LinkedList) {
   return "LinkedList";
  }
  else if(list instanceof ArrayList) {
   return "ArrayList";
  }
  else if(list instanceof Stack) {
   return "Stack";
  }
  else if(list instanceof Vector) {
   return "Vector";
  }
  else {
   return "List";
  }
 
 }
private static void insertByPosition(List list) {
 long starttime=System.currentTimeMillis();
 for(int i=0;i<count;i++)
  list.add(0,i);
  long endtime=System.currentTimeMillis();
  long interval=endtime-starttime;
  System.out.println(getListName(list)+" "+count+" "+interval);
  
}
}
插入操作
Stack 100000 3378
Vector 100000 2606
LinkedList 100000 19
ArrayList 100000 2368
读取操作
Stack 100000 5
Vector 100000 5
LinkedList 100000 19063
ArrayList 100000 2
删除操作
Stack 100000 1065
Vector 100000 1063
LinkedList 100000 3
ArrayList 100000 1077

对比ArrayList,LinkedList,Stack,Vector四者之间的插入,读取,删除的时间可以看出ArrayList在进行读取操作时速度明显比LinkedList快,在进行插入和删除操作时速度慢。

注意:ArrayList 是实现了RandomAccess接口的,这种接口的子类,在循环时使用 for 循环相比 iterator 效率要高很多;LinkedList 并没有实现 RandomAccess 接口,在读取数据的时候应该用迭代器的方式去读取

if(list instanceof LinkedList){
for(Iterator it = list.iterator(); it.hasNext;)
it.next();
}

使用List集合时,通常情况下声明为List类型,实例化时,根据实际情况的需要选择不同的实现类。



















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值