Java:自己实现一个ArrayList
目录
四.关于在Java中System.arraycopy() 和 Arrays.copyOf()两者之间的区别
为了更好地理解Java的ArrayList类,我们决定自己实现一个ArrayList类,就叫它MyArrayList吧!
一.MyList接口
首先,我们先写一个MyList接口,将我们要实现的方法都列举出来:
public interface MyList<E> {
/**
*
* @return 存储的元素个数
*/
int size();
/**
* @param value 添加的元素
*/
void add(E value);
/**
* 合并
* @param list 需要合并的List
*/
void addAll(MyList list);
/**
* 合并一个对象数组
* @param objects
*/
void addAll(E[] objects);
/**
* 获取:
* @param index 根据下标获取
* @return 返回元素对象
*/
Object get(int index);
/**
* 根据元素查找
* @param value
* @return 下标数组
*/
int[] get(E value);
/**
* 根据下标删除
* @param index
*/
void remove(int index);
/**
* 根据元素对象值删除
* @param value
* @return 是否删除成功
*/
boolean remove(E value);
/**
* 清空队列
*/
void removeAll();
/**
*
* @param index 目标元素的下标
* @param value 目标元素需要替换的对象
*/
void set(int index,E value);
/**
*
* @param repobj 目标元素对象
* @param value 目标元素需要替换的对象
*/
void set(E repobj,E value);
/**
* 排序 对象的 hashcode
*/
void sort();
}
二.实现MyArrayList的方法
然后我们要做的就是逐个实现这些方法:
1.检查范围checkRange()
索引index必须在0到Integer.MAX_VALUE之间,否则抛出异常
//检查范围
public void checkRange(int index) {
if(index < 0 || index >= size) {
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.add(),addAll()的实现
add系列的方法实现:关键在于扩容机制,其中add方法如果容量不够我们的做法是利用
Arrays.copyOf()将容量增加10.
@Override
public void add(E value) {
//扩展容量
if(size >= arr.length) {
Object[] newArr = Arrays.copyOf(arr, arr.length+10);
arr = newArr;
}
arr[size++] = value;
}
@Override
public void addAll(MyList list) {
Object[] newArr = Arrays.copyOf(arr, arr.length+list.size());
arr = newArr;
System.arraycopy(list, 0, arr, size, list.size());
}
@Override
public void addAll(E[] objects) {
Object[] newArr = Arrays.copyOf(arr, arr.length+objects.length);
arr = newArr;
System.arraycopy(objects, 0, arr, size, objects.length);
}
3.remove(),removeAll()的实现
其中remove(int index)方法是关键,remove(E value)、 removeAll()是在前者基础上实现的;
实现remove(int index)方法,我们的做法是以下标为index的元素为分界线,分别利用arraycopy方法将其前后的两段数组复制到一个新的数组newArray中去,然后让arr指向新的newArr;
@Override
public void remove(int index) {
this.checkRange(index);
Object[] newArr = new Object[arr.length-1];
System.arraycopy(arr, 0, newArr, 0, index);
System.arraycopy(arr, index+1, newArr, index, size-index-1);
this.size -= 1;
arr = newArr;
}
@Override
public boolean remove(E value) {
for(int i = 0; i < this.size; i++) {
if(arr[i].equals(value)) {
this.remove(i);
return true;
}
}
return false;
}
@Override
public void removeAll() {
for(int i = 0; i < arr.length; i++) {
this.remove(i);
}
this.size = 0;
}
4.sort()方法的实现
利用hashCode进行排序:
@Override
public void sort() {
//利用hashCode进行排序
int[] hash = new int[this.size];
for(int i = 0; i < this.size; i++) {
hash[i] = arr[i].hashCode();
}
//冒泡排序
for (int i = 0; i < this.size; i++)
{
for (int j = 0; j < this.size - i - 1; j++)
{
if (hash[j] > hash[j + 1])
{
Object temp1 = null;
temp1 = this.arr[j + 1];
this.arr[j + 1] = this.arr[j];
this.arr[j] = temp1;
int temp2 = 0;
temp2 = hash[j + 1];
hash[j + 1] = hash[j];
hash[j] = temp2;
}
}
}
}
三.完整代码
给各位hxdm完整代码:
import java.util.Arrays;
public class MyArrayList<E> implements MyList<E> {
//数组最小大小
private static final int MIN_SIZE = 10;
//数组最大大小
private static final int MAX_SIZE = Integer.MAX_VALUE;
//数组中元素的个数
private int size = MIN_SIZE;
//声明数组arr
private Object[] arr = null;
//检查范围
public void checkRange(int index) {
if(index < 0 || index >= size) {
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public MyArrayList() {
arr = new Object[this.MIN_SIZE];
}
public MyArrayList(int length) {
//长度小于0,异常
if(length < 0) {
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
}
//长度大于等于0小于10,设置为最小长度
else if(length >= 0 && length < MIN_SIZE) {
length = MIN_SIZE;
}
arr = new Object[length];
size = 0;
}
public MyArrayList(Object[] arr) {
this.size = arr.length;
System.arraycopy(arr, 0, this.arr, 0, arr.length);
}
@Override
public int size() {
return size;
}
@Override
public void add(E value) {
//扩展容量
if(size >= arr.length) {
Object[] newArr = Arrays.copyOf(arr, arr.length+10);
arr = newArr;
}
arr[size++] = value;
}
@Override
public void addAll(MyList list) {
Object[] newArr = Arrays.copyOf(arr, arr.length+list.size());
arr = newArr;
System.arraycopy(list, 0, arr, size, list.size());
}
@Override
public void addAll(E[] objects) {
Object[] newArr = Arrays.copyOf(arr, arr.length+objects.length);
arr = newArr;
System.arraycopy(objects, 0, arr, size, objects.length);
}
@Override
//返回下标为index的元素的值
public Object get(int index) {
this.checkRange(index);
return arr[index];
}
@Override
public int[] get(E value) {
int[] ret = new int[size];
int index = 0;
for(int i = 0; i < size; i++) {
if(arr[i] == value) {
ret[index] = i;
index++;
}
}
return ret;
}
@Override
public void remove(int index) {
this.checkRange(index);
Object[] newArr = new Object[arr.length-1];
System.arraycopy(arr, 0, newArr, 0, index);
System.arraycopy(arr, index+1, newArr, index, size-index-1);
this.size -= 1;
arr = newArr;
}
@Override
public boolean remove(E value) {
for(int i = 0; i < this.size; i++) {
if(arr[i].equals(value)) {
this.remove(i);
return true;
}
}
return false;
}
@Override
public void removeAll() {
for(int i = 0; i < arr.length; i++) {
this.remove(i);
}
this.size = 0;
}
@Override
public void set(int index, E value) {
this.checkRange(index);
arr[index] = value;
}
@Override
public void set(E repobj, E value) {
for(int i = 0 ; i < this.size; i++) {
if(arr[i].equals(repobj)) {
arr[i] = value;
}
}
}
@Override
public void sort() {
//利用hashCode进行排序
int[] hash = new int[this.size];
for(int i = 0; i < this.size; i++) {
hash[i] = arr[i].hashCode();
}
//冒泡排序
for (int i = 0; i < this.size; i++)
{
for (int j = 0; j < this.size - i - 1; j++)
{
if (hash[j] > hash[j + 1])
{
Object temp1 = null;
temp1 = this.arr[j + 1];
this.arr[j + 1] = this.arr[j];
this.arr[j] = temp1;
int temp2 = 0;
temp2 = hash[j + 1];
hash[j + 1] = hash[j];
hash[j] = temp2;
}
}
}
}
}
四.关于在Java中System.arraycopy() 和 Arrays.copyOf()两者之间的区别
这篇文章讲的很不戳: