using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _01_ArrayList案例
{
internal class Program
{
static void Main(string[] args)
{
MyArrayList myArrayList = new MyArrayList(new object[] { 1,2,3, "123","456", true ,false,'a'}) ;
myArrayList.Add(100);
myArrayList.AddRange(new object[] { 100, 200, 300, "abc", "def", true, false, 'g' });
myArrayList.Insert(4, 120);
//myArrayList.Insert(4, 100);
Console.WriteLine("ArrayList的初始容量为:" + myArrayList.Capacity);
Console.WriteLine("ArrayList的初始元素个数为:" + myArrayList.Count);
Console.WriteLine("------------------------");
for (int i = 0; i < myArrayList.Count; i++)
{
Console.WriteLine(myArrayList[i]);
}
Console.ReadLine();
}
}
class MyArrayList
{
// 声明字段存储数据
object[] objects = new object[8];
// 获取数组的长度 存储的数据个数
int _Count = 0;
public int Count { get { return _Count; } }
// 获取内存大小
public int Capacity
{
get
{
return objects.Length;
}
}
// 通过索引器获取元素
public object this[int index]
{
get
{
if (index < 0 || index > Count)
{
throw new IndexOutOfRangeException("索引超出范围");
}
return objects[index];
}
set
{
if (index < 0 || index > Count)
{
throw new IndexOutOfRangeException("索引超出范围");
}
objects[index] = value;
}
}
public MyArrayList()
{
}
public MyArrayList(object[] items )
{
// 根据当前元素的个数来确定数组的大小
UpdateCapacity(items .Length);
// 将初始化数组中的元素添加到ArrayList中
for (int i = 0; i < items.Length; i++)
{
objects [i] = items[i];
}
_Count = items.Length;
}
// 更新数组大小
void UpdateCapacity(int itemLength)
{
// 获取数组应该的长度大小
int nowSize = GetNewArryLength(itemLength);
// 判断当前应该的空间大小是否大于当前数组的空间大小
if (nowSize > objects.Length)
{
object[] objects_temp = new object[nowSize];
for (int i = 0; i < objects.Length ; i++)
{
objects_temp[i] = objects[i];
}
objects = objects_temp;
}
}
// 获取当前数组应该的长度大小
// 根据数组的长度和元素的个数来确定新的数组的长度
int GetNewArryLength(int itemLength)
{
int size = 8;
while (size < itemLength)
{
size *= 2;
}
return size;
}
public void Add(object obj)
{
// 根据现有元素的个数来跟新数组空间大小
UpdateCapacity(Count + 1);// 只要执行这个方法 那么现在的空间大小一定是够用的
// 将新添加的元素添加到数组中
objects[Count] = obj;
}
// 添加一个范围的元素
public void AddRange(object[] items)
{
UpdateCapacity(Count + items.Length);
// 将新添加的元素添加到数组中
for (int i = 0; i < items.Length; i++)
{
objects[Count + i] = items[i];
}
_Count += items.Length;
}
public void Insert(int index, object obj)
{
if (index < 0 || index > Count)
{
throw new IndexOutOfRangeException("索引超出范围");
}
// 根据现有元素的个数来跟新数组空间大小
UpdateCapacity(Count + 1);// 只要执行这个方法 那么现在的空间大小一定是够用的
// 将新添加的元素添加到数组中
for (int i = Count-1; i >= index; i--)
{
objects[i+1] = objects[i];
}
// 将插入的元素替换为要插入的元素
objects[index] = obj;
_Count++;
}
public void InsertRange(int index, object[] items)
{
if (index < 0 || index > Count)
{
throw new IndexOutOfRangeException("索引超出范围");
}
// 根据现有元素的个数来跟新数组空间大小
UpdateCapacity(Count + items.Length);
// 将新添加的元素添加到数组中
for (int i = Count - 1; i >= index; i--)
{
objects[i + items.Length] = objects[i];
}
// 将插入的元素替换为要插入的元素
for (int i = 0; i < items.Length; i++)
{
objects[index + i] = items[i];
}
_Count += items.Length;
}
// 查找元素第一次出现的位置
public int IndexOf(object item)
{
for (int i = 0; i < Count; i++)
{
// 当把值类型数据进行装箱操作 编程引用数据类型 那么因为在堆内存中存储的地址不同索引在条件判断时即便值类型数据相同 两个数据不相同
// 引用数据在进行相等比较时 对比的是引用地址 而不是值 所以即便值类型数据相同 两个引用地址也不相同
//if (objects[i] == item)
//{
// return i;
//}
// 判断数据类型是否是值类型 或者字符串类型 如果是值类型或者字符串类型则需要转化为值类型 或者字符串类型进行判断
// Console.WriteLine(objects[i].GetType());// 用来获取数据是什么类型
// Equase 方法用来判断引用类型数据是否相等
// 任何数据中都有Equals方法 用来判断数据是否相等
if (objects[i].Equals(item)) return i;
}
return -1;
}
// 查找元素最后一次出现的位置
public int LastIndexOf(object item)
{
for (int i = Count - 1; i >= 0; i--)
{
// 条件判断逻辑只有一句时可以不用写{}
if (objects[i].Equals(item)) return i;
}
return -1;
}
// 删除指定位置的元素
public void RemoveAt(int index)
{
if (index < 0 || index >= Count)
{
throw new IndexOutOfRangeException("索引超出范围");
}
for (int i = index +1; i < Count ; i++)
{
objects[i-1] = objects[i];
}
_Count--;
}
// 删除指个数定元素
public void RemoveRange(int index, int count)
{
if (index < 0 || index >= Count)
{
throw new IndexOutOfRangeException("索引超出范围");
}
for (int i = index + count; i < Count ; i++)
{
objects[i-Count ] = objects[i];
}
_Count -= count;
}
// 根据元素删除
public void Remove(object item)
{
int index = IndexOf(item);
if (index != -1)
{
RemoveAt(index);
}
}
// 反转数组
public void Reverse()
{
for (int i = 0; i < Count / 2; i++)
{
object temp = objects[i];
objects[i] = objects[Count - i - 1];
objects[Count - i - 1] = temp;
}
}
// 清空数组
public void Clear()
{
_Count = 0;
}
}
}
/*
Capacity 容量
*/