gpt4 book ai didi

Java中ArrayList类的用法与源码完全解析

转载 作者:qq735679552 更新时间:2022-09-29 22:32:09 29 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章Java中ArrayList类的用法与源码完全解析由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

System.Collections.ArrayList类是一个特殊的数组。通过添加和删除元素,就可以动态改变数组的长度.

一.优点 1. 支持自动改变大小的功能 2. 可以灵活的插入元素 3. 可以灵活的删除元素 。

二.局限性 跟一般的数组比起来,速度上差些 。

三.添加元素 1.publicvirtualintAdd(objectvalue); 将对象添加到ArrayList的结尾处 。

?
1
2
3
4
5
6
ArrayList aList = new ArrayList();
aList.Add( "a" );
aList.Add( "b" );
aList.Add( "c" );
aList.Add( "d" );
aList.Add( "e" );

内容为 。

?
1
abcde

2.publicvirtualvoidInsert(intindex,objectvalue); 将元素插入ArrayList的指定索引处 。

?
1
2
3
4
5
6
7
ArrayList aList = new ArrayList();
aList.Add( "a" );
aList.Add( "b" );
aList.Add( "c" );
aList.Add( "d" );
aList.Add( "e" );
aList.Insert( 0 , "aa" );

结果为 。

?
1
aaabcde

3.publicvirtualvoidInsertRange(intindex,ICollectionc); 将集合中的某个元素插入ArrayList的指定索引处 。

?
1
2
3
4
5
6
7
8
9
10
ArrayList aList = new ArrayList();
aList.Add( "a" );
aList.Add( "b" );
aList.Add( "c" );
aList.Add( "d" );
aList.Add( "e" );
ArrayList list2 = newArrayList();
list2.Add( "tt" );
list2.Add( "ttt" );
aList.InsertRange( 2 ,list2);

结果为 。

?
1
abtttttcde

四.删除 1. publicvirtualvoidRemove(objectobj); 从ArrayList中移除特定对象的第一个匹配项,注意是第一个 。

?
1
2
3
4
5
6
7
ArrayList aList = new ArrayList();
aList.Add( "a" );
aList.Add( "b" );
aList.Add( "c" );
aList.Add( "d" );
aList.Add( "e" );
aList.Remove( "a" );

结果为 。

?
1
bcde

2. publicvirtualvoidRemoveAt(intindex); 移除ArrayList的指定索引处的元素 。

?
1
2
3
4
5
6
aList.Add( "a" );
aList.Add( "b" );
aList.Add( "c" );
aList.Add( "d" );
aList.Add( "e" );
aList.RemoveAt( 0 );

结果为 。

?
1
bcde

3.publicvirtualvoidRemoveRange(intindex,intcount); 从ArrayList中移除一定范围的元素。Index表示索引,count表示从索引处开始的数目 。

?
1
2
3
4
5
6
aList.Add( "a" );
aList.Add( "b" );
aList.Add( "c" );
aList.Add( "d" );
aList.Add( "e" );
aList.RemoveRange( 1 , 3 );

结果为 。

  。

复制代码 代码如下:
ae

4.publicvirtualvoidClear(); 从ArrayList中移除所有元素.

  。

五.排序 1. publicvirtualvoidSort(); 对ArrayList或它的一部分中的元素进行排序.

?
1
2
3
4
5
6
7
8
ArrayListaList=newArrayList();
aList.Add( "e" );
aList.Add( "a" );
aList.Add( "b" );
aList.Add( "c" );
aList.Add( "d" );
DropDownList1.DataSource=aList; //DropDownListDropDownList1;
DropDownList1.DataBind();

结果为 。

?
1
eabcd
?
1
2
3
4
5
6
7
8
9
ArrayListaList=newArrayList();
aList.Add( "a" );
aList.Add( "b" );
aList.Add( "c" );
aList.Add( "d" );
aList.Add( "e" );
aList.Sort(); //排序
DropDownList1.DataSource=aList; //DropDownListDropDownList1;
DropDownList1.DataBind();

结果为 。

?
1
abcde

2.publicvirtualvoidReverse(); 将ArrayList或它的一部分中元素的顺序反转.

?
1
2
3
4
5
6
7
8
9
ArrayListaList=newArrayList();
aList.Add( "a" );
aList.Add( "b" );
aList.Add( "c" );
aList.Add( "d" );
aList.Add( "e" );
aList.Reverse(); //反转
DropDownList1.DataSource=aList; //DropDownListDropDownList1;
DropDownList1.DataBind();

结果为 。

?
1
edcba

六.查找 1.publicvirtualintIndexOf(object); 2. publicvirtualintIndexOf(object,int); 3. publicvirtualintIndexOf(object,int,int);     返回ArrayList或它的一部分中某个值的第一个匹配项的从零开始的索引。没找到返回-1.

?
1
2
3
4
5
6
7
8
ArrayList aList = new ArrayList();
aList.Add( "a" );
aList.Add( "b" );
aList.Add( "c" );
aList.Add( "d" );
aList.Add( "e" );
intnIndex=aList.IndexOf(“a”); //1
nIndex=aList.IndexOf(“p”); //没找到,-1

4.publicvirtualintLastIndexOf(object); 5.publicvirtualintLastIndexOf(object,int); 6.publicvirtualintLastIndexOf(object,int,int);     返回ArrayList或它的一部分中某个值的最后一个匹配项的从零开始的索引.

?
1
2
3
4
5
6
7
ArrayList aList = new ArrayList();
aList.Add( "a" );
aList.Add( "b" );
aList.Add( "a" ); //同0
aList.Add( "d" );
aList.Add( "e" );
intnIndex=aList.LastIndexOf( "a" ); //值为2而不是0

7. publicvirtualboolContains(objectitem);     确定某个元素是否在ArrayList中。包含返回true,否则返回false 。

七.其他 1.publicvirtualintCapacity{get;set;} 获取或设置ArrayList可包含的元素数。 2.publicvirtualintCount{get;} 获取ArrayList中实际包含的元素数。 Capacity是ArrayList可以存储的元素数。Count是ArrayList中实际包含的元素数。Capacity总是大于或等于Count。如果在添加元素时,Count超过Capacity,则该列表的容量会通过自动重新分配内部数组加倍。 如果Capacity的值显式设置,则内部数组也需要重新分配以容纳指定的容量。如果Capacity被显式设置为0,则公共语言运行库将其设置为默认容量。默认容量为16。 在调用Clear后,Count为0,而此时Capacity切是默认容量16,而不是0 3.publicvirtualvoidTrimToSize(); 将容量设置为ArrayList中元素的实际数量。 如果不向列表中添加新元素,则此方法可用于最小化列表的内存系统开销。 若要完全清除列表中的所有元素,请在调用TrimToSize之前调用Clear方法。截去空ArrayList会将ArrayList的容量设置为默认容量,而不是零.

?
1
2
3
4
5
6
7
ArrayList aList = new ArrayList();
aList.Add( "a" );
aList.Add( "b" );
aList.Add( "c" );
aList.Add( "d" );
aList.Add( "e" ); //Count=5,Capacity=16,
aList.TrimToSize(); //Count=Capacity=5;

八.源码分析 List 接口的一个实现类,内部是用一个数组存储元素值,相当于一个可变大小的数组.

1.签名 。

?
1
2
3
public class ArrayList<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, Serializable

可以看到ArrayList继承了AbstractList抽象类,它实现了List接口的大多数方法。如果要实现一个不可变的List,只要继承这个类并且实现get(int)和size方法。如果要实现可变的List,需要覆盖set(int, E)。另外,如果List的大小是可变的,还要覆盖add(int, E)和remove()方法.

2.构造器 ArrayList提供了三个构造器:

?
1
2
3
ArrayList()
ArrayList(Collection<? extends E> c)
ArrayList( int initialCapacity)

Collection接口约定,每个集合类应该提供两个”标准”构造器,一个是无参数的构造器(上面第一个),另外一个是拥有单个参数(类型为Collettion)的构造器(上面第二个)。ArrayList还提供了第三个构造器,其接受一个int值,用于设置ArrayLi的初始大小(默认大小为10).

3.相关方法 。

?
1
2
3
4
5
6
7
8
trimToSize
public void trimToSize() {
     modCount++;
     int oldCapacity = elementData.length;
     if (size < oldCapacity) {
       elementData = Arrays.copyOf(elementData, size);
     }
   }

用于把ArrayList的容量缩减到当前实际大小,减少存储容量。其中的变量modCount由AbstracList继承而来,记录List发生结构化修改(structurally modified)的次数。elementData中实际存储了ArrayList的元素,在ArrayList中声明为:private transient Object[] elementData;变量size是ArrayList的元素数量,当size < oldCapacity时,调用Arrays.copyOf方法实现缩减.

4.indexOf 和 lasIndexOf 。

?
1
2
3
4
5
6
7
8
9
10
11
12
public int indexOf(Object o) {
     if (o == null ) {
       for ( int i = 0 ; i < size; i++)
         if (elementData[i]== null )
           return i;
     } else {
       for ( int i = 0 ; i < size; i++)
         if (o.equals(elementData[i]))
           return i;
     }
     return - 1 ;
   }

这两个方法返回指定元素的下标,要区分参数是否为null。lastIndexOf和indexOf类似,只不过是从后往前搜索.

5.ensureCapacity 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public void ensureCapacity( int minCapacity) {
     if (minCapacity > 0 )
       ensureCapacityInternal(minCapacity);
   }
private void ensureCapacityInternal( int minCapacity) {
     modCount++;
     // overflow-conscious code
     if (minCapacity - elementData.length > 0 )
       grow(minCapacity);
   }
private void grow( int minCapacity) {
     // overflow-conscious code
     int oldCapacity = elementData.length;
     int newCapacity = oldCapacity + (oldCapacity >> 1 );
     if (newCapacity - minCapacity < 0 )
       newCapacity = minCapacity;
     if (newCapacity - MAX_ARRAY_SIZE > 0 )
       newCapacity = hugeCapacity(minCapacity);
     // minCapacity is usually close to size, so this is a win:
     elementData = Arrays.copyOf(elementData, newCapacity);
   }

这个方法可以确保ArrayList的大小 。

6.add 和 addAll 。

?
1
2
3
4
5
6
7
8
9
public void add( int index, E element) {
     rangeCheckForAdd(index);
 
     ensureCapacityInternal(size + 1 ); // Increments modCount!!
     System.arraycopy(elementData, index, elementData, index + 1 ,
              size - index);
     elementData[index] = element;
     size++;
   }

add(int index, E element)向指定位置添加元素,首先调用rangeCheckForAdd检查index是否有效,如果index > size || index < 0将抛出异常。然后确保容量加1,调用System.arraycopy把从index开始的元素往后移动一个位置。最后把index处的值设置为添加的元素。还有一个重载的add(E e)方法是直接把元素添加到末尾。 addAll(Collection<? extends E> c)和addAll(int index, Collection<? extends E> c)则分别是向末尾和指定位置添加Collection中的所有元素.

7.remove 和 removeAll 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public boolean remove(Object o) {
     if (o == null ) {
       for ( int index = 0 ; index < size; index++)
         if (elementData[index] == null ) {
           fastRemove(index);
           return true ;
         }
     } else {
       for ( int index = 0 ; index < size; index++)
         if (o.equals(elementData[index])) {
           fastRemove(index);
           return true ;
         }
     }
     return false ;
   }

remove(Object o)方法删除指定的元素。首先是查找元素位置,然后调用fastRemove(index)删除,其代码如下:

?
1
2
3
4
5
6
7
8
9
private void fastRemove( int index) {
     modCount++;
     int numMoved = size - index - 1 ;
     if (numMoved > 0 )
       //把index+1往后的元素都往前移动一个位置
       System.arraycopy(elementData, index+ 1 , elementData, index,
                numMoved);
     elementData[--size] = null ; // Let gc do its work
   }

重载的remove(int index)方法用于删除指定位置的元素。removeRange(int fromIndex, int toIndex)用于删除指定位置之间的所有元素。 removeAll(Collection<?> c)和retainAll(Collection<?> c)代码如下:

?
1
2
3
4
5
6
7
8
public boolean removeAll(Collection<?> c) {
     Objects.requireNonNull(c);
     return batchRemove(c, false );
   }
public boolean retainAll(Collection<?> c) {
     Objects.requireNonNull(c);
     return batchRemove(c, true );
   }

它们都是通过调用batchRemove方法实现的,其代码如下:

?
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
private boolean batchRemove(Collection<?> c, boolean complement) {
     final Object[] elementData = this .elementData;
     int r = 0 , w = 0 ;
     boolean modified = false ;
     try {
       for (; r < size; r++)
         if (c.contains(elementData[r]) == complement)
           elementData[w++] = elementData[r];
     } finally {
       // Preserve behavioral compatibility with AbstractCollection,
       // even if c.contains() throws.
       if (r != size) {
         System.arraycopy(elementData, r,
                  elementData, w,
                  size - r);
         w += size - r;
       }
       if (w != size) {
         // clear to let GC do its work
         for ( int i = w; i < size; i++)
           elementData[i] = null ;
         modCount += size - w;
         size = w;
         modified = true ;
       }
     }
     return modified;
   }

这个方法有两个参数,第一个是操作的Collection,第二个是一个布尔值,通过设置为true或false来选择是removeAll还是retainAll。try里面的语句是把留下来的放在0到w之间,然后在finally中第二个if处理w之后的空间,第一个是在c.contains()抛出异常时执行.

最后此篇关于Java中ArrayList类的用法与源码完全解析的文章就讲到这里了,如果你想了解更多关于Java中ArrayList类的用法与源码完全解析的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com