,,JAVA ArrayList详细介绍(示例)

,,JAVA ArrayList详细介绍(示例)

本文对Java语言(一种计算机语言,尤用于创建网站)数组列表做了详细介绍,文中学到了数组列表源码解析、数组列表遍历方式、toArray()异常,最后给出了数组列表示例。

第1部分 ArrayList介绍数组列表是一个数组队列,相当于动态数组。与Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)中的数组相比,它的容量能动态增长。它继承于抽象主义者,实现了List,RandomAccess,Cloneable,java.io.Serializable这些接口数组列表。继承了抽象主义者,实现了列表。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能数组列表。实现了RandmoAccess接口,即提供了随机访问功能随机访问.是Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)中用来被目录实现,为目录提供快速访问功能的。在数组列表中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。稍后,我们会比较目录的"快速随机访问"和"通过迭代程序迭代器访问"的效率数组列表。实现了可克隆的接口,即覆盖了函数克隆(),能被克隆数组列表。实现java.io。序列化接口,这意味着数组列表支持序列化,能通过序列化去传输。和矢量不同,数组列表中的操作不是线程安全的。所以,建议在单线程中才使用数组列表,而在多线程中可以选择矢量或者CopyOnWriteArrayList。

ArrayList的继承关系ArrayList与Collection关系如下图:ArrayList构造函数复制代码代码如下://默认构造函数ArrayList()//容量是数组列表的默认容量大小。当由于增加数据导致容量不足时,容量会添加上一次容量大小的一半ArrayList(int capacity)//创建一个包含收藏品的ArrayListArrayList(集合?扩展E系列)

数组列表的应用程序接口复制代码代码如下://集合中定义的API布尔加法(E对象)布尔addAll(集合?扩展E集合)void clear()boolean contains(Object对象)boolean contains all(集合?集合)布尔等于(Object Object)int hashCode()布尔isEmpty()迭代器迭代器()布尔删除(Object Object)布尔删除全部(集合?收藏)布尔零售全部(收藏?collection)int size()T T[]to array(T[]array)Object[]to array()//抽象集合中定义的APIvoid add(int location,E object)boolean addAll(int location,Collection?扩展E集合)E get(int location)int index of(Object Object)int lastIndexOf(Object Object)list iterator list iterator(int location)list iterator list iterator()E remove(int location)E set(int location,E object)ListE subList(int start,int end)//ArrayList新增的API对象克隆()void确保容量(int最小容量)void trim tosize()void移除范围(int from index,int toIndex)

第2部分 ArrayList源码解析为了更了解数组列表的原理,下面对数组列表源码代码作出分析数组列表。是通过数组实现的,源码比较容易理解。复制代码代码如下:包java.util公共类数组列表扩展抽象主义者实现ListE,RandomAccess,Cloneable,java.io.Serializable{ //序列版本号私有静态最终长串行版本uid=8683452581122892189 l;//保存数组列表中数据的数组私有瞬态对象[]元素数据;//ArrayList中实际数据的数量私有(同Internationalorganizations)国际组织大小;//ArrayList带容量大小的构造函数public ArrayList(int初始容量){ super();if (initialCapacity 0)抛出新的IllegalArgumentException('非法容量:‘初始容量’);//新建一个数组这个。元素数据=新对象[初始容量];} //ArrayList构造函数。默认容量是10。public ArrayList(){ this(10);} //创建一个包含收藏品的数组列表公共数组列表(集合?将E c){ element data=c .扩展到array();size=elementData.length//托阿瑞可能(不正确地)不返回对象[](参见6260652)if(元素数据。getclass()!=对象[]。class)元素数据=数组。(元素数据,大小,对象[]得副本.类);}

//将当前容量值设为=实际元素个数public void trim tosize(){ modCount;旧能力=要素数据。长度;if(调整旧容量){元素数据=数组。(元素数据、大小)的副本;} }

//确定数组列表的容量。 //若数组列表的容量不足以容纳当前的全部元素,设置新的容量="(原始容量x3)/2 1 " public void确保容量(int minCapacity){//将"修改统计数“1 modCountint旧容量=元素数据。长度;//若当前容量不足以容纳当前的元素个数,设置新的容量="(原始容量x3)/2 1 " if(最小容量旧容量){对象旧数据[]=元素数据;int新容量=(旧容量* 3)/2 1;if(新产能最小产能)新产能=最小产能;元素数据=数组。(元素数据、新容量)的副本;} } //添加元素e public boolean add(E e) { //确定数组列表的容量大小确保容量(尺寸1);//递增modCount!//添加e到数组列表中元素数据[大小]=e;返回true} //返回数组列表的实际大小public int size(){ return size;} //返回数组列表是否包含Object(o) public布尔值包含(Object o){ return index of(o)=0;} //返回数组列表是否为空public boolean isEmpty(){ return size==0;} //正向查找,返回元素的索引值(Object o){ if(o==null){ for(int I=0;我尺寸;i ) if (elementData[i]==null)返回我;} else { for(int I=0;我尺寸;i ) if (o.equals(elementData[i]))返回我;} return-1;} //反向查找,返回元素的索引值public int lastIndexOf(Object o){ if(o==null){ for(int I=size-1;I=0;i - ) if (elementData[i]==null)返回我;} else { for(int I=size-1;I=0;i - ) if (o.equals(elementData[i]))返回我;} return-1;} //反向查找(从数组末尾向开始查找),返回元素(o)的索引值public int lastIndexOf(Object o){ if(o==null){ for(int I=size-1;I=0;i - ) if (elementData[i]==null)返回我;} else { for(int I=size-1;I=0;i - ) if (o.equals(elementData[i]))返回我;} return-1;}

//返回数组列表的目标数组array()的公共对象[]{返回数组。(元素数据、大小)的副本;} //返回数组列表的模板数组。所谓模板数组,即可以将T设为任意的数据类型public T T[] toArray(T[] a) { //若数组a的大小数组列表的元素个数;//则新建一个T[]数组,数组大小是"数组列表的元素个数",并将"数组列表"全部拷贝到新数组中if(a . length size)返回(T[])个数组。(element data,size,a . getclass())的副本;//若数组a的大小=数组列表的元素个数;//则将数组列表的全部元素都拷贝到数组a中System.arraycopy(elementData,0,a,0,size);if(a . length size)a[size]=null;返回a;} //获取指数位置的元素值public E get(int index){ range check(index);return(E)元素数据[index];} //设置指数位置的值为element public E set(int index,E element){ range check(index);E旧值=(E)元素数据[索引];元素数据[索引]=元素;返回旧值;} //将e添加到数组列表中public boolean add(E E){确保容量(大小1);//递增modCount!元素数据[大小]=e;返回true} //将e添加到数组列表的指定位置public void add(int index,E element){ if(Index Size | | Index 0)throw new IndexOutOfBoundsException(' Index:' Index ',Size:' Size);确保容量(尺寸1);//递增modCount!System.arraycopy(elementData,index,elementData,index 1,size-index);元素数据[索引]=元素;尺寸;} //删除数组列表指定位置的元素public E remove(int index){ range check(index);modCountE old value=(E)元素数据[index];int num moved=size-索引-1;if(num移动0)系统。数组复制(elementData,index 1,element data,index,num moved);元素数据[-size]=null;//让千兆周做它的工作返回旧值} //删除数组列表的指定元素public boolean remove(Object o){ if(o==null){ for(int index=0;索引大小;index)if(element data[index]==null){ fast remove(index);返回true} } else { for (int索引=0;索引大小;index)if(o . equals(element data[index]){ fast remove(index);返回true} }返回false}

//快速删除第指数个元素private void fast remove(int index){ modCount;int num moved=size-索引-1;//从索引1 '开始,用后面的元素替换前面的元素。if(num移动0)系统。数组复制(elementData,index 1,element data,index,num moved);//将最后一个元素设为null元素数据[-size]=null;//让千兆周做它的工作} //删除元素public boolean remove(Object o){ if(o==null){ for(int index=0;索引大小;index)if(element data[index]==null){ fast remove(index);返回true} } else { //便利数组列表,找到"元素o”,则删除,并返回没错for(int index=0;索引大小;index)if(o . equals(element data[index]){ fast remove(index);返回true} }返回false} //清空数组列表,将全部的元素设为空公共void clear(){ modCount;for(int I=0;我尺寸;I)元素数据[I]=空;大小=0;} //将集合c追加到数组列表中公共布尔addAll(集合?将E c){ Object[]a=c .扩展到array();int numNew=a.length确保容量(大小numNew);//递增modCount System.arraycopy(a,0,elementData,size,numNew);size=numNew返回numNew!=0;} //从指数位置开始,将集合c添加到数组列表公共布尔addAll(int index,Collection?extends E c){ if(Index Size | | Index 0)throw new IndexOutOfBoundsException(' Index:' Index ',Size:' Size);object[]a=c . to array();int numNew=a.length确保容量(大小numNew);//递增modCount int num moved=size-index;if(num移动0)系统。数组复制(elementData,index,element data,index numNew,num moved);System.arraycopy(a,0,elementData,index,numNew);size=numNew返回numNew!=0;} //删除从索引到toIndex之间的全部元素protected void remove range(int from index,int to index){ mod count;int num moved=size-toIndex;System.arraycopy(elementData,toIndex,elementData,fromIndex,num moved);//让千兆周做它的工作int new size=size-(到索引-从索引);而(大小!=newSize)元素数据[-size]=null;} private void range check(int Index){ if(Index=Size)throw new IndexOutOfBoundsException(' Index:' Index ',Size:' Size);}

//克隆函数public Object clone(){ try { ArrayList v=(ArrayList)super。clone();//将当前数组列表的全部元素拷贝到v中v .元素数据=数组。(元素数据、大小)的副本;v . mod计数=0;回归五;} catch(CloneNotSupportedException e){//这不应该发生,因为我们是可克隆的抛出新的内部错误();} }

//java.io.Serializable的写入函数//将数组列表的"容量,所有的元素值"都写入到输出流中私有void writeObject(Java。io。对象输出流抛出java.io.IOException{ //写出元素计数,任何隐藏的东西int expectedModCount=modCounts。defaultwriteobject();//写入"数组的容量" s . write int(元素数据。长度);//写入"数组的每一个元素“for(int I=0;isi zei)s . writeobject(element data[I]);如果(modCount!=expectedModCount){ throw new ConcurrentModificationException();} }

//java.io.Serializable的读取函数:根据写入方式读出//先将数组列表的"容量"读出,然后将"所有的元素值"读出私有void读取对象(Java。io。对象输入流抛出java.io.IOException,ClassNotFoundException {//读入大小,以及任何隐藏的stuff s . default read object();//从输入流中读取数组列表的"容量" int数组长度=s . readint();Object[]a=元素数据=新对象[数组长度];//从输入流中将"所有的元素值"读出for(int I=0;isi zei)a[I]=s . read object();}}总结:(01)数组列表实际上是通过一个数组去保存数据的。当我们构造数组列表时;若使用默认构造函数,则数组列表的默认容量大小是10。(02) 当数组列表容量不足以容纳全部元素时,数组列表会重新设置容量:新的容量="(原始容量x3)/2 1英寸。(03)数组列表的克隆函数,即是将全部元素克隆到一个数组中数组列表实现java.io。序列化的方式。当写入到输出流时,先写入"容量",再依次写入"每一个元素";当读出输入流时,先读取"容量",再依次读取"每一个元素"。

第3部分 ArrayList遍历方式数组列表支持3种遍历方式(01) 第一种,通过迭代器遍历。即通过迭代程序去遍历。复制代码代码如下:整数值ITER=列表。迭代器();而(ITER。has next()){ value=(整数)ITER。next();}(02) 第二种,随机访问,通过索引值去遍历。由于数组列表实现了随机访问接口,它支持通过索引值去随机访问元素。复制代码代码如下:整数值=nullint size=list。size();for(int I=0;isizeI){ value=(Integer)list。get(I);}(03) 第三种,用于循环遍历。如下:复制代码代码如下:整数值=null for(Integer integ:list){ value=integ;}下面通过一个实例,比较这3种方式的效率,实例代码(ArrayListRandomAccessTest.java)如下:复制代码代码如下:导入Java。util。*;导入Java。util。并发。*;/** @desc数组列表遍历方式和效率的测试程序* * @ author skywang */public class arrayislandomaccesstest { public static void main(String[]args){ List List=new ArrayList();for(int I=0;i100000list。add;//isRandomAccessSupported(list);iteratorthrourandomaccess(list);迭代器通过迭代器(列表);iteratorThroughFor2(列表);

}私有静态void isRandomAccessSupported(List List){ if(列出随机访问的实例){ system。出去。println('实现随机访问!');} else { system。出去。println('随机访问未实现!');} } public static void iterathrourandomaccess(List List){ long start time;结束时间长;开始时间=系统。当前时间毫秒();for(int I=0;伊利斯特。size();I){列表。get(I);}结束时间=系统。当前时间毫秒();长间隔=结束时间-开始时间;系统。出去。println(' iteratorthrourandomaccess:' interval ' ms ');}公共静态void迭代器through迭代器(List List){长启动时间;结束时间长;开始时间=系统。当前时间毫秒();for(迭代器ITER=列表。迭代器();ITER。有next();){ ITER。next();}结束时间=系统。当前时间毫秒();长间隔=结束时间-开始时间;系统。出去。println(' iterator through iterator:' interval ' ms ');}

2的公共静态void迭代器(列表列表){长开始时间;结束时间长;开始时间=系统。当前时间毫秒();对于(对象对象:列表)

结束时间=系统。当前时间毫秒();长间隔=结束时间-开始时间;系统。出去。println(' iteratorthroughfor 2:'间隔' ms ');}}运行结果:iteratorThroughRandomAccess:3 msiteratorthrough iterator:8 msiteratorthrough for 2:5毫秒由此可见,遍历数组列表时,使用随机访问(即,通过索引序号访问)效率最高,而使用迭代器的效率最低!

第4部分 toArray()异常当我们调用数组列表中的toArray(),可能遇到过抛出" java.lang.ClassCastException "异常的情况。下面我们说说这是怎么回事数组列表。提供了2个托阵列()函数:Object[]to array()T T[]to array(T[]contents)调用托阵列()函数会抛出" java.lang.ClassCastException "异常,但是调用toArray(T[]内容)能正常返回T[]。托阵列()会抛出异常是因为托阵列()返回的是对象[]数组,将对象[]转换为其它类型(如如,将对象[]转换为的整数[])则会抛出" java.lang.ClassCastException "异常,因为Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)不支持向下转型。具体的可以参考前面ArrayList.java的源码介绍部分的toArray()。解决该问题的办法是调用T T[] toArray(T[]内容),而不是Object[] toArray()。调用toArray(T[]内容)返回T[]的可以通过以下几种方式实现。复制代码代码如下://toArray(T[]内容)调用方式一public static Integer[]vectortoarray 1(ArrayListInteger v){ Integer[]new text=new Integer[v . size()];v.toArray(新文本);返回newText}//toArray(T[]内容)调用方式二。最常用!public static Integer[]vectortoarray 2(ArrayListInteger v){ Integer[]new text=(Integer[])v . to array(new Integer[0]);返回newText}//toArray(T[]内容)调用方式三public static Integer[]vectortoarray 3(ArrayListInteger v){ Integer[]new text=new Integer[v . size()];Integer[]new strings=(Integer[])v . to array(新文本);返回新字符串;}

第5部分 ArrayList示例本文通过一个实例(ArrayListTest.java),介绍数组列表的常用API。复制代码代码如下:导入Java。util。*;/** @desc数组列表常用应用程序接口的测试程序* @作者skywang * @邮箱-王@ 163。com */public class ArrayList test { public static void main(String[]args){

//创建ArrayList ArrayList=new ArrayList();//将“”列表。添加(“1”);列表。add(" 2 ");列表。add(" 3 ");列表。添加(“4”);//将下面的元素添加到第一个位置list.add(0,' 5 ');//获取第一个元素System.out.println('第一个元素是:'列表。get(0));//删除“3”列表。删除(“3”);//获取数组列表的大小系统。出去。println(' Arraylist size=:' list。size());//判断目录中是否包含3 '系统。出去。println(' ArrayList包含3个is:' list。包含(3));//设置第2个元素为10 list.set(1,' 10 ');//通过迭代程序遍历(迭代器ITER=列表的数组列表。迭代器();ITER。有next();){系统。出去。println(‘下一个是:‘ITER。next());} //将数组列表转换为数组String[]arr=(String[])list。to数组(新字符串[0]);for(String str:arr)系统。出去。println(' str:' str ');//清空数组列表。clear();//判断数组列表是否为空System.out.println('数组列表为空:'列表。isempty());}}

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: