自己实现基于数组的ArrayList的基本api
写一个自己的ArrayList
* 集合类 容器
*
* 1 里面提供了哪些操作? 参考List接口
*
* 2 里面有哪些数据? 成员变量 分析
*
* 3 构造方法;
接口List
import java.util.Iterator;
import java.util.ListIterator;
public interface List<E> {
boolean add(E e);
void add(int index,E e);
void remove(E e);
E remove(int index);
boolean contains(E e);
void clear();
E get(int index);
int indexof(E e);
int lastIndexof(E e);
void set(int index,E e);
int size();
boolean isEmpty();
ListIterator<E> iterator();
ListIterator<E> iterator(int index);
}
Test
package javahomework.day29;
import java.util.ListIterator;
public class Test {
public static void main(String[] args) {
MyList<String> ms = new MyList<>();
boolean empty = ms.isEmpty();
//System.out.println(empty);
ms.add("a");
ms.add("b");
ms.add("d");
ms.add("e");
ms.add("a");
System.out.println(ms.size);
//ms.remove(1);
System.out.println(ms);
ListIterator listIterator = ms.iterator();
while(listIterator.hasNext()){
Object next = listIterator.next();
if("a".equals(next)){
ms.remove(next);
//listIterator.add("java");
}
}
while(listIterator.hasPrevious()){
Object previous = listIterator.previous();
if("a".equals(previous)){
//listIterator.add("java");
}
}
System.out.println(ms);
}
}
MyList
package javahomework.day29;
import java.util.Arrays;
import java.util.ConcurrentModificationException;
import java.util.ListIterator;
import java.util.NoSuchElementException;
/*
* 写一个自己的ArrayList
*/
public class MyList<E> implements List<E> {
public Object[] element;//存储数据的数组
int size;//数据元素的个数
int modecount;//集合修改的次数
private static final int Defaultcapcity = 10; //默认分配的容量
private static final int Max_arry = Integer.MAX_VALUE-8;//最大数组容量
//无参构造,分配默认的容量Defaultcapcity
public MyList(){
element = new Object[Defaultcapcity];
}
//有参构造,分配指定容量
public MyList(int capcity) {
//判断参数是否合法
if(capcity<0||capcity>Max_arry){
throw new IllegalArgumentException("非法参数");
}
element = new Object[capcity];
}
/**
* toString方法 把集合元素输出
* @return 返回集合元素的字符串
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
if(size>0){
for(int i =0; i < size-1; i++){
sb.append(element[i]+" ");
}
sb.append(element[size-1]);
}
sb.append("]");
return sb.toString();
}
/**
* 在集合末尾增加一个元素
* @param o 任意指定类型
* @return 返回true添加成功
*/
@Override
public boolean add(Object o) {
add(size,o);
return true;
}
/**
* 在index位置添加元素
* @param index 集合的索引位置
* @param o 任意类型数据
*/
@Override
public void add(int index, Object o) {
checkIndex(index); //检查索引是否合法
int mincapcity = size+1; //要添加元素,那么最小容量至少为size+1
if(mincapcity>element.length){ //判断最小需要的容量与分配的容量的大小,决定是否需要扩容
int newcapcity = element.length+(element.length<<1); //新的容量一般为原容量的1.5倍
if(newcapcity<0||newcapcity>Max_arry){ //如果新的容量不符合容量的要求
newcapcity = Max_arry; //直接把新的容量设为容量最大值
}
if(mincapcity>newcapcity){ //计算好新的容量后,比较最小需要的容量和新的容量,二者的较大值才为需要的新的的容量
newcapcity= mincapcity;
}
Object[] objects = new Object[newcapcity];//用需要的容量创建新的数组
for(int i=0;i<newcapcity;i++){ //新的数组存入element数组的数据
objects[i] = element[i];
}
element = objects; //element数组指向新数组引用
}
for(int i = size; i>index; i--){ //开始添加数据,首先把添加位置后的数据都向后移动
element[i] = element[i-1];
}
element[index] = o; //在要添加的位置添加数据
modecount++; //修改集合次数+1
size++; //集合元素个数+1
}
/**
* 检查索引是否合法
* @param index 索引
*/
private void checkIndex(int index) {
if(index<0||index>size){
throw new IllegalArgumentException("非法参数");
}
}
/**
* 移除指定元素(有重复的移动位置最前的)
* @param o
*/
@Override
public void remove(Object o) {
int index = indexof(o);
if(index!=-1){ //如果索引可以找到
remove(index);
}
}
/**
* 移除指定位置的元素
* @param index 索引
* @return 返回移除的元素
*/
@Override
public E remove(int index) {
checkIndex(index); //检查索引是否合法
E e = (E) element[index]; //临时保存所移除元素
for (int i = index; i <size ; i++) { //移除元素,需要把index之后的 元素向前移动
element[i] = element[i+1];
}
element[size] = null; //移除后空出位置需要置为空
size--; //元素个数-1
modecount++; //修改集合次数+1
return e;
}
/**
* 判断集合中是否包含此元素
* @param e 任意类型数据
* @return 返回true表示找到,否则返回false
*/
@Override
public boolean contains(E e) {
int i = indexof(e);
return i!=-1;
}
/**
* 清空集合元素
*/
@Override
public void clear(){
for (int i = 0; i < size; i++) {
element[i] =null; //所有元素置为空
}
size = 0; //元素个数置为0
modecount++; //修改集合次数+1
}
/**
* 得到集合指定位置的元素
* @param index 索引
* @return 返回指定位置的元素
*/
@Override
public E get(int index) {
checkIndex(index); //判断索引是否合法
return (E) element[index];
}
/**
* 找到指定元素的位置
* @param o 任意类型
* @return 找到返回元素位置,否则返回-1
*/
@Override
public int indexof(Object o) {
for (int i = 0; i < size; i++) {
if(element[i].equals(o)){
return i;
}
}
return -1;
}
/**
* 找到指定元素最后一个的位置
* @param o 任意类型
* @return 找到返回元素位置,否则返回-1
*/
@Override
public int lastIndexof(Object o) {
for (int i = size-1; i >=0; i--) { //从后向前找方便
if(element[i].equals(o)){
return i;
}
}
return -1;
}
/**
* 修改集合指定位置的元素
* @param index 索引
* @param o 任意类型
*/
@Override
public void set(int index, Object o) {
checkIndex(index); //检查索引合法性
element[index] = o;
}
/**
* 返回集合元素个数
* @return size
*/
@Override
public int size() {
return size;
}
/**
* 判断集合是否为空
* @return 为空返回true,否则返回false
*/
@Override
public boolean isEmpty() {
return size==0;
}
/**
* 迭代器无参构造
* @return ListIterator<E>
*/
@Override
public ListIterator<E> iterator() {
return new MyIterator();
}
/**
* 迭代器有参构造
* @param index 索引
* @return ListIterator<E>
*/
@Override
public ListIterator<E> iterator(int index) {
return new MyIterator(index);
}
//成员内部类实现迭代器
public class MyIterator<E> implements ListIterator<E> {
int cursor; //游标
int lastRet=-1; //记录上一次next或previous返回元素的索引位置
int expectedmodecount = modecount; //记录集合修改次数,用于检查是否出现并发修改
public MyIterator(int cursor) { //迭代器有参构造
if(cursor<0||cursor>size){ //游标合法性,对应size
throw new IllegalArgumentException("-1");
}
this.cursor = cursor;
}
public MyIterator() {} //无参构造
/**
* 判断是否有下一个元素
* @return 有返回true,否则返回false
*/
@Override
public boolean hasNext() {
return cursor<size; //游标对应size
}
/**
*
* @return 返回游标的下一个元素
*/
@Override
public E next() {
checkBinfa(); //并发检查
if(hasNext()){ //有下一个元素
E e = (E) element[cursor]; //保存下一个元素
lastRet=cursor; //记录上一次next或previous返回元素的索引位置
cursor++; //游标后移
return e;
}else {
throw new NoSuchElementException();
}
}
/**
* 检查是否发生并发修改
*/
private void checkBinfa() {
if(expectedmodecount!=modecount){
throw new ConcurrentModificationException();
}
}
/**
* 判断是否有前一个元素
* @return 有的话返回true,没有返回false
*/
@Override
public boolean hasPrevious() {
return cursor>0;
}
/**
*
* @return 返回游标的上一个元素
*/
@Override
public E previous() {
checkBinfa(); //并发修改检查
if(hasPrevious()){ //有上一个元素
E e = (E) element[cursor-1]; //保存上一个元素
cursor--; //游标前移
lastRet = cursor; //记录上一次next或previous返回元素的索引位置
return e;
}else{
throw new NoSuchElementException();
}
}
/**
*
* @return 返回对 next 的后续调用所返回元素的索引。
*/
@Override
public int nextIndex() {
return cursor;
}
/**
*
* @return 返回对 previous 的后续调用所返回元素的索引。
*/
@Override
public int previousIndex() {
return cursor--;
}
/**
* 移除next 或者 previous 返回的最后一个位置的元素
*/
@Override
public void remove() {
if(lastRet==-1){ //如果已经修改过,就不再允许在当前游标位置进行修改
throw new IllegalStateException();
}
checkBinfa(); //并发修改检查
MyList.this.remove(cursor); //删掉
expectedmodecount = modecount;//迭代器的自身的修改不会引发并发修改异常
cursor = lastRet; //这里next和previous统一处理即可
lastRet=-1; //不允许在当前游标位置进行修改,如果修改就会发生逻辑错误
}
/**
* 修改curcor位置的元素的值
* @param e
*/
@Override
public void set(E e) {
if(lastRet == -1){ // 如果已经修改过,就不再允许在当前游标位置进行修改
throw new IllegalStateException();
}
checkBinfa();
MyList.this.set(cursor,e);
}
/**
* 在当前curcor位置添加一个元素
* @param e
*/
@Override
public void add(E e) {
if(lastRet==-1){ // 如果已经修改过,就不再允许在当前游标位置进行修改
throw new IllegalStateException();
}
checkBinfa(); //并发修改检查
MyList.this.add(cursor,e);
expectedmodecount = modecount;//迭代器的自身的修改不会引发并发修改异常
cursor++; //游标后移
lastRet = -1; //不允许在当前游标位置进行修改,如果修改就会发生逻辑错误
}
}
}

浙公网安备 33010602011771号