Android编程之ArrayList源码详解及使用

来源:互联网 发布:如何入侵centos系统 编辑:程序博客网 时间:2024/05/22 08:20

ArrayList 本是 java中的代码,放到android这边显得不太合适,但由于它在android开发中又大量应用,所以就放到这里,供大家学习。

相信大家对ArrayList不陌生,但要说到细节的方面,可能就有点含糊其辞了。下面就来说几个日常使用中的几个例子:

List和ArrayList区别:

List是接口  定义了一些方法 但是方法没有被实现 ArrayList是一个类 实现了List这个接口 List里边定义的方法 在ArrayList里边都实现了 同时List也可以被别的类所实现 例如Vector,  Vector和ArrayList对List定义的方法的实现就有所区别。

1、判断ArrayList是否有值:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. if (mList.size() != 0){  
  2.     // do something  
  3. }  
上面这个写法,是最常见的。但你知道吗,ArrayList中其实是有个isEmpty()方法的,源码如下:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. public boolean isEmpty() {  
  2.     return size == 0;  
  3. }  
所以,判断ArrayList是否有值的写法应改为:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. if (!mList.isEmpty()){  
  2.     // do something  
  3. }  

补充一点:最好再增加一个mList是否为空的判断,让代码的严谨性更好。


2、ArrayList 的add(E e)方法,可以传入null的值吗?

看了下面它的源码,就有答案了:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. public boolean add(E e) {  
  2.     ensureCapacity(size + 1);  // Increments modCount!!  
  3.     elementData[size++] = e;  
  4.     return true;  
  5. }  
所以,答案是肯定的,可以传入null。

补充一点:虽然ArrayList 是可以传入null的,但在实际应用中,这么做没有什么意义。所以,在调用add方法前,最好还是判断一下传入的值是否为空。


3、ArrayList的get(int index)方法,会返回null吗?

看一下它的源码:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. public E get(int index) {  
  2.     RangeCheck(index);  
  3.     return (E) elementData[index];  
  4. }  
这个的回答,还要看代码是如何写的。如果之前add的时候添加了null进去,那么这里就会有可能返回null。

很多人会这样写代码:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. for (int i = 0; i < mList.size(); i++) {  
  2.   mList.get(i).xxx();  
  3. }  
如果能确定ArrayList中确实没有null值的话,这么写没问题。但如果确定不了的话,还是增加一个是否为空的判断吧,避免空指针异常。


4、ArrayList的remove(Object o)方法,出入null时,会空指针异常吗?

实际应用当中,我相信没人会直接传个null进去。多数应用场景是,获取了一个对象,在不知道其是否为null的情况下,想要移除掉它。

看一下它的源码:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. public boolean remove(Object o) {  
  2.     if (o == null) {  
  3.         for (int index = 0; index < size; index++)  
  4.             if (elementData[index] == null) {  
  5.                 fastRemove(index);  
  6.                 return true;  
  7.             }  
  8.     } else {  
  9.         for (int index = 0; index < size; index++)  
  10.         if (o.equals(elementData[index])) {  
  11.             fastRemove(index);  
  12.             return true;  
  13.         }  
  14.     }  
  15.     return false;  
  16. }  
所以,传入为null的值的话,如果我们之前调用add方法时,传入过null值,那么这里就会移除掉它。


5、ArrayList的remove(Object o)方法传入未添加的值,会报异常吗?

如果我们传入的值,之前没有add过,也只是返回false,并不会报什么异常。原因就在上面那段代码里。

而在实际代码中,有些人在调用remove方法时,会这么写:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. if(mList.contain(object)){  
  2.     mList.remove(object);  
  3. }  
所以,这么看来,remove方法前再调用contain,就没什么意义了。我们可以通过判断其返回值,来获得其是否有这个值,也就是是否删除成功。


6、ArrayList可以重复添加相同的值吗?

这个问题其实比较基础了,但实际写代码中,还会有很多人在这块犯错误,认为相同对象只能添加一次。

这里直接给出答案:相同的对象是可以重复添加进去的。原因可以从上面add方法了解到。

补充一点:可以添加多个相同对象,但remove的时候,可不会一次全部都删掉,而是按添加顺序删除。调一次,删除一个!这一点,初学java的同学要特别注意了!


7、ArrayList中的Object[ ] toArray() 与 <T> T[ ] toArray(T[ ] a) 方法

在实际应用场景中,会需要将ArrayList转换成数组的形式。我见过有些人会用for循环的方法,一个个将ArrayList取出来,再赋值给数组的。没那么麻烦,用toArray这个方法即可。但ArrayList会有两个同名方法,该用哪一个呢?还是先看源码吧:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. public Object[] toArray() {  
  2.     return Arrays.copyOf(elementData, size);  
  3. }  
  4.   
  5. public <T> T[] toArray(T[] a) {  
  6.     if (a.length < size)  
  7.         // Make a new array of a's runtime type, but my contents:  
  8.         return (T[]) Arrays.copyOf(elementData, size, a.getClass());  
  9.     System.arraycopy(elementData, 0, a, 0, size);  
  10.     if (a.length > size)  
  11.         a[size] = null;  
  12.     return a;  
  13. }  
直接调用toArray()这个方法,会直接返回一个数组,源码是返回Object类型的。所以,你需要自己手动泛型一下。

说起这个泛型,还真得唠叨一句,不知道有多少人会这么写:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. ArrayList<String> mList = new ArrayList<String>();  
  2. ......  
  3. String[] s = (String[]) mList.toArray();  
如果有哪位同学这么写运行不报错的话,给我留个言。


继续。下面那个toArray(T[] a),就显得稍微复杂了一些。如果T[]的大小比ArrayList要小的话,则只会返回与T[]大小相等的数组。

注意,如果传入的数组与ArrayList的大小不相等,则会将ArrayList的size那位赋值为null。

这里给个最简单的测试例子:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. ArrayList<String> mList = new ArrayList<String>();  
  2.   
  3. mList.add("a");  
  4. mList.add("b");  
  5.   
  6. String[] s = new String[4];  
  7. s[2] = "c";  
  8. s[3] = "d";  
  9.           
  10. for (String string: s) {  
  11.     System.out.println(string);  
  12. }  
  13.           
  14. s = mList.toArray(s);  
  15. for (String string : s) {  
  16.     System.out.println(string);  
  17. }  
第一个for循环输出内容为:

null
null
c
d

因为我没有对String数组第一个和第二个赋值,所以自然为输出内容为null。


第二个for循环输出内容为:

a
b
null
d

可以看到,String数组的第三个值被赋值为null。


所以,在使用toArray(T[] a)要特别留心这个问题。当然,如果对第一个toArray()使用觉得麻烦的话,可以创建一个与ArrayList大小一样的数组,调用toArray(T[] a)传参进去,就可以直接得到了:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. ArrayList<String> mList = new ArrayList<String>();  
  2. ......  
  3. String[] s = new String[mList.size()];  
  4. s = mList.toArray(s);  


以上,就是总结了ArrayList在实际使用中的一些细节知识点,希望对大家能有所帮助。

0 0