一、数组
实现数组的增加元素、删除指定下标元素、删除指定元素、查询对应元素下标,修改元素
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace 数组
{
internal class Array01
{
private int[] data;//数组
private int N; //数组元素的个数
public Array01(int capacity)
{
Console.WriteLine(capacity);
data = new int[capacity];
N = 0;
}
//无参构造方法
public Array01() : this(10) {
Console.WriteLine("2222");
}
public int Capaticy
{
get
{
return data.Length;
}
}
public int Count
{
get { return N; }
}
public bool isEmpty
{
get { return N == 0; }
}
//往数组中,中间任意位置插入元素
/// <summary>
///
/// </summary>
/// <param name="index">需要插入哪个位置的下标</param>
/// <param name="e">当前需要插入的值</param>
public void Add(int index,int e)
{
if (index < 0 || index > N) throw new ArgumentException("数组索引越界");
if (index == data.Length) ResetCapaticy(data.Length*2);
//每插入一个元素,都是从最后一个元素的位置开始移动一个单位长度,并且长度+1
for(int i = N-1; i >=index; i--) {
//把前一个位置的值赋值给后一个位置
data[i+1] = data[i];
}
//将新的元素赋值给当前需要插入元素的下标
data[index] = e;
N++;
}
//数组头部开始插入元素
public void AddFirst(int e)
{
Add(0, e);
}
//数组的尾部插入元素
public void AddLast(int e)
{
Add(N, e);
}
//查询的方法
public int Get(int index)
{
if (index < 0 || index >= N)
throw new AggregateException("数组越界");
return data[index];
}
public int GetFirst()
{
return Get(0);
}
public int GetLast()
{
return Get(N - 1);
}
//修改
public void Set(int index,int newIndex)
{
if (index < 0 || index >= N)
throw new AggregateException("数组越界");
data[index] = newIndex;
}
//是否包含某一个元素
public bool Contains(int e)
{
for(int i = 0;i< N; i++)
{
if (data[i] == e) return true;
}
return false;
}
//返回对应数组元素下标
public int IndexOf(int e)
{
for(int i = 0; i < N; i++)
{
if (data[i] == e) return i;
}
return -1;
}
//删除指定下标元素
public int RemoveAt(int index)
{
if (index < 0 || index >= N)
throw new AggregateException("数组越界");
int del = data[index];
for(int i = index + 1; i < N; i++)
{
data[i-1] = data[i];
}
N--;
data[N] = default(int);
if (N == data.Length / 4)
{
ResetCapaticy(data.Length / 2);
}
return del;
}
//删除数组开头元素
public int RemoveFirst()
{
return RemoveAt(0);
}
//删除数组最后的元素
public int RemoveLast()
{
return RemoveAt(N - 1);
}
//删除指定数据的元素
public void Remove(int e)
{
int del = IndexOf(e);
//Console.WriteLine(del);
if (del != -1)
{
RemoveAt(del);
Console.WriteLine("删除成功!");
}
else
{
throw new AggregateException("当前元素不在数组中,删除失败!");
}
}
//数组的扩容
private void ResetCapaticy(int newCapacity)
{
int[] newData = new int[newCapacity];
for(int i = 0; i < N; i++)
{
newData[i] = data[i];
}
data = newData;
}
//重写tostring方法
public override string ToString()
{
StringBuilder res = new StringBuilder();
//格式化
res.Append(string.Format("Array01: count={0} capacity={1}\n", N, data.Length));
res.Append('[');
for(int i = 0;i< N; i++)
{
res.Append(data[i]);
if(i!=N-1) res.Append(',');
}
res.Append("]");
return res.ToString();
}
}
}
main方法调用:
using System.Collections;
namespace 数组
{
internal class Program
{
static void Main(string[] args)
{
/*//静态数组,数组长度不能动态扩充
int[] arr = new int[10];
//动态数组ArrayList,长度可以根据插入的元素个数动态扩充,可以插入多种不同的数据类型到ArrayList中
ArrayList arrayList = new ArrayList(10);
for(int i = 0; i < 15; i++)
{
arrayList.Add(i);
}
foreach(int i in arrayList) Console.Write(i+" ");
Console.WriteLine();
//动态数组List,长度可以根据插入的元素个数动态扩充,但是list需要指定数据类型
List<int> list = new List<int>(10);
for (int i = 0; i < 15; i++)
{
list.Add(i);
}
foreach (int i in list) Console.Write(i + " ");
Console.ReadLine();*/
Array01 a = new Array01(20);
//循环插入值
for(int i = 0;i<10; i++)
{
a.AddLast(i);
}
Console.Write(a.ToString());
Console.WriteLine();
//中间插入值:
a.Add(2, 100);
Console.Write(a.ToString());
Console.WriteLine();
//头部插入
a.AddFirst(50);
Console.Write(a.ToString());
Console.WriteLine();
//修改某一个元素值
a.Set(a.Count - 1, 99);
Console.Write(a.ToString());
Console.WriteLine();
Console.WriteLine("--------------------------------");
//删除下标位置元素
a.RemoveLast();
Console.Write(a.ToString());
Console.WriteLine();
a.RemoveFirst();
Console.Write(a.ToString());
Console.WriteLine();
a.Remove(100);
Console.Write(a.ToString());
Console.WriteLine();
Console.WriteLine("--------------------------------");
a.AddLast(50);
a.AddLast(70);
Console.Write(a.ToString());
Console.WriteLine();
for(int i = 0; i < 6; i++)
{
a.RemoveLast();
}
Console.Write(a.ToString());
Console.WriteLine();
}
}
}
最终结果:
二、装箱、拆箱
装箱拆箱只发生在ArrayList集合中,因为ArrayList底层是采用的object类型去存储元素,任何类型都能存储进去,这时候安全性不强。在开发中,强烈使用List进行开发
性能对比:
//装箱和拆箱对比
Console.WriteLine("测试值类型对象int");
int n = 1000000;
Stopwatch t1 = new Stopwatch();
Stopwatch t2 = new Stopwatch();
Stopwatch t3 = new Stopwatch();
Stopwatch t4 = new Stopwatch();
t1.Start();
List<int> list1 = new List<int>();
for(int i = 0; i < n; i++) {
list1.Add(i);//不发生装箱
int x = list1[i]; //不发生拆箱
}
t1.Stop();
Console.WriteLine("List Time:"+t1.ElapsedMilliseconds+"ms");
t2.Start();
ArrayList array1 = new ArrayList();
for (int i = 0; i < n; i++)
{
array1.Add(i);//发生装箱--值类型转化为引用类型了,因为由最初的int装箱到object类型中
int x = (int)array1[i]; //发生拆箱,由引用类型转化为值类型
}
t2.Stop();
Console.WriteLine("ArrayList Time:" + t2.ElapsedMilliseconds + "ms");
Console.WriteLine("测试引用类型对象string");
t3.Start();
List<string> list2 = new List<string>();
for (int i = 0; i < n; i++)
{
list2.Add("X");//不发生装箱
string x = list2[i]; //不发生拆箱
}
t1.Stop();
Console.WriteLine("List Time:" + t3.ElapsedMilliseconds + "ms");
t4.Start();
ArrayList array2 = new ArrayList();
for (int i = 0; i < n; i++)
{
array2.Add("X");//发生装箱--值类型转化为引用类型了,因为由最初的int装箱到object类型中
string x = (string)array2[i]; //发生拆箱,由引用类型转化为值类型
}
t2.Stop();
Console.WriteLine("ArrayList Time:" + t4.ElapsedMilliseconds + "ms");
Console.Read();
性能对比图:
总结:相对于值类型存储,一定要使用List集合来进行存储,能很大程度的提高数据安全性以及内存性能,针对于引用类型,值类型和引用类型性能消耗不大,综上所述,推荐使用List很有必要!