C#编程(三十三)----------Array类
Array类
创建数组
Array intArray1 = Array.CreateInstance(typeof(int), 5);
for (int i = 0; i < 5; i++)
{
intArray1.SetValue(33, i);
}
for (int i = 0; i < 5; i++)
{
Console.WriteLine(intArray1.GetValue(i));
}
Console.ReadKey();
分析:array类是一个抽象类,所以不能使用构造函数来创建数组(不能使用new).但除了可以使用C#语法创建数组实例之外,还可以使用静态方法CreateInstance()创建数组.如果事先不知道元素的类型,该静态方法就非常游泳.因为类型可以作为Type对象传递给CreateInstance()方法.
还可以将使用Array类创建的数组强制转换成声明为int[]的数组:
int[] intArray2 = (int[])intArray1;
CreateInstance()方法有许多重载版本,可以创建多维数组和不基于0的数组:
using System;
namespace ConsoleApplication4
{
class Program
{
static void Main(string[] args)
{
int[] lengths = { 2, 3 };
int[] lowerBounds = { 1, 10 };
Array racers = Array.CreateInstance(typeof(Person), lengths, lowerBounds);
racers.SetValue(new Person("a", "b"), 1, 10);
racers.SetValue(new Person("c", "d"), 1, 11);
racers.SetValue(new Person("e", "f"), 1, 12);
racers.SetValue(new Person("g", "h"), 2, 10);
racers.SetValue(new Person("i", "j"), 2, 11);
racers.SetValue(new Person("k", "l"), 2, 12);
Person[,] racers1 = (Person[,])racers;
Person first = racers1[1, 10];
}
}
public class Person
{
public Person()
{ }
public Person(string firstName, string lastName)
{
this.FirstName = firstName;
LastName = lastName;
}
public string FirstName { get; set; }
public string LastName { get; set; }
public override string ToString()
{
return String.Format("{0} {1}", FirstName, LastName);
}
}
}
使用SetValue()方法设置数组的元素,参数是:要设置的值,和当前索引号.
复制数组
因为数组是引用类型,所以江数组变量赋予另一个数组变量,就会得到两个引用同一数组的变量.而复制数组,会使数组实现ICloneable接口.这个接口定义的Clone()方法会创建数组的浅表副本.
如果数组的元素是值类型,则:
如果数组包含引用类型,则不复制元素,而知复制引用.
除了使用Clone()方法之外,还可以使用Array.Copy()方法创建浅表副本.但Clone()方法和Copy()方法有一个重要区别:Clone()方法会创建一个新数组,而Copy()方法必须传递阶数相同且有足够元素的已有数组.
如果需要包含引用类型的数组的深层副本,就必须迭代数组并创建对象.
排序
string[] names = {"zhao","qian","sun","li" };
Array.Sort(names);
foreach (var item in names)
{
Console.WriteLine(item);
}
Console.ReadKey();
排序后的结果:
li
qian
sun
zhao
由此看见,排序是按照字典序排列.
如果对数组使用自定义类,就必须事先IComparable接口.这个接口定义了一个方法CompareTo(),如果要比较的对象相等,该方法就返回0.如果该实例应拍在参数对象的前面,该方法就返回小于0的值.如果该实例应排在参数对象的后面,该方法就返回大于0的值.
案例:
public class Person:IComparable<Person>
{
public Person()
{ }
public Person(string firstName, string lastName)
{
this.FirstName = firstName;
LastName = lastName;
}
public string FirstName { get; set; }
public string LastName { get; set; }
public override string ToString()
{
return String.Format("{0} {1}", FirstName, LastName);
}
public int CompareTo(Person other)
{
if (other==null)
{
throw new ArgumentNullException("other");
}
int result = this.LastName.CompareTo(other.LastName);
if (result==0)
{
result = this.FirstName.CompareTo(other.FirstName);
}
return result;
}
}
编写测试代码:
static void Main(string[] args)
{
Person[] persons ={
new Person{FirstName="shan",LastName="yongxu"},
new Person{FirstName="sun",LastName="yanzhao"},
new Person{FirstName="zhu",LastName="haitao"},
new Person{FirstName="wang",LastName="jiwei"}
};
Array.Sort(persons);
foreach (var item in persons)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
这样是按照名排序,不是按照姓排序.
如果Person对象的排序方式与上述不同,或者不能修改在数组中用作元素的类,就可以实现IComparer接口或IComparer<T>接口.这两个接口定义了方法Compare().要比较的类必须实现这两个接口之一.ICompare接口的Compare()方法定义了两个要比较的参数的原因.其返回值与IComparable接口的CompareTo()方法类似.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
public enum PersonCompareType
{
FirstName,
LastName
}
public class PersonComparer : IComparer<Person>
{
private PersonCompareType compareType;
public PersonComparer(PersonCompareType compareType)
{
this.compareType = compareType;
}
public int Compare(Person x, Person y)
{
if (x==null||y==null)
{
throw new ArgumentNullException("x==y");
}
switch (compareType)
{
case PersonCompareType.FirstName:
return x.FirstName.CompareTo(y.FirstName);
case PersonCompareType.LastName:
return x.LastName.CompareTo(y.LastName);
default:
throw new ArgumentNullException("type");
}
}
}
class Program
{
static void Main(string[] args)
{
Person[] persons ={
new Person{FirstName="shan",LastName="yongxu"},
new Person{FirstName="sun",LastName="yanzhao"},
new Person{FirstName="zhu",LastName="haitao"},
new Person{FirstName="wang",LastName="jiwei"}
};
Array.Sort(persons,new PersonComparer(PersonCompareType.FirstName));
foreach (var item in persons)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
}
public class Person : IComparable<Person>
{
public Person()
{ }
public Person(string firstName, string lastName)
{
this.FirstName = firstName;
LastName = lastName;
}
public string FirstName { get; set; }
public string LastName { get; set; }
public override string ToString()
{
return String.Format("{0} {1}", FirstName, LastName);
}
public int CompareTo(Person other)
{
if (other == null)
{
throw new ArgumentNullException("other");
}
int result = this.LastName.CompareTo(other.LastName);
if (result == 0)
{
result = this.FirstName.CompareTo(other.FirstName);
}
return result;
}
}
}
分析:类PersonComparer实现了IComparer<Person>接口,可以按照FirstName或LastName对象排序.枚举PersonComparerType定义了可用于PersonComparer的排序选项:FirstName和LastName.排序方式由PersonComparer类的构造函数定义,在该构造函数中设置了一个PersonComparerType值.实现Compare()方法时用一个switch语句指定是按照FirstName还是LastName排序.
这样就可以按照你的需要来排序;是按照姓排序,还是按照名排序?
Array类还提供了Sort方法,需要将一个委托作为参数,这个参数可以传递给方法,从而比较两个对象,而不需要依赖IComparable或IComparer接口.
C#编程(三十三)----------Array类的更多相关文章
- java 编程基础 Class对象 反射 :数组操作java.lang.reflect.Array类
java.lang.reflect包下还提供了Array类 java.lang.reflect包下还提供了Array类,Array对象可以代表所有的数组.程序可以通过使 Array 来动态地创建数组, ...
- JAVA之旅(三十三)——TCP传输,互相(伤害)传输,复制文件,上传图片,多并发上传,多并发登录
JAVA之旅(三十三)--TCP传输,互相(伤害)传输,复制文件,上传图片,多并发上传,多并发登录 我们继续网络编程 一.TCP 说完UDP,我们就来说下我们应该重点掌握的TCP了 TCP传输 Soc ...
- 孤荷凌寒自学python第三十三天python的文件操作初识
孤荷凌寒自学python第三十三天python的文件操作初识 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天开始自学python的普通 文件操作部分的内容. 一.python的文件打开 ...
- 剑指Offer(三十三):丑数
剑指Offer(三十三):丑数 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baidu_31 ...
- Java集合---Array类源码解析
Java集合---Array类源码解析 ---转自:牛奶.不加糖 一.Arrays.sort()数组排序 Java Arrays中提供了对所有类型的排序.其中主要分为Prim ...
- Android线程管理(三)——Thread类的内部原理、休眠及唤醒
线程通信.ActivityThread及Thread类是理解Android线程管理的关键. 线程,作为CPU调度资源的基本单位,在Android等针对嵌入式设备的操作系统中,有着非常重要和基础的作用. ...
- javascript Array类
Array类 toString()方法和valueOf()方法,返回特殊的字符串.该字符串是通过对每项调用toString()方法,然后用逗号把它们连接在一起构成的.例如,对具有项"red& ...
- C#数组--(Array类的属性和方法)
Array 类是 C# 中所有数组的基类,它是在 System 命名空间中定义.Array 类提供了各种用于数组的属性和方法,可看作扩充了功能的数组(但不等同数组),可以使用Array类的属性来对数组 ...
- Java并发编程三个性质:原子性、可见性、有序性
并发编程 并发程序要正确地执行,必须要保证其具备原子性.可见性以及有序性:只要有一个没有被保证,就有可能会导致程序运行不正确 线程不安全在编译.测试甚至上线使用时,并不一定能发现,因为受到当时的 ...
随机推荐
- 证书(Certificate)与描述文件(Provisioning Profiles)
在使用脚本xcodebuild自动打包的时候,会用到签名证书和描述文件,我在编译的时候搞了好长时间才搞明白,下面介绍如何得到正确配置. 证书:证书是用来给应用程序签名的,只有经过签名的应用程序才能保证 ...
- nio--自己总结
阻塞/非阻塞 + 同步/异步 其实,这两者存在本质的区别,面向的对象是不同的. 阻塞/非阻塞:进程/线程需要操作的数据如果尚未就绪,是否妨碍了当前进程/线程的后续操作. 同步/异步:数据如果尚未就 ...
- java 其它可选方法
异常处理的一个原则时,只有当你在知道如何处理的情况下才捕获异常,异常处理的一个重要目标时将错误处理代码同错误发生的地点相分离. "被检查异常"强制你在还没准备好处理错误的时候被迫加 ...
- iOS仿安卓手势解锁
界面是一个九宫格的布局.九宫格实现思路. 先确定有多少列 cloum = 3; 计算出每列之间的距离 计算为: CGFloat margin = (当前View的宽度 - 列数 * 按钮的宽度) / ...
- .NetCore中使用ExceptionLess 添加操作日志
上一篇文章已经扩展了日志,下面我们在结合下处理操作日志 通常我们想到操作日志 可能想到的参数可能有 模块 方法 参数内容 操作人 操作时间 操作 Ip 下面我们就来结合这些信息添加操作日志 如果要在代 ...
- .NetCore 使用 Linq 动态拼接Expression表达式条件来实现 对EF、EF Core 扩展查询排序操作
相信在使用EF的时候对查询条件或者排序上的处理令人心烦,下面我们就来动态拼接表达式解决这一问题 当我们在查询中使用Where的时候可以看到如下参数 下面我们就来扩展 Expression<Fun ...
- 【AtCoder】AGC025题解
A - Digits Sum 枚举即可 代码 #include <bits/stdc++.h> #define fi first #define se second #define pii ...
- 007 @CookieValue绑定请求中的cookie
1.介绍 2.使用的cookie 3.index.jsp <%@ page language="java" contentType="text/html; char ...
- Mac idea 快捷键
Mac键盘符号和修饰键说明 ⌘ Command⇧ Shift⌥ Option⌃ Control↩︎ Return/Enter⌫ Delete⌦ 向前删除键(Fn+Delete)↑ 上箭头↓ 下箭头← ...
- 【*】单线程的redis为什么吞吐量可以这么大
一.Redis的高并发和快速原因 1.redis是基于内存的,内存的读写速度非常快: 2.redis是单线程的,省去了很多上下文切换线程的时间: 3.redis使用多路复用技术,可以处理并发的连接.非 ...