C#数据容器
字符串(String)
构造
string str = "this is a string"; //使用字面值初始化;
str = new string(charr_array); //使用字符数组初始化;
str = new string(ch, n); // 重复字符n次;
查找
tf = name.StartsWith("B")
正则表达式
Regex in System.Text.RegularExpressions
Regex.Match()
运算
String类有很多字符串修改方法,但是String对象本身是不会改变的;修改的结果由返回值返回,只能对变量进行重新复制,让它指向内存中的另一块区域。
要在源字符串直接做修改,则改用StringBuilder类。
拼接
使用+或Concat方法,将对象的字符串表示(ToString())拼接形成一个字符串。
String.Concat(obj1,obj2,...);
String.Concat({obj1,obj2,....})
+运算符作用对象包含字符串时,作为拼接运算符。
字符串内插
string greeting = 'Hello', firstName = 'Bob';
string message = $"{greeting} {firstName}!";
可以同时使用逐字文本前缀符号
@和字符串内插$符号。
格式化
使用格式声明对参数进行格式化并输出字符串。
String.Format("{0}...{1}...", arg1, arg2, ...)
支持格式化语法的类似方法包括:
StringBuilder.AppendFormat、Console.WriteLine、TextWriter.WriteLine、Debug.WriteLine等。
复合格式声明
复合格式由参数索引,对齐声明和格式声明组成)。
{ index[,[+-]alignment][:formatString]}
多个格式项可以引用同一个参数,索引顺序与参数顺序无关。
对齐方式:alignment的绝对值代表了字符串的最小长度(字符串长度超过该值,则alignment无效);正值代表右对齐,负值代表左对齐,如果需要则填充空白。
不同类型的对象有不同的格式声明(格式声明在不同国家/语言有不同输出),其中: 标准数字格式包括:
| 格式 | 名称 | 说明 |
|---|---|---|
| `C | c[n]` | 货币格式 |
| `D | d[n]` | 整型数字 |
| `E | e[n]` | 指数计数法 |
| `F | f[n]` | 定点计数法 |
| `G | g[n]` | 科学计数法 |
| `P | p[n]` | 百分比 |
| `X | x` | 十六进制整型 |
自定义数值格式:
标准日期和时间:
| 格式 | 说明 | 示例 |
|---|---|---|
d | 短日期 | 6/15/2009 |
D | 长日期 | Monday, June 15, 2009 |
g | 短日期时间 | 6/15/2009 1:45 PM |
G | 长日期时间 | 6/15/2009 1:45:30 PM |
自定义日期和时间类型:获取日期时间中的字段
| 格式 | 说明 | 格式 | 说明 |
|---|---|---|---|
y/yy | year(0-99/00-99) | yyyy | year(0000-9999) |
M/MM | month(1-12/01-12) | MMM/MMMM | month name (short/long) |
d/dd | day-of-month | ||
ddd | day-of-week, short (Mon) | dddd | day-of-week, long (Monday) |
h/hh | hour(1-12/01~12) | H/HH | hour(0-23/01-23) |
m/mm | minute(0-59/00-59) | ||
s/ss | second(0-59/00-59) | ||
t/tt | AM/PM | ||
g/gg | A.D. or B.C. | f/ff/fff/... | .x/.xx/.xxx/... seconds |
K | time zone | z/zz | timezone hour offset |
: | 时间分隔符 | / | 日期分隔符 |
TimeSpan类型
枚举类型
比较
bool Equals(string value, StringComparison comparisonType);
bool EndsWith(string value, comparisonType)
comparisonType:比较规则包括{Ordinal, OrdinalIgnoreCase }。当调用字符串比较函数如String.Compare、String.Equals、String.IndexOf,应该总是使用带有comparisonType的函数指定比较规则。省略comparisonType,则该方法按照Ordinal规则(case-sensitive和culture-insensitive)进行比较。
StringBuilder
StringBuilder str = new StringBuilder();
str.Append(value);
编码
Encoding
数组
数组是用于存储多个同一类型变量的数据结构。数组是引用类型,派生于抽象基类Array类,所以数组也能当做类来使用。
声明
声明数组:
type[] arrayname; // 1-D
type[,,,...] arrayname; // multi-dimension array
数组的类型由值类型type和“[]”指定的维数决定。数组元素的类型可以是基本类型也可以是引用类型(甚至可以是数组类型)。数组的维数根据“[]”中的“,”的个数确定,维数=逗号个数+1。
数组初始化时的维度应该与数组声明一致,也可以将数组的声明和初始化放到一起。
type[] arrayname = new type[size];// initialize as default
数组在初始化时确定其维数和长度,且不能在实例存在期间修改。
数组的每个维度的长度或初始化列表可以省略,但两者不能同时省略:如果省略初始化列表则使用元素类型的默认值初始化数组;如果省略长度,则根据初始化列表元素的长度确定数组的长度;如果两者同时给出,则必须保证维数和长度声明与初始化列表一致。
arrayname = new type[size]{initialize_list};
arrayname = new type[m,n]{{list1},{list2},...{listm}};
arrayname = new type[,]{{list1},{list2},...{listm}};
arrayname = {{list1},{list2},...{listm}};
锯齿数组
锯齿数组(或称为交错数组)的每个元素是数组。
type [,...][,...] arrayname;
声明中,第一个[,...]是锯齿数组的维度声明,第二个是锯齿数组元素的维度声明。虽然每个子数组的维数由声明确定,但是在初始化时,子数组之间各相应维度的长度可以各不相同,因此称为锯齿/交错数组。使用初始化列表赋值:
int[][,] jag_array = { // 使用初始化列表
new int[,]{{1,2,3},{2,4,1}},
new int[,]{{2,1},{4,2}},
new int[,]{{1,3,5},{2,1,3},{3,4,5}}
...
};
int[][,] jag_array = new int[M][,]{...}
先使用new初始化交替数组本身,再初始化数组的每个元素:
int[][] jag_array = new int[M][];
for(int i=0; i<M; ++i){ //对每个元素逐个赋值
jag_array[i] = new int[len_i];
}
可以定义高维的锯齿数组::
int[,][] multi_array = {
{new int[]{1,2,3}, new int[]{2,1}},
{new int[]{1,3}, new int[]{2,1,3}}
};
数组访问
下标
普通数组的访问方法是array[i,j,...]。
交错数组的访问方法是array[i][j,k,...]。
迭代
使用循环语句for。
// 普通数组
for(int i = 0; i<M; ++i){
for(int j=0; j<M; ++j){
Console.Write("{0:G} ", array2d[i,j])
}
}
使用foreach语句,高维数组视为一维数组迭代。
foreach(int x in array2d){
Console.Write("{0:G} ", x)
}
foreach只能读元素,而不能修改数组。
数组维数和长度
array.Length; // 数组的元素总数
array.GetLength(dim); //数组的一个维度的长度;
容器
容器类型
泛型和非泛型容器
泛型容器(System.Collections.Generic)用于储存同一类型的元素,具有强类型要求,从而提供更好的类型安全以及更好的性能。
非泛型容器(System.Collections)存储的元素不要求特定的类型,所有元素都当作Object对象。非泛型集合(如 ArrayList)不建议使用,并且保留用于兼容性目的。大多数非泛型版本容器都不支持应用商店应用。
| 容器名 | 泛型 | 非泛型 | 说明 |
|---|---|---|---|
| 列表 | List<T> | ArrayList | 容器的大小可以增加或减小。提供查找、排序和修改等等方法。 |
| 链表 | LinkedList<T> | ||
| 有序列表 | SortedList<Tk, Tv> | SortedList | 使用ICompare接口根据对元素进行排序。 |
| 队列 | Queue<T> | Queue | 具有先进先出(FIFO)操作规则。 |
| 栈 | Stack<T> | Stack | |
| 映射 | Dictionary<Tk,Tv> | HashTable | 基于键值或Hash值索引元素。 |
| 有序映射 | SortedDictionary<Tk, Tv> | ||
| 集合 | HashSet<T> | ||
| 有序集合 | SortedSet<T> |
专用容器
System.Collections.Specialized
包含专用的强类型的结合。例如:链表字典,位向量,字符串容器。
并发容器
System.Collections.Concurrent
提供高效地线程安全的容器访问操作。当从多线程访问容器时,应该使用本空间中的对应容器类型代替System.Collections.Generic和System.Collections中的类型。
容器公共特性
容器基于ICollection、IList和IDictionary接口及其泛型版本。IList和IDictionary派生自ICollection。
容器接口包括:
-
ICollection<T> -
IList<T> -
IDictionary<T> -
IComparer<T> -
IEqualityComparer<T> -
IEnumerator<T> -
ISet<T>
枚举元素
容器类型继承IEnumerable/IEnumerable<T>,因此可以通过foreach语句进行枚举。继承自IEnumerable<T>的容器还可以通过LINQ进行查询。LINQ通常更简洁且可读性更强,提供筛选、排序以及分组能力,且能提高性能。
复制到数组
通过CopyTo方法将元素按照枚举顺序复制到一维数组中。
容量和计数
-
Capacity在不重新分配空间前,容器的容量。
Capacity不应该设置为比Count小的值,否则引发异常(ArgumentOutOfRangeException)。 -
Count容器包含元素的数量。
一致的下界
元素从0起索引。Array可以自定义起始索引。
比较
Contains, IndexOf,
LastIndexOf以及Remove等方法使用等式比较。泛型容器的比较方案:如果类型T继承了IEquatable\<T\>接口,则使用接口的Equals函数;否则使用Object.Equals。
排序顺序
BinarySearch和Sort使用一个顺序比较器,用于比较容器的元素或与给定的值比较。
default comparer:依赖参与比较的对象至少有一个实现了IComparable接口。泛型类型的比较器方案:如果T实现了IComparable<T>接口,则默认比较器为IComparable<T>.CompareTo(T);如果T实现了IComparable接口,则默认比较器为IComparable.CompareTo(T);如果T没有实现以上接口,则必须显示提供比较器。
元素排序
SortedList/SortedList<TKey, TValue>、SortedDictionary<TKey, TValue>
实现
IDictionary/``IDictionary<TKey, TValue>`接口,每个元素是key/value对。元素根据
ICompare/ICompare<T>接口排序。每个类提供仅返回key或value的属性。
HashTable/Dictionary<TKey,TValue>
按key排序。
迭代器
迭代器用于容器的迭代访问操作。
使用foreach语句来调用迭代器。
访问容器的接口
容器相关操作
Queue
- Dequeue/Enqueue
Stack
-
Push/Pop
Peek
LINQ
You can write LINQ queries in C# with SQL Server databases, XML documents, ADO.NET Datasets, and any collection of objects that supports IEnumerable or the generic IEnumerable<T> interface.
All LINQ query operations consist of three distinct actions:
-
Obtain the data source.
-
Create the query.
-
Execute the query.
数据源(Data Source)
LINQ数据源可以是支持IEnumerable<T>接口以及继承该接口的任何实例。支持IEnumerable<T>及其派生接口(如IQueryable<T>)的类型被称为可查询类型。
Enumerable类提供一组用于查询实现IEnumerable<T>的对象的静态方法。
XElement
Northwnd
查询
查询语法:从对象序列中查询满足条件的对象,并返回筛选结果。
var seattleCustomers = from customer in customers
where customer.City == "Seattle"
[orderby customer.ID]
select customer.Name; // or select customer
from指定数据源;where应用过滤条件;select语句指定返回元素的类型。
var localDistributors =
from customer in customers
join distributor in distributors on customer.City equals distributor.City
select new { Customer = customer, Distributor = distributor.ID };
return a new type
var scoreQuery = from student in students
from score in student.Scores
where score > 90
select new { Last = student.LastName, score };
执行查询
延迟执行
查询变量本身只储存查询命令,当通过foreach语句对查询变量进行迭代时,才真正执行查询。
强制立即执行
统计函数:Count、Max、Average、First
强制执行:ToList()或ToArray();
在查询语句之后,立即使用foreach语句。
List
List实现的接口
IndexOf、LastIndexOf和Remove方法使用类型T的默认比较函数(EqualityComparer<T>.Default属性)判断相等。如果T实现了System.IEquatable<T>接口,则返回包含该接口的EqualityComparer,否则返回包含由T提供的Objects.Equals和Objects.GetHashCode的EqualityComparer。
Contains方法使用默认的相等比较函数判断相等。如果T实现了IEquatable<T>接口,则调用IEquatabale.Equals方法,否则使用Object.Equals。
Sort、BinarySearch使用类型T的默认的比较函数(Comparer<T>.Default属性)。如果T实现了IComparable<T>接口,则默认比较函数为IComparable<T>.CompareTo(T);否则如果实现了IComparable接口,则默认比较函数是IComparable.CompareTo();如果T没有实现比较接口,则必须显式提供比较委托。
List允许引用类型取值为null,以及重复元素。
ArrayList
ArrayList的容量是自动扩充的(类似于字符串,与一般数组不同);
ArrayList只能是一维的;
构造函数
List<T>() //with default capacity
List<T>(Int32 Capacity)
属性
T this[int index] { get; set; }
按序号访问指定的元素。
方法
插入
void Add( T item );
void Insert( int index, T item )
Add添加元素到列表末尾。
Insert在指定序号处插入元素,指定的序号小于0或大于Count会引发异常(ArgumentOutOfRangeException)。
删除
bool Remove( T item );
int RemoveAll( Predicate<T> match );
void RemoveAt( int index )
void Clear();
void TrimExcess()
Remove移除出现的第一个指定元素,如果成功移除返回true;如果指定元素不在列表中或移除失败,返回false。
RemoveAll移除满足条件的所有元素,并返回移除元素的数量。
RemoveAt移除指定位置的元素,指定的序号小于0或大于Count会引发异常(ArgumentOutOfRangeException)。
Clear移除列表中的所有元素。
TrimExcess将列表的容量缩小至元素实际数量。
查找
bool Contains( T item );
bool Exists( Predicate<T> match );
T Find( Predicate\<T\> match ); // FindLast
int FindIndex( Predicate\<T\> match ); // FindLastIndex
int IndexOf( T item ); // LastIndexOf
List<T> FindAll( Predicate<T> match );
Contains判断一个元素是否包含在列表中。(This method determines equality by using
the default equality comparer, as defined by the object's
implementation of the IEquatable<T>.Equals method forT (the type of
values in the list).)
Exists判断是否存在匹配给定条件的元素。match定义了查找元素的条件。列表的元素分别被传递给match函数,当找到匹配元素时停止操作。
Find查找满足条件的元素并返回第一个元素。
FindAll查找所有满足条件的元素并返回。
FindIndex查找满足条件的元素并返回第一个元素序号。
IndexOf查找指定的元素,并返回第一个元素的序号。
排序
void Reverse()
反转整个列表的元素排列顺序。
void Sort()
void Sort( Comparison<T> comparison )
void Sort( IComparer<T> comparer )
使用comparison对列表排序。
使用comparer进行排序。
Dictionary
System.Collections in mscorlib
代表非一般性的键值对(key/value)的容器。每一个键值对储存在一个DictionaryEntry对象中。
每个键值对必须具有唯一的键名,实现类型可以决定是否允许键名为null。值可以是null且不要求唯一性。
IDictionary的实现类型分为三类:只读、固定长度、可变长度。
属性
按键名key访问元素:
Object this[ Object key] { get; set; }
键名和值
ICollection Keys { get; }
ICollection Values { get; }
值的顺序与Keys返回的键名的顺序对应。
DictionaryEntry定义字典的键值对。
Object Key { get; set; }
Object Value { get; set; }