数据结构--线性表-ArraryList底层实现. no 4.

List.jar

package com.st.datastructure.lineable;

/**
 *线性表结构 
 *与储存结构无关
 * @author God's Night Is Not Ended
 */
public interface List {
	//返回线性表的大小,即数据元素的个数
	public int size();
	
	//返回线性表中序号为i的数据元素
	public Object get(int i);
	
	//如果线性表为空返回true,否则返回false
	public boolean isEmpty();
	
	//判断线性表是否包含数据元素e
	public boolean contains(Object e);
	
	//返回数据元素e在线性表中的序号
	public int indexof(Object e);
	
	//将数据元素e 插入到线性表中i号位置
	public void add(int i,Object e);
	
	//将数据元素e插入到线性表末尾
	public void add(Object e);
	
	//将数据元素e插入到元素obj之前
	public boolean addBefore(Object obj,Object e);
	
	//将数据元素e插入到元素obj之后
	public boolean addAfter(Object obj,Object e);
	
	//删除线性表中序号为i的元素,并返回
	public Object remove(int i);
	
	//删除线性表中第一个与e相同的元素
	public boolean remove(Object e);
	
	//替换线性表中序号为i的数据元素为e,返回数据元素
	public Object replace(int i,Object e);
	
	
		

}

ArrayList.jar

package com.st.datastructure.lineable;

/**
 * 
 *顺序表
 *底层采用数组,但是长度可以变化
 * @author God's Night Is Not Ended
 */
public class ArrayList implements List {
	private Object[] elementData;//是一个数组,还没有确定长度
	private int size;//不是分配了几个空间,而是元素的个数
	public ArrayList() {
		//没有指定长度,默认长度是4
		this(4);
		//没有指定长度。长度是0
		//elementData=new Object[] {};
	}
	
	public ArrayList(int initialCapacity) {
		elementData=new Object[initialCapacity];
		//指定顺序表的元素个数,默认是0
		size=0;
	}

	@Override
	public int size() {
		// 直接返回长度
		return size;
	}

	@Override
	public Object get(int i) {
		//判断是否有类似于数组下标越界 如果有抛出异常.
		if(i<0 || i>=size) {
			//throw new RuntimeException("数组索引越界异常"+i);
			throw new MyArrayIndexOutOfBoundsException("数组索引越界异常"+i);
		}
		
		// 获取第几个元素
		return elementData[i];
	}

	@Override
	public boolean isEmpty() {
		// 判断元素是否为空
		return size==0;
	}

	@Override
	public boolean contains(Object e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public int indexof(Object e) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void add(int i, Object e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void add(Object e) {
		//给数组第一个元素赋值
		elementData[size]=e;
		//依次赋值
		size++;
	}

	@Override
	public boolean addBefore(Object obj, Object e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean addAfter(Object obj, Object e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Object remove(int i) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean remove(Object e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Object replace(int i, Object e) {
		// TODO Auto-generated method stub
		return null;
	}

}

自定义异常

package com.st.datastructure.lineable;

public class MyArrayIndexOutOfBoundsException extends RuntimeException {

	public MyArrayIndexOutOfBoundsException() {
		super();
		// TODO Auto-generated constructor stub
	}

	public MyArrayIndexOutOfBoundsException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

}

Test.jar

package com.st.datastructure.lineable;

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		List list=new ArrayList();
		list.add(233);
		list.add(3333);
		list.add(4445);
		System.out.print(list.size());
		System.out.print(list.isEmpty());
		System.out.print(list.get(8));

	}

}

接下来现实动态扩容:

添加分配元素原理:
在这里插入图片描述
动态扩容原理:

在这里插入图片描述

	public void add(Object e) {
		//判断数组是否满
		if(size==elementData.length) {
//			//如果满 创建一个新的构造数组长度是原来的2倍
//		 Object newArr[]=new Object[elementData.length*2];
//		 //将旧数组拷贝到新数组
//		 for(int i=0;i<size;i++) {
//			 newArr[i]=elementData[i];
//			 //让elementData指向newArr
//			 elementData=newArr;
//		 }
//省略上文 可以调用封装函数 一条语句完成
		elementData=Arrays.copyOf(elementData, elementData.length*2);
		 
		}
		//给数组第一个元素赋值
		elementData[size]=e;
		//依次赋值
		size++;
		
		
		System.out.println("length是:"+elementData.length);
	}

在这里插入图片描述

抽取公共方法:

private void grow() {
		elementData=Arrays.copyOf(elementData, elementData.length*2);
	}

插入元素:

		//在第几个元素添加
	@Override
	public void add(int i, Object e) {
		// TODO Auto-generated method stub
		if(size==elementData.length) {
			grow();
		}
		
		//后移i及其后面元素,从最后一个元素开始
		for(int j=size;j>i;j--) {
			elementData[j]=elementData[j-1];
		}
		//给数组第i个元素赋值
		elementData[i]=e;
		//依次赋值
		size++;

	}

在这里插入图片描述

在这里插入图片描述

把list toString输出控制台:

//toString格式:[   ,    ,]
	@Override
	public String toString() {
		if(size==0) {
			return "[]";
		}
			StringBuilder stb=new StringBuilder("[");
			for(int i=0;i<size;i++) {
				if(i!=size-1) {
					stb.append(elementData[i]+",");
				}else {
					stb.append(elementData[i]);
				}
			
			}
			stb.append("]");
			return stb.toString();
	
	}
	System.out.println(list.toString());

在这里插入图片描述

添加元素到最后一个改造并且在指定位置做判断 是否小于0和大于size:

public void add(Object e) {
		this.add(size, e);
		System.out.println("length是:"+elementData.length);
	}
public void add(int i, Object e) {
		
		if(i<0 || i>size) {
			throw new MyArrayIndexOutOfBoundsException("数组下标越界异常"+i);
			
		}
		// TODO Auto-generated method stub
		if(size==elementData.length) {
			grow();
		}
		
		//后移i及其后面元素,从最后一个元素开始
		for(int j=size;j>i;j--) {
			elementData[j]=elementData[j-1];
		}
		//给数组第i个元素赋值
		elementData[i]=e;
		//依次赋值
		size++;

	}

在这里插入图片描述

在这里插入图片描述

完整代码:

重点是:数组的扩容 数组的后移。

List.java

package com.st.datastructure.lineable;

/**
 *线性表结构 
 *与储存结构无关
 * @author God's Night Is Not Ended
 */
public interface List {
	//返回线性表的大小,即数据元素的个数
	public int size();
	
	//返回线性表中序号为i的数据元素
	public Object get(int i);
	
	//如果线性表为空返回true,否则返回false
	public boolean isEmpty();
	
	//判断线性表是否包含数据元素e
	public boolean contains(Object e);
	
	//返回数据元素e在线性表中的序号
	public int indexof(Object e);
	
	//将数据元素e 插入到线性表中i号位置
	public void add(int i,Object e);
	
	//将数据元素e插入到线性表末尾
	public void add(Object e);
	
	//将数据元素e插入到元素obj之前
	public boolean addBefore(Object obj,Object e);
	
	//将数据元素e插入到元素obj之后
	public boolean addAfter(Object obj,Object e);
	
	//删除线性表中序号为i的元素,并返回
	public Object remove(int i);
	
	//删除线性表中第一个与e相同的元素
	public boolean remove(Object e);
	
	//替换线性表中序号为i的数据元素为e,返回数据元素
	public Object replace(int i,Object e);
	
	
		

}

ArrayList.java

package com.st.datastructure.lineable;

import java.util.Arrays;

/**
 * 
 *顺序表
 *底层采用数组,但是长度可以变化
 * @author God's Night Is Not Ended
 */
public class ArrayList implements List {
	private Object[] elementData;//是一个数组,还没有确定长度
	private int size;//不是分配了几个空间,而是元素的个数
	public ArrayList() {
		//没有指定长度,默认长度是4
		this(4);
		//没有指定长度。长度是0
		//elementData=new Object[] {};
	}
	/**
	 * 数组的初始长度
	 * @param initialCapacity
	 */
	public ArrayList(int initialCapacity) {
		elementData=new Object[initialCapacity];
		//指定顺序表的元素个数,默认是0
	//	size=0;
	}

	@Override
	public int size() {
		// 直接返回长度
		return size;
	}

	@Override
	public Object get(int i) {
		//判断是否有类似于数组下标越界 如果有抛出异常.
		if(i<0 || i>=size) {
			//throw new RuntimeException("数组索引越界异常"+i);
			throw new MyArrayIndexOutOfBoundsException("数组索引越界异常"+i);
		}
		
		// 获取第几个元素
		return elementData[i];
	}

	@Override
	public boolean isEmpty() {
		// 判断元素是否为空
		return size==0;
	}

	@Override
	public boolean contains(Object e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public int indexof(Object e) {
		// TODO Auto-generated method stub
		return 0;
	}

	//在第几个元素添加
	@Override
	public void add(int i, Object e) {
		
		if(i<0 || i>size) {
			throw new MyArrayIndexOutOfBoundsException("数组下标越界异常"+i);
			
		}
		// TODO Auto-generated method stub
		if(size==elementData.length) {
			grow();
		}
		
		//后移i及其后面元素,从最后一个元素开始
		for(int j=size;j>i;j--) {
			elementData[j]=elementData[j-1];
		}
		//给数组第i个元素赋值
		elementData[i]=e;
		//依次赋值
		size++;

	}

	@Override
	public void add(Object e) {
		this.add(size, e);
//		//判断数组是否满
//		if(size==elementData.length) {
			//如果满 创建一个新的构造数组长度是原来的2倍
		 Object newArr[]=new Object[elementData.length*2];
		 //将旧数组拷贝到新数组
		 for(int i=0;i<size;i++) {
			 newArr[i]=elementData[i];
			 //让elementData指向newArr
			 elementData=newArr;
		 }
//		grow();
//		 
//		}
//		//给数组第一个元素赋值
//		elementData[size]=e;
//		//依次赋值
//		size++;
		
		
		System.out.println("length是:"+elementData.length);
	}
	private void grow() {
		elementData=Arrays.copyOf(elementData, elementData.length*2);
	}

	@Override
	public boolean addBefore(Object obj, Object e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean addAfter(Object obj, Object e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Object remove(int i) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean remove(Object e) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Object replace(int i, Object e) {
		// TODO Auto-generated method stub
		return null;
	}
	//toString格式:[   ,    ,]
	@Override
	public String toString() {
		if(size==0) {
			return "[]";
		}
			StringBuilder stb=new StringBuilder("[");
			for(int i=0;i<size;i++) {
				if(i!=size-1) {
					stb.append(elementData[i]+",");
				}else {
					stb.append(elementData[i]);
				}
			
			}
			stb.append("]");
			return stb.toString();
	
	}

}

MyArrayIndexOutOfBoundsException.java

package com.st.datastructure.lineable;

public class MyArrayIndexOutOfBoundsException extends RuntimeException {

	public MyArrayIndexOutOfBoundsException() {
		super();
		// TODO Auto-generated constructor stub
	}

	public MyArrayIndexOutOfBoundsException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}

}

Test.java

package com.st.datastructure.lineable;

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		List list=new ArrayList();
		list.add(233);
		list.add(3333);
		list.add(4445);
		list.add(4555);
		
		list.add(4445);
		list.add(4555);
	
		list.add(-5, 522);
		System.out.print(list.size());
		System.out.print(list.isEmpty());
		System.out.print(list.get(3));
		System.out.println(list.toString());
		
	

	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值