用JAVA实现一个List
数据结构常见的几种类型
数据结构的逻辑结构:数据对象中数据元素之间的相互关系,分为集合结构,线性结构、树形结构和图形结构。
数据结构的物理结构:数据的逻辑结构在计算机中的存储形式,分为顺序存储和链式存储(比如链表)(不连续存储)。
⑴集合结构
该结构的数据元素间的关系是“属于同一个集合”。既多个元素属于一个集合,有三个特性:
1).确定性(集合中的元素必须是确定的)
2).互异性(集合中的元素互不相同。例如:集合A={1,a},则a不能等于1)
3).无序性(集合中的元素没有先后之分),如集合{3,4,5}和{3,5,4}算作同一个集合。
⑵线性结构
该结构的数据元素之间存在着一对一的关系。
常用的线性结构有:线性表,栈,队列,双队列,数组,串。
⑶树型结构
该结构的数据元素之间存在着一对多的关系。
一颗树可以简单的表示为根节点, 左子树, 右子树。 左子树和右子树又有自己的子树,子树上面有节点。
⑷图形结构
该结构的数据元素之间存在着多对多的关系,也称网状结构。
图形结构,简称“图”,是一种复杂的数据结构。图形结构中,每个结点的前驱结点数和后续结点数可以任意多个。
现在需要自己实现一个线性的类似数组的结构,初始化size,length等信息,添加增删查改,自动扩容等功能,根据不同的需求实现不同的线性存储结构在使用时非常方便。
二、代码实现
1.创建MyList接口
创建一个interface接口类型,将想要实现的功能名称写进接口内,后续在MyList类中实现这些方法。
代码如下:
public interface MyListInterface<E> {
public void growArry(); //扩容
public void add(E value); //末尾插入
public void deletebyelement(E value); // 根据输入的值,删除元素
public void deletebyindex(int index); // 根据下标删除元素,删除第几个元素
public void changebyelement(E oldvalue,E newValue);
public void changebyindex(int index,E newValue); //下标index 改为newValue
public MyList findbyelement(E value); //根据值查找元素
public Object findbyindex(int index); // 根据index,查找第几个元素
public MyList findelement(E value);//查找元素
}
这些只是暂时想到的方法,后面会继续扩展其他的方法。
2.实现MyList类
创建一个类叫做MyList,定义属性并实现接口中的方法。
泛型
在这之前插入一个泛型的概念:泛型,用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数进行传递。
定义格式:
修饰符 class 类名<代表泛型的变量> { }
例:
class ArrayList<E>{
public boolean add(E e){ }
public E get(int index){ }
....
}
使用泛型: 即什么时候确定泛型。
在创建对象的时候确定泛型
例如,ArrayList<String> list = new ArrayList<String>();
此时,变量E的值就是String类型,那么我们的类型就可以理解为:
class ArrayList<String>{
public boolean add(String e){ }
public String get(int index){ }
...
}
再例如,ArrayList<Integer> list = new ArrayList<Integer>();
此时,变量E的值就是Integer类型,那么我们的类型就可以理解为:
class ArrayList<Integer> {
public boolean add(Integer e) { }
public Integer get(int index) { }
...
}
举例自定义泛型类
public class MyGenericClass<E> {
//没有E类型,在这里代表 未知的一种数据类型 未来传递什么就是什么类型
private E e;
public void setMVP(E e) {
this.e = e;
}
public E getE() {
return e;
}
}
含有泛型的方法
定义格式:
修饰符 <代表泛型的变量> 返回值类型 方法名(参数){ }
例如,
public class MyGenericMethod {
public <MVP> void show(MVP mvp) {
System.out.println(mvp.getClass());
}
public <MVP> MVP show2(MVP mvp) {
return mvp;
}
}
使用格式:调用方法时,确定泛型的类型
public class GenericMethodDemo {
public static void main(String[] args) {
// 创建对象
MyGenericMethod mm = new MyGenericMethod();
// 演示看方法提示
mm.show("aaa");//泛型为string
mm.show(123);//泛型为int
mm.show(12.45);
}
}
含有泛型的接口
定义格式:
修饰符 interface接口名<代表泛型的变量> { }
例如,
public interface MyGenericInterface<E>{
public abstract void add(E e);
public abstract E getE();
}
使用格式:
创建不确定的格式
public class MyImp2<E> implements MyGenericInterface<E> {
@Override
public void add(E e) {
// 省略...
}
@Override
public E getE() {
return null;
}
}
确定泛型类型:
/*
* 使用
*/
public class GenericInterface {
public static void main(String[] args) {
MyImp2<String> my = new MyImp2<String>();
my.add("aa");//泛型为String
}
}
实现MyList
public class MyList<E> implements MyListInterface<E> {
// 属性 :
int length;
int size;// 个数: 从1开始计算 下标: 从0开始
// 存储结构 所有类的父类为数据类型
Object[] arrvalue;
// 默认长度
final int defaultlength = 10;
// 获取长度
public int getLength() {
return length;
}
// 返回 容器中元素个数
public int getSize() {
return size;
}
// 初始化
public MyList() {
initList();
}
// 默认初始化
private void initList() {
length = defaultlength;
arrvalue = new Object[length];
size = 0;
}
// 初始长度
public MyList(int initLength) {
if (initLength <= 0) {
System.err.println("输入长度小于0!");
}
if (initLength >= Integer.MAX_VALUE) {
System.out.println("输入长度大于上限!");
}
if (initLength <= defaultlength) {
initList();
}
if (initLength > defaultlength) {
length = initLength;
arrvalue = new Object[length];
size = 0;
}
}
public void growArry() {
// 扩容 创建一个新的数组 ,比原数组容量更大
int oldlength = length;
length = (oldlength / 2) + oldlength;
Object[] newArrvalue = new Object[length];
// 然后 将原数组中的所有数据 存入新数组中
for (int i = 0; i < arrvalue.length; i++) {
newArrvalue[i] = arrvalue[i];
}
// 引用替换
arrvalue = newArrvalue;
}
@Override
// 添加元素
public void add(E value) {
//size 当前越界了
if (size >= length) {
growArry();
}
arrvalue[size++] = value;
}
// 根据下标删除元素,删除第几个元素
public void deletebyindex(int index) {
//下标越界了
if (index > size) {
System.out.println("数组中元素个数为为:" + size + ",输入的位置没有元素,不可以删除!");
} else if (index <= 0) {
System.out.println("此功能为删除第几个元素,输入的值最小应该为1");
} else {
System.out.println("success");
for (int i = index; i < size; i++) {
Object temp = arrvalue[i];
arrvalue[i - 1] = temp;
}
arrvalue[size - 1] = null;
size--;
}
}
// 根据输入的值,删除元素
public void deletebyelement(E value) {
for (int i = 0; i < size; i++) {
if (arrvalue[i].equals(value)) {
deletebyindex(i + 1);
}
}
}
// 根据下标删除元素,查找第几个元素
public Object findbyindex(int index) {
Object result = null;
//下标越界了
if (index > size) {
System.out.println("数组中元素个数为为:" + size + ",输入的位置没有元素,不可以查找!");
} else if (index <= 0) {
System.out.println("此功能为查找第几个元素,输入的值最小应该为1");
} else {
System.out.println("success");
result = arrvalue[index - 1];
System.out.println("第" + index + "个元素是:" + result);
}
return result;
}
public MyList findelement(E value) {
MyList result = new MyList();
for (int i = 0; i < size; i++) {
if (arrvalue[i].equals(value)) {
result.add(i+1);
}
}
return result;
}
public MyList findbyelement(E value) {
MyList result = findelement(value);
if(result.arrvalue[0]==null){
System.out.println("List中没有元素"+value);
} else{
System.out.print("第");
for (int i = 0; i < result.size; i++) {
if (i == result.size - 1) {
System.out.print(result.arrvalue[i]);
} else {
System.out.print(result.arrvalue[i] + ",");
}
}
System.out.println("个元素是"+value);
}
return result;
}
public void changebyindex(int index,E newValue) {
//下标越界了
if (index > size) {
System.out.println("数组中元素个数为为:" + size + ",输入的位置没有元素,不可以修改!");
} else if (index <= 0) {
System.out.println("此功能为修改第几个元素,输入的值最小应该为1");
} else {
arrvalue[index - 1]=newValue;
System.out.println("成功将第"+index+"个元素修改为"+newValue);
}
}
public void changebyelement(E oldvalue,E newValue) {
MyList result = findelement(oldvalue);
if(result.arrvalue[0]==null){
System.out.println("List中没有元素"+oldvalue);
} else{
System.out.print("将第");
for (int i = 0; i < result.size; i++) {
arrvalue[(int)(result.arrvalue[i])-1]=newValue;
if (i == result.size - 1) {
System.out.print(result.arrvalue[i]);
} else {
System.out.print(result.arrvalue[i] + ",");
}
}
System.out.println("的元素"+oldvalue+"成功修改为元素"+newValue);
}
}
public static void main(String[] args) {
MyList myList = new MyList(12);
myList.add(2);
for (int i = 0; i < 6; i++) {
myList.add(i);
myList.add(2);
}
myList.add(2);
for (int i = 0; i < myList.size; i++) {
System.out.println(myList.arrvalue[i]);
}
myList.changebyelement(2,10);
for (int i = 0; i < myList.size; i++) {
System.out.println(myList.arrvalue[i]);
}
// System.out.println(a);
System.out.println(myList.getSize());
}
}
总结
在使用线性数据结构时可以自己写一个类,添加不同的方法功能可以更加的快捷方便的对数据进行处理。