Web开发之C#:(9)C#常用类库2:集合
2.集合
2.1集合—ArrayList(“动态数组”)
引子:数组的长度是分配好的,不可以随时变化。集合的长度是可变的。
ArrayList:使用大小可按需动态增加的数组实现 IList 接口,集合中项(items)的类型是object的类型,即可以是各种不同的类型。
(1)增:Add()、AddRange()、Insert()、InsertRange()
int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
ArrayList arraylist = new ArrayList();
arraylist.Add("一个集合");
arraylist.Add(123);
arraylist.Add(nums); //整个数组作为一个元素加进去
arraylist.AddRange(nums); //将数组的每个元素依次加进去
arraylist.Insert(3, 999); //在集合的索引为3的位置插入一个元素
arraylist.InsertRange(1, nums); //在集合索引为1的位置,将数组元素依次加进去
arraylist.Add(123);
arraylist.Add("我是一个集合");
(2)删:Clear()、RemoveAt()、RemoveRange()、Remove()
arraylist.Clear(); //删除集合中的所有元素
arraylist.Remove(123); //移除集合中的第一个“123”的匹配项
arraylist.RemoveAt(3); //移除集合中的索引为3的元素
arraylist.RemoveRange(6, 2); //从集合中的索引为6的元素起,移除两个元素
(3)改:使用索引(同字符串)
arraylist[3] = "aaabbb"; //修改集合中的元素的值
(4)查:IndexOf、lastIndexOf、Contains(同字符串)
object arr1=arraylist[18];
int index1=arraylist.LastIndexOf(123);
int index2=arraylist.LastIndexOf("我是一个集合");
bool flag1=arraylist.Contains("123");
bool flag1=arraylist.Contains(123);
(5)综合应用
(A)Contains应用——添加项时过滤重复项
ArrayList arr1 = new ArrayList { "a", "b", "c", "d", "e" };
ArrayList arr2 = new ArrayList { "d", "e", "f", "g", "h", };
for (int i = 0; i < arr2.Count; i )
{
if (!arr1.Contains(arr2[i]))
arr1.Add(arr2[i]);
}
(B)产生10个1-100的随机数加入到集合中,要求这10个数不重复,且为偶数
ArrayList arrlist = new ArrayList();
Random r = new Random();
for (int i = 0; list.Count < 10; i )
{
int num = r.Next(1, 101); //1<= num<101
if (num%2==0&&!(arrlist.Contains(num)))
{
arrlist.Add(num);
}
}
2.2集合—HashTable(键值对集合)
引子:处理符合键值对特征的数据,实现快速查找。
//普通的集合(有序),查找使用简单遍历,效率不高。
ArrayList arrlist = new ArrayList();
arrlist.Add(new Person("张三", "732492380"));// arrlist[0]
arrlist.Add(new Person("张三1", "73422380"));// arrlist[1]
arrlist.Add(new Person("张三2", "7324232380"));// arrlist[2]
HashTable:是无序的集合,通过键来快速定位查找。
(1)增:Add( )、Table[key] = value(使用索引实现添加数据);
Hashtable table = new Hashtable();
table['d'] = "大先生";
table.Add('m',"先生");
table.Add('f',"小姐");
(2)删:Clear( )、Remove(key ) (Hashtable的元素无序,删除没有“At”和“Range”)
table.Clear();
table.Remove('a');
(3)改:Table[key] = value; 使用键索引!
table['d'] = "大先生";
(4)查:Table[key]、ContainsKey( )、ContainsValue( ) 。键是用来查找的,所以不允许重复。
objectobj=table['m'];
bool flag1=table.ContainsKey('z')
bool flag2=table.ContainsValue("西西")
附:集合应用之分拣奇偶数(将字符串内容重新排序奇数在前偶数在后)
static void Main(string[] args)
{
string str = "27 9 8 33 2 29 57 28";//处理成"27 9 33 29 57 8 2 28"
string[] strs = str.Split(' ');
ArrayList arrOdd = new ArrayList();
ArrayList arrEven = new ArrayList();
for (int i = 0; i < strs.Length; i )
{
int num = Convert.ToInt32(strs[i]);
if (num % 2 == 0)
{
arrEven.Add(strs[i]);//偶数
}
else
{
arrOdd.Add(strs[i]);//奇数
}
}
arrOdd.AddRange(arrEven);
str = string.Join(" ", arrOdd.ToArray()); //方法1:VS2008不可以,VS2010可以
StringBuilder sb = new StringBuilder();
for (int i = 0; i < listOdd.Count - 1;i )
{
sb.Append(string.Format("{0} ", listOdd[i]));
}
sb.Append(listOdd[listOdd.Count - 1]);
string res = sb.ToString(); //方法2:VS2008可以,VS2010可以
//得到string类型元素的数组,需强制转换为子类类型string[]
string[] ss = (string[])arrOdd.ToArray(typeof(string));
string s =string.Join(" ", ss); //方法3:VS2008可以,VS2010可以
2.3集合—泛型集合
引子:ArrayList和HashTable元素的类型是object,使用中经常需要做类型转换。
string strnum = "2 9 8 3 2 2 7 8";
string[] strArr=strnum.Split(' ');
ArrayList arrlist = newArrayList();
arrlist.AddRange(strArr);
Array arr =arrlist.ToArray(typeof(string));
string[] ss = (string[])arr;
//如果上面ToArray方法不使用typeof(string),则得到的Object类型的数组,转换出错
//无法将类型为“System.Object[]”的对象强制转换为类型“System.String[]”
char[] charArr = { '2', '4', 'h', '4', '3', 'd' };
ArrayList arrlist1 = newArrayList();
arrlist1.AddRange(charArr);
Array arr1 = arrlist1.ToArray(typeof(char));
char[] c = (char[])arr1;
//如果ToArray方法中不使用typeof(char),则得到的Object类型的数组,转换出错
//无法将类型为“System.Object[]”的对象强制转换为类型“System.Char[]”
如果一个集合中存放的多种类型的数据,转换时还可能出现异常。
泛型集合:泛型集合的出现正是考虑到集合中类型问题的不方便。
泛型集合先指定类型,再使用,避免了使用过程中的类型转换。
命名空间:System.Collections.Generic;
使用泛型集合前,指定集合类型,在尖括号中填入需要使用的类型,这个集合就是专门为这个类型定制的集合,所有方法使用的参数均会变成相关的类型。
1)List<T>集合(对应ArrayList,使用类似)
List<string> liststr = new List<string>();
List<char> listchar = new List<char>();
List<Person> listper = new List<Person>();
Add()方法,自动匹配参数类型。
ToArray()方法,自动返回相应类型的数组,不需要指定typeof参数了
liststr.ToArray(); //返回string[]类型数组
listchar.ToArray(); //返回char[]类型数组
listper.ToArray(); //返回Person[]类型数组
2)Dictionary<TKey,TValue>集合(对应HashTable,使用类似)
应用:参考以下foreach。
2.4 集合的遍历foreach( )
像HashTable、Dictionary这样的无序集合,无法通过数字来索引,不能用for循环实现遍历只能采用Foreach( )来遍历。(有序集合则可以使用for循环或者Foreach())
注:KeyValuePair<TKey, TValue>是泛型结构,只能对应Dictionary的foreach输出,而不能是非泛型的HashTable的。
语法:public struct KeyValuePair<TKey, TValue>
C# 语言中的 foreach 语句需要集合中的元素类型,是 KeyValuePair(TKey, TValue) 类型。
因为基于 IDictionary(TKey, TValue) 的集合中的每个元素都是一个键/值对,因此元素类型既不是键的类型,也不是值的类型。
1)HashTable的foreach( )输出
Hashtable table = new Hashtable();
table.Add("张无忌", new Person("张无忌", "13423234923"));
table.Add("赵敏", new Person("赵敏", "1347237864923"));
foreach (string item in table.Keys) //输出键
{
Console.WriteLine(item);
}
foreach (Person p in table.Values) //输出值
{
Console.WriteLine("{0}\t{1}",p.Name,p.Phone);
}
foreach (DictionaryEntry o in table) //输出键和值
{
Console.WriteLine("{0}\t{1}", o.Key, o.Value); //o.Value只得到Person类型,没有得到成员
}
2)Dictionary的foreach( )输出
Dictionary<string,Person> dic = new Dictionary<string,Person>();
dic.Add("张无忌", new Person("张无忌", "13423234923"));
dic.Add("赵敏", new Person("赵敏", "1347237864923"));
foreach (KeyValuePair<string, Person> kvp in dic)
{
Console.WriteLine("{0}\t{1}\t{2}", kvp.Key, kvp.Value.Name,kvp.Value.Phone);
//泛型的好处,得到了Person的成员!
}