概述
上一篇手写ArrayList并不完整,相对重要的contains,indexOf,remove方法都没有,更重要的没有支持泛型。又刚好这些方法都跟泛型存在一定关系,所以本篇就以这个3个方法为基础继续完善MyArrayList。
泛型改造
首先要做的,先对原先MyArrayList进行泛型改造:1>定义类名时声明泛型 2>使用用泛型替换原先的方法中Object
public class MyArrayList<E> {...}
具体做法,很简单,就是将原先Object 类型参数,转换成E即可,比如:
/**
* 获取指定索引的数据
* @param index 索引
* @return 数据
*/
public E get(int index) {
if (index >= size || index < 0){
throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);
}
return (E) elementData[index];
}
定位-indexOf
indexOf(element)方法返回指定元素在集合中索引位置(第一个匹配的),如果不存在,则返回-1。具体实现逻辑不能,就是遍历所有元素,跟传入的元素比对,如果一样(相等)返回当前元素的索引即可。这里存在难点,如何判断元素相等?
java中常规比较方式有2种:
1:比较内存地址: A对象 == B对象
2:比较内容:A对象.equals(B对象) A变量 == B变量 (基本类型)
这里注意,如果A对象 没有重写Object对象equals方法,默认比较是内存地址,这里讲的是重写后的对象。
public class Object {
public boolean equals(Object obj) {
return (this == obj);
}
}
这里是实现逻辑,如果为null,等值比较,如果不为null,调用比较对象的equals方法。这里要注意啦,如果比较对象不重写Object父类的equals比较的是内存地址。
/**
* 返回第一次匹配的元素所在索引位置
* @param element 要查的元素
* @return
*/
public int indexOf(E element){
for(int i = 0;i < size; i++){
if(element == null){
if(elementData[i] == null){
return i;
}
}else{
if(element.equals(elementData[i])){
return i;
}
}
}
return -1;
}
包含-contains
包含,判断指定元素是否在集合中,返回true与false。方法实现逻辑indexOf类似:
/**
* 判断指定对象是否存在集合中
* @param element
* @return
*/
public boolean contains(E element) {
return indexOf(element) >= 0;
}
删除-remove
remove(index) 跟 remove(element) 区别:都是删除元素,前一个根据索引删除,只要对应索引有值便可以删除,后一个根据元素删除,只要删除原则在集合中便可以删除。
/**
* 判断指定对象是否存在集合中
* @param element
* @return
*/
public boolean remove(E element) {
int i = this.indexOf(element);
if(i != -1){
remove(i);
return true;
}
return false;
}
到这,MyArrayList的基本方法就结束啦,上一份完整代码,后续抽空把迭代器加上就差不多,期待。
public class MyArrayList<E> {
private int size; //存放数据大小
private Object[] elementData; //存放数据数组
//默认长度
private static final int DEFAULT_CAPACITY = 10;
//模仿ArrayList初始化 2个空数组,执行add时才进行扩容
private static final Object[] EMPTY_ELEMENTDATA = {};
//为什么弄2个空数组,官方给出解释:
// We distinguish this from EMPTY_ELEMENTDATA to know how much to inflate
//when first element is added.
//翻译过来就是:我想知道它啥时候塞值进去
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public MyArrayList(){
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
public MyArrayList(int initialCapacity){
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
public MyArrayList(MyArrayList list){
elementData = list.toArray();
if ((size = elementData.length) == 0) {
this.elementData = EMPTY_ELEMENTDATA;
}
}
public Object[] toArray() {
//借用工具类啦
return Arrays.copyOf(elementData, size);
}
/**
* 往数组中添加元素(默认添加到最后)
* @param element 元素
* @return 添加成功返回true, 不成功返回false
*/
public boolean add(E element) {
this.add(size, element);
return true;
}
//拓展方法
private void grow() {
int oldCapacity = elementData.length; //新长度
int newCapacity;
if(oldCapacity == 0){
newCapacity = DEFAULT_CAPACITY;
}else{
//扩展增幅是 1.5倍
newCapacity = oldCapacity + (oldCapacity >> 1);
}
elementData = Arrays.copyOf(elementData, newCapacity);
}
/**
* 往数组指定位置添加元素(默认添加到最后)
* @param index 索引
* @param element 元素
* @return 添加成功返回true, 不成功返回false
*/
public boolean add(int index, E element) {
//检查索引是否正确
this.rangeCheck(index);
if(size == elementData.length){
this.grow();
}
System.arraycopy(elementData, index, elementData, index + 1, size - index);
elementData[index] = element;
size++;
return true;
}
//检查索引是否正确
private void rangeCheck(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);
}
/**
* 根据指定索引删除数据
* @param index 索引
* @return 被删除的数据
*/
public E remove(int index){
if (index >= size || index < 0){
throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);
}
Object old = elementData[index];
if(size - 1 > index){
System.arraycopy(elementData, index + 1, elementData, index, size -1 - index);
}
elementData[size-1] = null;
size --;
return (E) old;
}
/**
* 清空集合元素
*/
public void clear() {
for (int i = 0; i < size; i++){
elementData[i] = null;
}
size = 0;
}
/**
* 修改指定位置元素数据
* @param index 索引
* @param element 元素
* @return 返回被改动的数据
*/
public E set(int index, E element) {
if (index >= size || index < 0){
throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);
}
Object oldValue = elementData[index];
elementData[index] = element;
return (E) oldValue;
}
/**
* 获取指定索引的数据
* @param index 索引
* @return 数据
*/
public E get(int index) {
if (index >= size || index < 0){
throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);
}
return (E) elementData[index];
}
/**
* 返回第一次匹配的元素所在索引位置
* @param element 要查的元素
* @return
*/
public int indexOf(E element){
for(int i = 0;i < size; i++){
if(element == null){
if(elementData[i] == null){
return i;
}
}else{
if(element.equals(elementData[i])){
return i;
}
}
}
return -1;
}
/**
* 判断指定对象是否存在集合中
* @param element
* @return
*/
public boolean contains(E element) {
return indexOf(element) >= 0;
}
/**
* 判断指定对象是否存在集合中
* @param element
* @return
*/
public boolean remove(E element) {
int i = this.indexOf(element);
if(i != -1){
remove(i);
return true;
}
return false;
}
@Override
public String toString() {
return "MyArrayList{" +
"size=" + size +
", elementData=" + Arrays.toString(elementData) +
'}';
}
}