关于ArrayList的5道面试题

1、ArrayList的大小是如何自动增加的?你能分享一下你的代码吗?

这是最有技巧性的的一个问题,大多数人都无法回答。事实上,当有人试图在arraylist中增加一个对象的时候,Java会去检查arraylist,以确保已存在的数组中有足够的容量来存储这个新的对象。如果没有足够容量的话,那么就会新建一个长度更长的数组,旧的数组就会使用Arrays.copyOf方法被复制到新的数组中去,现有的数组引用指向了新的数组。看如下的代码段:

[html]  view plain  copy
  1. //ArrayList Add方法:  
  2. public boolean add(E e){  
  3.     ensureCapacity(size+1); //Increment modCount!!  
  4.     elementData[size++] = e;  
  5.     return true;  
  6. }  
  7.    
  8. //ensureCapacity方法:处理ArrayList的大小  
  9. public void ensureCapacity(int minCapacity) {  
  10.     modCount++;  
  11.     int oldCapacity = elementData.length;  
  12.     if (minCapacity > oldCapacity) {  
  13.     Object oldData[] = elementData;  
  14.     int newCapacity = (oldCapacity * 3)/2 + 1;  
  15.     if (newCapacity < minCapacity)  
  16.         newCapacity = minCapacity;  
  17.     // minCapacity is usually close to size, so this is a win:  
  18.     elementData = Arrays.copyOf(elementData, newCapacity);  
  19.     }  
  20. }  
请注意这样一个情况:新建了一个数组;旧数组的对象被复制到了新的数组中,并且现有的数组指向新的数组。


2、什么情况下你会使用ArrayList?什么时候你会选择LinkedList?

这又是一个大多数面试者都会困惑的问题。多数情况下,当你遇到访问元素比插入或者是删除元素更加频繁的时候,你应该使用ArrayList。另外一方面,当你在某个特别的索引中,插入或者是删除元素更加频繁,或者你压根就不需要访问元素的时候,你会选择LinkedList。这里的主要原因是,在ArrayList中访问元素的最糟糕的时间复杂度是”1″,而在LinkedList中可能就是”n”了。在ArrayList中增加或者删除某个元素,通常会调用System.arraycopy方法,这是一种极为消耗资源的操作,因此,在频繁的插入或者是删除元素的情况下,LinkedList的性能会更加好一点。

3、当传递ArrayList到某个方法中,或者某个方法返回ArrayList,什么时候要考虑安全隐患?如何修复安全违规这个问题呢?

当array被当做参数传递到某个方法中,如果array在没有被复制的情况下直接被分配给了成员变量,那么就可能发生这种情况,即当原始的数组被调用的方法改变的时候,传递到这个方法中的数组也会改变。下面的这段代码展示的就是安全违规以及如何修复这个问题。

ArrayList被直接赋给成员变量——安全隐患:

[html]  view plain  copy
  1. public void setMyArray(String[] myArray){  
  2.   
  3. <span style="white-space:pre">    </span>this.myArray=myArray;  
  4.   
  5. }  

修复这个安全隐患:

[html]  view plain  copy
  1. public void setMyArray(String[] newMyArray){  
[html]  view plain  copy
  1. <span style="white-space:pre">    </span>if(newMyArray == null){  
[html]  view plain  copy
  1. <span style="white-space:pre">        </span>this.<span style="font-family: 'Microsoft YaHei', 宋体, 'Myriad Pro', Lato, 'Helvetica Neue', Helvetica, Arial, sans-serif;">myArray = new String[0];</span>  
[html]  view plain  copy
  1. <span style="font-family:Microsoft YaHei, 宋体, Myriad Pro, Lato, Helvetica Neue, Helvetica, Arial, sans-serif;"><span style="white-space:pre">   </span>}else{</span>  
[html]  view plain  copy
  1. <span style="font-family:Microsoft YaHei, 宋体, Myriad Pro, Lato, Helvetica Neue, Helvetica, Arial, sans-serif;"><span style="white-space:pre">       </span>this.</span><span style="font-family: 'Microsoft YaHei', 宋体, 'Myriad Pro', Lato, 'Helvetica Neue', Helvetica, Arial, sans-serif;">myArray = Arrays.copyOf(newMyArray,newMyArray.length);</span>  
[html]  view plain  copy
  1. <span style="font-family:Microsoft YaHei, 宋体, Myriad Pro, Lato, Helvetica Neue, Helvetica, Arial, sans-serif;"><span style="white-space:pre">   </span>}</span><span style="font-family:Microsoft YaHei, 宋体, Myriad Pro, Lato, Helvetica Neue, Helvetica, Arial, sans-serif;">  
  2. }</span>  

4、如何复制某个ArrayList到另一个ArrayList中去?写出你的代码?

下面就是把某个ArrayList复制到另一个ArrayList中去的几种技术:

  1. 使用clone()方法,比如ArrayList newArray = oldArray.clone();
  2. 使用ArrayList构造方法,比如:ArrayList myObject = new ArrayList(myTempObject);
  3. 使用Collection的copy方法。

注意1和2是浅拷贝(shallow copy)。

5、在索引中ArrayList的增加或者删除某个对象的运行过程?效率很低吗?解释一下为什么?

在ArrayList中增加或者是删除元素,要调用System.arraycopy这种效率很低的操作,如果遇到了需要频繁插入或者是删除的时候,你可以选择其他的Java集合,比如LinkedList。看一下下面的代码:

在ArrayList的某个索引i处添加元素:

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

删除ArrayList的某个索引i处的元素:

[html]  view plain  copy
  1. public E remove(int index) {  
  2.         rangeCheck(index);  
  3.   
  4.         modCount++;  
  5.         E oldValue = elementData(index);  
  6.   
  7.         int numMoved = size - index - 1;  
  8.         if (numMoved > 0)  
  9.             System.arraycopy(elementData, index+1, elementData, index,  
  10.                              numMoved);  
  11.         elementData[--size] = null; // clear to let GC do its work  
  12.   
  13.         return oldValue;  
  14.     }  




版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liuhuanchao/article/details/51303686





猜你喜欢

转载自blog.csdn.net/varyall/article/details/80470416