您的位置:首页 > 编程语言 > Java开发

自己写一个简单的ArrayList

2017-09-27 15:42 423 查看
自己通过写一个简单的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;
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  arraylist 源码 java