package com.hu;
import java.util.*;
public class MyArrayList<E> implements MyList<E> {
private int size;
private Object[] elementData;
private static final int DEFAULT_CAPACITY = 10;
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private int modCount;
//无参构造方法
public MyArrayList (){
elementData=new Object[DEFAULT_CAPACITY];
}
//1参构造方法,指定初始容量
public MyArrayList (int minCapacity){
elementData=new Object[minCapacity];
}
//增加元素
@Override
public boolean add(E e) {
add(size,e);
return true;
}
//在指定索引位置增加元素
@Override
public void add(int index, E element) {
//检查index是否越界
rangeCheckForAdd(index);
int newCapacity=size+1;
//是否需要扩容
if(newCapacity>elementData.length){
//扩容的计算方法
newCapacity=capacityCaculate(newCapacity);
}
//扩容
grow(newCapacity);
//为新加入的元素腾出位置
for(int i=size-1;i>=index;i--){
elementData[i+1]=elementData[i];
}
//放置元素
elementData[index]=element;
size++;
//集合发生结构性变化
modCount++;
}
//扩容的计算方法
private int capacityCaculate(int minCapacity) {
int newcapacity=minCapacity+minCapacity>>1;
if(newcapacity<0||newcapacity>Integer.MAX_VALUE){
newcapacity=MAX_ARRAY_SIZE;
}
//如果minCapacity值比较大,它扩容1.5倍之后超过了Integer最大值,但是它又比我们设置的默认最大值MAX_ARRAY_SIZE大
//此时我们直接将minCapacity设为集合容量大小
return (newcapacity>minCapacity)?newcapacity:minCapacity;
}
//扩容
private void grow(int newCapacity){
elementData= Arrays.copyOf(elementData,newCapacity);
}
//检查索引位置合法性
private void rangeCheckForAdd(int index) {
if(index<0||index>size){
throw new IndexOutOfBoundsException("size=:"+size);
}
}
//清楚集合所有元素
@Override
public void clear() {
for(int i=0;i<size;i++){
elementData[i]=null;
}
size=0;
modCount++;
}
//判断元素是否包含
@Override
public boolean contains(Object o) {
//如果o是null的话,要单独判断,因为equals不能比较null
if(o==null){
for (int i=0;i<size;i++){
if(elementData[i]==null){
return true;
}
}
}
for(int i=0;i<size;i++){
if(elementData[i].equals(o)){
return true;
}
}
return false;
}
//获得指定位置元素值
@Override
public E get(int index) {
//判断索引合法性
rangeCheckForGet(index);
return (E) elementData[index];
}
/**
*
* @param index 0-size-1
*/
private void rangeCheckForGet(int index) {
if(index<0||index>size-1){
throw new IndexOutOfBoundsException("index="+index);
}
}
/**
* 获得指定元素首次出现的位置
* @param o
* @return 找不带指定元素返回-1
*/
@Override
public int indexOf(Object o) {
if(o==null){
for(int i=0;i<size;i++){
if(elementData[i]==null){
return i;
}
}
}
for(int i=0;i<size;i++){
if(elementData[i].equals(o)){
return i;
}
}
//找不到指定元素返回-1
return -1;
}
/**
* 获得指定元素最后出现的位置
* @param o
* @return 找不带指定元素返回-1
*/
@Override
public int lastIndexOf(Object o) {
if(o==null){
for(int i=size-1;i>=0;i--){
if(elementData[i]==null){
return i;
}
}
}
for(int i=size-1;i>=0;i--){
if(elementData[i].equals(o)){
return i;
}
}
//找不到指定元素返回-1
return -1;
}
//判断集合是否为空
@Override
public boolean isEmpty() {
return size==0;
}
//删除指定索引位置的元素
@Override
public E remove(int index) {
//检查索引合法性
rangeCheckForGet(index);
E element=(E) elementData[index];
for(int i=index+1;i<size;i++){
elementData[i-1]=elementData[i];
}
size--;
modCount++;
return element;
}
//删除指定元素
@Override
public boolean remove(Object o) {
if(o==null){
for(int i=0;i<size;i++){
if(elementData[i]==null){
remove(i);
return true;
}
}
}
for(int i=0;i<size;i++){
if(elementData[i].equals(o)){
remove(i);
return true;
}
}
return false;
}
//将指定索引位置的元素更改为指定的元素
@Override
public E set(int index, E element) {
//检查索引合法性检查
rangeCheckForGet(index);
E e = (E)elementData[index];
elementData[index]=element;
return e;
}
@Override
public int size() {
return size;
}
@Override
public ListIterator<E> listIterator() {
return new MyListIterator();
}
@Override
public ListIterator<E> listIterator(int index) {
return new MyListIterator(index);
}
private class MyListIterator implements ListIterator<E>{
//初始游标索引为0
int cursor;
//lastRet是为remove()、add()和set()方法设计的
int lastRet=-1;
//exceptModCount用于监测迭代器外部是否更改了集合结构
int exceptModCount=modCount;
//无参构造方法
public MyListIterator() {
}
//一参构造方法,指定游标起始位置
public MyListIterator(int index) {
cursor=index;
}
//hasNext()判断cursor后是否还有元素
@Override
public boolean hasNext() { return cursor<size; }
//next()返回cursor指向的那个元素
@Override
public E next() {
//检查是否有并发修改异常
checkConcurrentModficationException();
if(hasNext()){
E e = (E)elementData[cursor];
lastRet=cursor;
cursor++;
return e;
}else {
//游标已经走到了最后
throw new NoSuchElementException("cursor="+cursor);
}
}
//检查是否有并发修改异常
private void checkConcurrentModficationException() {
if(exceptModCount!=modCount){
throw new ConcurrentModificationException("集合结构发生变化");
}
}
//hasPrevious()判断cursor前是否还有元素
@Override
public boolean hasPrevious() {
return cursor>0;
}
//
@Override
public E previous() {
checkConcurrentModficationException();
if(hasPrevious()){
E e=(E) elementData[cursor-1];
cursor--;
lastRet=cursor;
return e;
}else {
//游标已经走到了最前面
throw new NoSuchElementException("cursor="+cursor);
}
}
//nextIndex()返回cursor,下一次next()返回的元素的索引
@Override
public int nextIndex() {
return cursor;
}
//previousIndex()返回cursor-1,下一次previous()返回的元素的索引
@Override
public int previousIndex() { return cursor-1; }
@Override
public void remove() {
checkConcurrentModficationException();
//lastRet如果小于0,说明还未调用next()或previous(),或者调用了next()和previous()之后又重新调用了迭代器的add()或set()方法,
// 或者已经调用了remove()方法,导致lastRet,又重新置为-1
if(lastRet<0){
throw new IllegalStateException("lastRet="+lastRet);
}
//调用MyArrayList的remove(int index)删除元素
MyArrayList.this.remove(lastRet);
cursor=lastRet;
lastRet=-1;
//迭代器内部更改集合结构不应该造成并发修改异常
exceptModCount=modCount;
}
@Override
public void set(E e) {
checkConcurrentModficationException();
//lastRet如果小于0,说明还未调用next()或previous(),或者调用了next()和previous()之后又重新调用了迭代器的add()或remove()方法,
// 或者已经调用了set()方法,导致lastRet,又重新置为-1
if(lastRet<0){
throw new IllegalStateException("lastRet="+lastRet);
}
elementData[lastRet]=e;
lastRet=-1;
//这里并未更改集合结构
//exceptModCount=modCount;
}
@Override
public void add(E e) {
checkConcurrentModficationException();
//lastRet如果小于0,说明还未调用next()或previous(),或者调用了next()和previous()之后又重新调用了迭代器的add()或remove()方法,
// 或set()方法,导致lastRet,又重新置为-1
if (lastRet<0){
throw new IllegalStateException("lastRet="+lastRet);
}
//调用MyArrayList的add(int index,E e)添加元素
MyArrayList.this.add(cursor,e);
lastRet=-1;
迭代器内部更改集合结构不应该造成并发修改异常
exceptModCount=modCount;
}
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
MyArrayList<?> that = (MyArrayList<?>) o;
return size == that.size &&
modCount == that.modCount &&
Arrays.equals(elementData, that.elementData);
}
@Override
public int hashCode() {
int result = Objects.hash(size, modCount);
result = 31 * result + Arrays.hashCode(elementData);
return result;
}
@Override
public String toString() {
StringBuilder stringBuilder=new StringBuilder();
stringBuilder.append("[");
if (size>0){
for (int i=0;i<size-1;i++){
stringBuilder.append(elementData[i]+",");
}
stringBuilder.append(elementData[size-1]+"");
}
stringBuilder.append("]");
return stringBuilder.toString();
}
}
package com.hu;
import java.util.ListIterator;
public class Test {
public static void main(String[] args) {
MyArrayList<String> list = new MyArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("a");
list.add("b");
list.add("c");
list.add(1,"1");
System.out.println("初始集合为:"+list);
boolean contains = list.contains("1");
System.out.println("是否包含元素1:"+contains);
String s = list.get(3);
System.out.println("索引为3的元素为:"+s);
int b = list.indexOf("b");
System.out.println("首次出现元素b的索引为:"+b);
int b1 = list.lastIndexOf("b");
System.out.println("最后出现元素b的索引为:"+b1);
boolean empty = list.isEmpty();
System.out.println("集合是否为空:"+empty);
String remove = list.remove(3);
System.out.println("删除索引为3的元素后,集合为:"+list);
boolean b2 = list.remove("b");
System.out.println("是否成功删除了集合中第一次出现的元素b:"+b2+" "+"删除第一次出现的元素b后集合为:"+list);
String a = list.set(1, "aa");
System.out.println("将索引为1的元素更改为元素aa,被更改的元素是:"+a+" "+"更改后集合为:"+list);
list.clear();
System.out.println("清除集合所有元素后,集合为:"+list+" "+"此时集合size为"+list.size());
System.out.println("------------------------------------------------------------------------------------------");
System.out.println("-----------------------------------测试迭代器---------------------------------------------");
list.add("a");
list.add("b");
list.add("c");
list.add("d");
System.out.println("初始集合为:"+list);
ListIterator<String> listIterator = list.listIterator(1);
System.out.println("1.下面正向遍历从cursor等于1开始遍历,这可以测试迭代器的有参构造方法");
for(;listIterator.hasNext();){
System.out.print(listIterator.next()+" ");
}
System.out.println();
System.out.println("下面逆向遍历从cursor等于size开始遍历");
for(;listIterator.hasPrevious();){
System.out.print(listIterator.previous()+" ");
}
System.out.println();
System.out.println("2.测试nextIndex()和previousIndex(),此时cursor为0");
System.out.println("nextIndex=:"+listIterator.nextIndex()+" "+"previousIndex()=:"+listIterator.previousIndex());
System.out.println("3.上面逆向遍历已经将cursor置为0,现在开始测试迭代器的remove()方法");
String next = listIterator.next();
listIterator.remove();
System.out.println("remove()删除的next()返回的那个元素,也就是"+next+" "+"删除后集合为:"+list);
System.out.println("4.测试迭代器的add()方法,上面调用过remove(),此时lastRet已经置为-1,不能直接调用add()");
String next1 = listIterator.next();
listIterator.add("111");
System.out.println("迭代器的add()方法在next()方法已经返回的那个元素后面加入元素111,已经返回的元素为:"+next1+" "+"增加元素111后,集合为:"+list);
System.out.println("5.测试迭代器的set()方法,同理,上面调用过remove()和add(),此时lastRet已经置为-1,不能直接调用set()");
String next2 = listIterator.next();
listIterator.set("222");
System.out.println("迭代器的set()方法将next()方法已经返回的那个元素更改为元素222,已经返回的元素为:"+next2+" "+"增加元素222后,集合为:"+list);
// System.out.println("测试并发修改异常");
// ListIterator<String> listIterator = list.listIterator();
// String next = listIterator.next();
// listIterator.add("111");
// System.out.println(list);
// listIterator.remove();
}
}
实现一个基于数组的ArrayList
最新推荐文章于 2021-12-09 17:32:39 发布