ArrayList的特点: 是List接口的实现类 * 内部的数据结构是数组 * 内存是连续的 * 查询速度快 * 增删速度慢 * 线程不安全的集合--运行速度快 * 默认初始容量是10 * 每次扩容是原来的容量 + 原来容量的一半
下面咱们来自定义实现ArrayList类(慢慢理解后,自己多跟着敲几遍,最好能自己敲下来)
public class TestDemo {
public static void main(String[] args) {
ArrayListDemo arrayListDemo = new ArrayListDemo();
arrayListDemo.add("abc");
arrayListDemo.add("cde");
arrayListDemo.add("jjk");
arrayListDemo.add("llo");
arrayListDemo.add(2,"詹姆斯");
System.out.println(arrayListDemo.subList(1, 3));
arrayListDemo.set(2,"欧文");
arrayListDemo.remove("jjk");
System.out.println(arrayListDemo);
}
}
class ArrayListDemo{
// 存储数据的数组
private String[] data;
// 记录元素的个数
private int size = 0;
// 定义无参和有参的构造方法
public ArrayListDemo(){
// 给定一个默认长度为10的数组
data = new String[10];
}
// 指定初始容量的构造方法
public ArrayListDemo(int len){
// 判断参数是否合法
if (len < 0)
throw new IllegalArgumentException("长度不能小于0");
data = new String[len];
}
// 添加元素方法
public void add(String str){
// 判断是否需要扩容
if (size >= data.length){
grow();
}
data[size++] = str;
}
/**
* 扩容方法
*/
private void grow() {
if (data.length <= 1){
data = Arrays.copyOf(data,data.length + 1);
}else {
data = Arrays.copyOf(data, data.length + (data.length >> 1));
}
}
// 插入元素方法
// index:要插入的位置的索引
// str:要插入的数据
public void add(int index,String str){
// 判断索引是否越界
if (index > size || index < 0){
throw new IndexOutOfBoundsException();
}
// 判断是否需要扩容
if (size >= data.length){
grow();
}
// 插入数据
// 其实就是将数据向后挪动一位,然后腾出来的那一位赋值要插入的数据
// 方法一:
// for (int i = size - 1;i >= index;i--){
// data[i + 1] = data[i];
// }
// 方法二: 8,5,3,6,2 8 5 10 3 6 2
System.arraycopy(data,index,data,index + 1,size - index);
data[index] = str;
size++;
}
// 删除指定索引上的元素
public void remove(int index){
out(index);
// 删除元素
// 将后面的元素按个向前移动一位
// 方法一:
// for (int i = index;i < size - 1;i++){
// data[i] = data[i + 1];
// }
// 方法二:
System.arraycopy(data,index + 1,data, index,size - index - 1);
size--;
}
private void out(int index) {
// 判断越界
if (index >= size || index < 0){
throw new IndexOutOfBoundsException();
}
}
// 查找元素第一次出现的索引
public int indexOf(String str){
for (int i = 0;i < size;i++){
if (str == data[i] || str != null && str.equals(data[i])){
return i;
}
}
// 如果没有找到,返回-1
return -1;
}
// 删除指定元素
public void remove(String str){
// 找str对应的索引
int index = indexOf(str);
if (index != -1){
remove(index);
}
}
// 清空集合
public void clear(){
data = new String[10];
size = 0;
}
// 判断是否包含指定的元素
public boolean contains(String str){
return indexOf(str) != -1;
}
// 获取元素
public String get(int index){
// 判断越界
out(index);
return data[index];
}
// 判断集合是否为空
public boolean isEmpty(){
return size == 0;
}
// 替换元素
public void set(int index,String str){
// 判断索引是否越界
out(index);
data[index] = str;
}
// 获取元素个数
public int size(){
return size;
}
// 截取子列表 [1,1,2,3,3,3,4,3,43,43,4,6,4,4,45,4,4]
public ArrayListDemo subList(int fromIndex,int toIndex){
// 判断越界和合法问题
out(fromIndex);
out(toIndex);
// 判断参数是否合法
if (fromIndex > toIndex){
throw new IllegalArgumentException();
}
// 创建一个新的列表
ArrayListDemo sublist = new ArrayListDemo(toIndex - fromIndex);
// 将旧列表的数组的值拷贝到新列表中
System.arraycopy(this.data,fromIndex,sublist.data,0,toIndex - fromIndex);
// 设置新列表的size
sublist.size = toIndex - fromIndex;
// 返回新列表
return sublist;
}
// 重写toString,打印数组中的值
// [1, 2, 3, 4]
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0;i < size;i++){
if (i != size - 1){
sb.append(data[i]).append(", ");
}else{
sb.append(data[i]);
}
}
sb.append("]");
return sb.toString();
}
}