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());
}
}