自己寫一個簡單的ArrayList
阿新 • • 發佈:2019-01-03
自己通過寫一個簡單的SimpleArrayList來加深對JDK原始碼中的ArrayList的理解。
- 構造器
如果沒有對集合設定長度,這裡我們預設採取長度為10作為內建陣列的初始化長度。
public SimpleArrayList() {
this(DEFAULT_SIZE);
}
public SimpleArrayList(int size) {
target = new Object[size];
}
- 向集合中新增元素add(E)
這裡用到了Arrays類的copyof。如果長度超過我們設定的長度。陣列中的元素複製到新陣列。新陣列長度為原陣列的2倍。(當然這裡可以自定義設定擴容比例)
由於陣列長度設定不能大於int的長度即java.lang.Integer.MAX_VALUE = 2^31-1 = 2147483647(實際上虛擬機器記憶體不一定支援理論上的最大值),這裡沒有加上這個校驗,真實的程式是有這個校驗的。
public void add(E e){
if(this.size < DEFAULT_SIZE){
//小於預設尺寸10
target[size++] = e;
}else{
//大於10的時候需要擴容,
//copyOf複製指定的陣列到新陣列,第一個引數為原陣列,第二個引數為新陣列長度
target = Arrays.copyOf(target, size*2);
target[size++] = e;
}
}
- 根據下標獲取元素get(index)
public E get(int index){
return (E)target[index];
}
- 返回集合長度size()方法
public int size(){
return this.size;
}
- 判斷元素是否在集合 indexOf(Object)
public int indexOf(Object obj){
if(obj==null){
for(int i=0;i<target.length;i++){
if (target[i]==null){
return i;
}
}
}else{
for(int i=0;i<target.length;i++){
if(obj.equals(target[i])){
return i;
}
}
}
return -1;
}
- 根據下標移除集合中的元素remove(index)
System.arraycopy(被複制的陣列,被複制位置,目標陣列,目標陣列位置,被複制陣列的結束到開始的長度)
target將index+1到最後的所有資料,複製到target的排除e元素即index位置到最後的位置。
這樣的陣列長度還是沒有變化的,所以,–size,讓集合長度減一,而溢位的這個元素,等待GC回收
public E remove(int index){
E e =get(index);
System.arraycopy(target, index+1, target, index, size-index-1);
target[--size] = null;
return e;
}
- 根據元素移除集合中和該元素相同的元素remove(Object)
public boolean remove(Object o){
if(o==null){
for(int i=0;i<target.length;i++){
if(target[i]==null){
remove(i);
return true;
}
}
}else{
for(int i=0;i<target.length;i++){
if(o.equals(target[i])){
remove(i);
return true;
}
}
}
return false;
}
- 清空集合(clear)
public void clear(){
for(int i=0;i<target.length;i++){
target[i] =null;
}
size = 0;
}
最後附上全部的原始碼,有什麼不對的地方,請指出。
/**
* 模擬ArrayList
* 1,實現方法,get(int),add(E),add(int,E),size(),remove(int),remove(Object),indexOf(Object)
* 2,ArrayList本質上是動態陣列
* 3,巧用System.arraycopy和Arrays.copyof來實現元素的新增和刪除
*
*/
public class SimpleArrayList<E> {
private final static int DEFAULT_SIZE = 10;
private int size;
private Object[] target;
public SimpleArrayList() {
this(DEFAULT_SIZE);
}
public SimpleArrayList(int size) {
target = new Object[size];
}
/**
* 向集合中新增元素
* @param e 元素
*/
public void add(E e){
if(this.size < DEFAULT_SIZE){
//小於預設尺寸10
target[size++] = e;
}else{
//大於10的時候需要擴容,
//copyOf複製指定的陣列到新陣列,第一個引數為原陣列,第二個引數為新陣列長度
target = Arrays.copyOf(target, size*2);
target[size++] = e;
}
}
/**
* 根據下標獲取集合中的元素
* @param index 下標
* @return
*/
public E get(int index){
return (E)target[index];
}
/**
* 返回集合長度
* @return
*/
public int size(){
return this.size;
}
/**
* 判斷元素是否存在集合中
* 存在返回下標
* 不存在返回-1
* @param obj
* @return
*/
public int indexOf(Object obj){
if(obj==null){
for(int i=0;i<target.length;i++){
if(target[i]==null){
return i;
}
}
}else{
for(int i=0;i<target.length;i++){
if(obj.equals(target[i])){
return i;
}
}
}
return -1;
}
/**
* 根據下標移出集合中的元素
* @param index 下標
* @return
*/
public E remove(int index){
E e =get(index);
/**
* System.arraycopy(被複制的陣列,被複制位置,目標陣列,目標陣列位置,被複制陣列的結束到開始的長度)
*
* target將index+1到最後的所有資料,複製到target的排除e元素即index位置到最後的位置。
*
* 這樣的陣列長度還是沒有變化的,所以,--size,讓集合長度減一,而溢位的這個元素,等待GC回收
*/
System.arraycopy(target, index+1, target, index, size-index-1);
target[--size] = null;
return e;
}
/**
* 根據移除集合中的元素
* 移除成功返回true,反之false
* @param o 元素
* @return
*/
public boolean remove(Object o){
if(o==null){
for(int i=0;i<target.length;i++){
if(target[i]==null){
remove(i);
return true;
}
}
}else{
for(int i=0;i<target.length;i++){
if(o.equals(target[i])){
remove(i);
return true;
}
}
}
return false;
}
/**
* 清空集合
*/
public void clear(){
for(int i=0;i<target.length;i++){
target[i] =null;
}
size = 0;
}
}