整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Delphi基础教程图文版之泛型容器

Delphi基础教程图文版之泛型容器

方描述

Unit that implements generic container classes to group data items in arrays, dictionaries, lists, stacks, queues, and more.

译文:实现泛型容器类的单元,以在数组中对数据项进行分组,词典,列表,堆栈,队列等。

起初在接触到Delphi的时候我以为没有这一部分内容,所有的都要自己实现,此处请原谅我的无知。。。。

关于从那个版本开始支持泛型的,我在官方文档上没有找到对应的说明,也可能是我英语太菜,在官网迷路了。

根据百度得来的结果2007的版本没有(真百度的)支持2009的版本(万一老师的博客上引用的也是这个版本)开始出现,也就是最早支持泛型容器的版本应该是Delphi2009

聊泛型容器避不开的就是泛型的概念,之前看哔哩哔哩的网友留言从泛型一节就是开始懵逼了。其实大可不必,泛型可以理解为一个变量,它的值是一个具体的类型

嗯,其实也可以把它当作孙大圣,它可以变成任何东西

Collections单元

在这个单元内一共定义了13个容器类,我们在其中甚至可以看到线程队列。那么问题来了,我们需要精通或者学习所有的类吗?答案是否定的

容器类就我个人的理解其实一共有两大表现形式,一种是列表形式的像数组,而另一种形式则以 Key,Value 成对的形式。也就是说我们从中选择两个比较有代表性的类进行学习即可。下面是我选择的两个类

  • System.Generics.Collections.TList:很明显这个是列表
  • System.Generics.Collections.TDictionary:Dictionary这个单词翻译成中文是字典的意思,不知道为啥这么起名,它是K,V形式的代表

注意:在单元内我们还可以看到相似的类例如 System.Generics.Collections.TObjectList<T> 和 System.Generics.Collections.TList<T>区别在于带有Object的类会在删除元素时释放对象,而没有带Object的不会释放

API代码

针对容器类学习的总原则是围绕增、删、改、查这几个核心的API功能即可,其他的就只能现用现查了,不知道别人写代码是什么习惯,我写代码的时候帮助文档基本上都是开着的。。。

下面是针对两个容器类的代码实现

TList

实体类(TStudent)代码

type

    TStudent=class
    private
        FName: string;
    public
        property Name: string read FName write FName;
        // 构造方法
        constructor Create; overload;
        // 有参构造方法
        constructor Create(FName: string); overload;
    end;

constructor TStudent.Create;
begin

end;

constructor TStudent.Create(FName: string);
begin
    Self.FName :=FName;
end;

操作类(即增、删、改、查),我没有使用内联,几次想用都删了

uses
    System.Generics.Collections, System.SysUtils;

var
    // 文档上的定义是TList<T>,而我们的定义尖括号中的是TStudent,这就是泛型的用法
    StudentList: TList<TStudent>;
    // 循环中使用获取TList成员
    Stu: TStudent;

begin
    // 初始化学生列表
    StudentList :=TList<TStudent>.Create;
    StudentList.add(TStudent.Create('小强'));
    StudentList.add(TStudent.Create('萧蔷'));
    StudentList.add(TStudent.Create('小黑'));
    StudentList.add(TStudent.Create('小白'));
    StudentList.add(TStudent.Create('小黄'));

    // 开始之前输出一次
    for Stu in StudentList do begin

        Writeln('学生信息是:' + Stu.Name);
    end;

    // 泛型容器自带的删除函数,偷个懒
    StudentList.Delete(0);

    // 修改,查询到指定的学生,修改其值即可
    StudentList.Items[0].Name :='小白';


    // 查询,其实和数组的操作没有太大区别
    for Stu in StudentList do begin

        Writeln('学生信息是:' + Stu.Name);
    end;

end.

TDictionary

此类容器的特点是 key 唯一,并且几乎所有的操作都是根据 key 来的

改造下实体类(TStudent)增加一个属性,代码如下

type

    TStudent=class
    private
        FName: string;
        FId: string;
    public
        property Name: string read FName write FName;
        property Id: string read FId write FId;

        // 构造方法
        constructor Create; overload;
        // 有参构造方法
        constructor Create(FName: string; FId: string); overload;
    end;

constructor TStudent.Create;
begin

end;

constructor TStudent.Create(FName: string; FId: string);
begin
    Self.FName :=FName;
end;

操作类(即增、删、改、查)


{注意单元的引用}
uses
    System.Generics.Collections, System.SysUtils;

var
    // 文档上的定义是TList<T>,而我们的定义尖括号中的是TStudent,这就是泛型的用法
    StudentMap: TDictionary<string, TStudent>;
    // 循环中使用获取TList成员
    Key: string;
    Student,Stu: TStudent;

begin
    // 初始化学生列表
    StudentMap :=TDictionary<string, TStudent>.Create;
    // 此处的添加其实并不是太好,根据文档描述,当我们添加的元素的key已经存在会抛出异常
    // 建议使用AddOrSetValue
    StudentMap.add('1001', TStudent.Create('1002', '小强'));
    StudentMap.add('1002', TStudent.Create('1001', '萧蔷'));
    StudentMap.add('1003', TStudent.Create('1003', '小黑'));
    StudentMap.add('1004', TStudent.Create('1004', '小白'));
    StudentMap.add('1005', TStudent.Create('1004', '小黄'));

    // 注意此处获取是key,也就是1001 1002这些东西
    for Key in StudentMap.Keys do begin

        // 获取到key之后,再根据key获取对应value也就是学生对象
        // 这里的获取方式有点儿任性居然要的是一个指针,而不是直接返回
        StudentMap.TryGetValue(Key, Student);
        // 最好判断一下,否则容易出现空指针
        if (Student <> nil) then
            Writeln('学生信息是:' + Student.Name)
    end;

    // 删除元素,无论什么操作都是通过key去操作,因为key是不可以重复的
    StudentMap.Remove('1005');

    // 修改,没有就添加,有就更新
    StudentMap.AddOrSetValue('1004', TStudent.Create('1004', '小黄'));

    // 直接获取value
    for Stu in StudentMap.values do begin
        // 最好判断一下,否则容易出现空指针
        if (Stu <> nil) then
            Writeln('学生信息是:' + Student.Name)

    end;
end.

参考资料

万一的博客:https://www.cnblogs.com/del/category/113556.html

官方文档:http://docwiki.embarcadero.com/Libraries/Sydney/en/System.Generics.Collections

ttp://www.gotapi.com/

语言:英语

简介:HTML,CSS,XPATH,XSL,JAVASCRIPT等API的查询网站。

http://www.w3schools.com/

语言:英语

简介:W3C制定的标准诸如XML,HTML,XSL等等的在线学习教程。

http://www.xml.org.cn/

语言:中文

简介:可以说是XML的中国官方网吧。W3C标准的翻译组织与XML系列技术交流社区.

http://www.connectionstrings.com/

语言:英语

简介:这里几乎收集了所有的数据库连接字符(connectionstring)了。

http://www.itpub.net/

语言:中文

简介:我个人认为是国内最专业的综合性行业性技术类社区.

http://www.netvtm.com/

语言:中文

简介:内容多翻译于w3schools.com,少有原创。不过还是应该鼓励精品翻译。

http://www.regexlib.com

语言:英语

简介:正则表达式库。搜索正则表达式用。

http://www.rexv.org/

语言:英语

简介:用Ajax开发的在线正则表达式验证器.

http://www.koders.com/

语言:英语

简介:代码搜索引擎,可以搜索几十种语言的代码。

http://www.123aspx.com/Rotor/

语言:英语

简介:.Net Frameworks的源代码。

语言:中文

简介:孟宪会的资料站,虽资料大多比较简单,却解决了开发中的大部分问题?!

http://www.dofactory.com/Patterns/Patterns.aspx

语言:英语

简介:23种设计模式的实现参考。特点是UML+精练的示例代码+简洁的解说风格。

http://www.open-open.com/

语言:中文

简介:Java开源大全,如果你用.NET,照着它的名字前加N找找应该都有吧 ?!:)

http://www.riacn.com/

语言:中文

简介:我认为是国内少有的RIA专业技术站于交流社区.

http://www.cnpaf.net/

语言:中文

简介:中国协议分析网,很全面的协议资料网。

http://www.pinvoke.net/

语言:英语

简介:通过.net调用win32等非受控API的资料大全。

http://bbs.51js.com/

语言:中文

简介:无忧脚本,专业的脚本技术社区。

http://www.c-sharpcorner.com/

语言:英语

简介:C# Corner,学习c#的好地方.

http://blog.csdn.net/group/experts/

语言:中文

简介:CSDN专家群,汇集CSDN专家的电子报.

http://www.codeproject.com/

语言:英语

简介:有很多可学习的示例代码,特点是丰富,深入浅出.

http://www.gotdotnet.com/

语言:英语

简介:微软开发维护的关于.net framework交流社区.

http://www.sourceforge.net/

语言:英语

简介:全球最大的开源软体站点

http://www.asp.net/QuickStart/

语言:英语

简介:Microsoft .NET Framework SDK QuickStart Tutorials

http://www.matrix.org.cn/

语言:中文

简介:与 Java 共舞,Java优秀的专业社区,文章质量很高.做.Net的朋友也可以从其借鉴很多知识.

JAVA学习模板——学习流程

http://www.7zcn.com/javastep/StudyJavaInfo.html

SUN中国技术社区

http://developers.sun.com.cn/

综合网站 -

数动在线http://www.shudoo.com/(电脑报) -http://www.csdn.net/ -

比特网IT知识库http://know.chinabyte.com/index.php/%E9%A6%96%E9%A1%B5 -

至顶网http://www.zdnet.com.cn/ -

计世网http://www.ccw.com.cn/ -

中国IT实验室http://www.chinaitlab.com/ -

天极网http://www.yesky.com/ -

赛迪网http://www.ccidnet.com/ -

全球流量查询http://www.alexa.com/ -

Java网站 -

Java软件社区http://www.javaeye.com/ -

java世纪网http://www.java2000.net/ -

JAVABUGShttp://bugs.sun.com/JAVA漏洞 -

http://www.mldnjava.cn/java.htm -

HEY JAVA技术社区http://www.heyjava.com/ -

ACCP教程网http://www.accptech.com/index.html

论坛网站 -

美河论坛http://www.eimhe.com/bbs/ -

魔http://bbs.mldn.cn/ -

http://bbs.chinajavaworld.com/index.jspa

技术网站 -

apache的ANThttp://ant.apache.org/bindownload.cgi -

IBM http://www.ibm.com/developerworks/-

IDE-

Eclipse官网http://www.eclipse.org/downloads-

MyEclipse官网http://www.myeclipseide.com/

软件测试

软件测试网http://www.51testing.com/

1 程序员论坛:http://www.gxcxy.com

2 J2me社区 http://www.j2meforums.com/forum/

3 csdn http://www.csdn.net/

4 Vc知识库 http://www.vckbase.com/

5 codeproject http://www.codeproject.com/

6 程序员联合开发网 http://www.pudn.com/

7 看雪学院 http://www.pediy.com

8 蓝色理想 http://www.blueidea.com/

9 博客园 http://www.cnblogs.com/

10 Nuix应用开发社区 http://chinaunix.net/

11 javaeye http://www.javaeye.com

12 It人网 http://www.iteer.net/

13 中国人才热线 http://www.cjol.com/

14 天涯论坛 http://www.tianya.cn/

15 风云的blog http://blog.codingnow.com/

16 新浪科技频道 http://tech.sina.com.cn/

17 phpchina http://www.phpchina.com/html/index.html

18 游戏开发资源网 http://www.gameres.com/

19 网络游戏第一门户 http://www.17173.com/

20 我爱研发网 http://www.52rd.com/

21 Msdn中文网 http://www.microsoft.com/china/MSDN/DeveloperCenter/default.mspx

22 大富翁编程网站 http://www.delphibbs.com/

23 Delphi盒子 http://www.2ccc.com/

24 C++buillder研究 http://www.ccrun.com/

25 It论坛 http://bbs.itren.cn/

26 Java开源大全 http://www.open-open.com/

27 codegurn http://www.codeguru.com/

28 编程爱好者 http://www.programfan.com/

29 Java中文站 http://www.java-cn.com/

30 reactos http://www.reactos.org/zh/index.htm

31 开源力量 http://www.opensourceforce.org/

32 电脑编程技巧与维护 http://www.comprg.com.cn/

33 中国电子网 http://21ic.com/

34 编程中国 http://www.bc-cn.net/

35 嵌入式开发论坛 http://www.cevx.com/bbs/

36 电脑爱好者 http://www.cfan.com.cn/

37 sybase中国 http://www.sybase.com.cn/gvswse/site/china/index.jsp

38 pbdr http://www.pbdr.com/

39 apache http://www.apache.org

40 rootkit http://www.rootkit.com/index.php

41 驱动开发网 http://www.driverdevelop.com/first.html

42 安全焦点 http://www.xfocus.net/

43 cnbeta网友媒体与言论平台 http://www.cnbeta.com/

44 fyter的博客 http://www.fyter.cn/Default.aspx

45 asp.net控件 http://www.devexpress.com/

46 operamask http://www.operamasks.org/

47 中国源码网 http://www.yuanma.org/

48 sawin软件研发之窗 http://www.sawin.cn/

49 电脑教育与WEB教育在线 http://210.40.7.188/

50 中国dos联盟 http://www.cn-dos.net/

51 中国bios联盟 http://www.biosren.com/index.php

52 bioscentral http://bioscentral.com/

53 eda专业论坛 http://www.edacn.net/bbs/

54 诺基亚论坛 http://forum.nokia.com.cn/sch/index.html

55 计算机科学论坛 http://www.ieee.org.cn/index.asp

56 ibm developerworks 中国 http://www.ibm.com/developerworks/cn/

57 w3 http://www.w3.org/

58 网页设计师 http://www.w3cn.org/

59 中国万维网联盟 http://www.w3china.org/index.htm

60 豆瓣 http://www.douban.com/

61 程序员门户站:http://www.gxcxy.com

62 软件商务网 http://www.bizsofts.com/

63 sun http://www.sun.com/

64 google code http://code.google.com/

65 google 开发人员主页 http://code.google.com/intl/zh-CN/

66 the official microsoft asp.net http://www.asp.net/

67 microsoft IIS http://www.iis.net/default.aspx?tabid=1

68 荣耀 http://www.royaloo.com/index.html

69 侯捷网站 http://jjhou.csdn.net/

70 java大本营 http://www.javadby.com/

71 比特网 http://www.chinabyte.com/

72 51cto http://www.51cto.com/

73 infoq http://www.infoq.com/

74 博客堂 http://blog.joycode.com/

75 嵌入式开发网 http://www.embed.com.cn/

76 嵌入式开线 http://www.mcuol.com/

77 中嵌网 http://www.chinaeda.cn/

78 酷勤网 http://www.kuqin.com/

79 红联linux门户 http://www.linuxdiyf.com/

80 itpub技术门户 http://www.itpub.net/

81 程式设计俱乐部 http://www.programmer-club.com/index.asp

82 uml软件工程组织 http://www.uml.org.cn/index.asp

83 delphi园地 http://www.delphifans.com/

84 theserverside http://www.theserverside.com/

85 中国donet俱乐部 http://www.chinaaspx.com/

86 编程王 http://www.kingofcoders.com/

87 it168 http://www.it168.com/

88 open source software in c# http://csharp-source.net/

89 中国IT实验室 http://www.chinaitlab.com/

90 落伍者站长论坛 http://www.im286.com/

91 中国站长站 http://www.chinaz.com/

92 asp.net源码下载专业站 http://www.51aspx.com/

93 it职业工程师 http://www.51myit.com/

94 太平洋电脑网 http://www.pconline.com.cn/

95 乘风原创程序 http://study.qqcf.com/

96 网易学院 http://tech.163.com/school/

97 程序设计/程序开发类教程 http://www.pcvz.com/Program/Programs/Index.html

98 算法源码吧 http://www.sfcode.cn/

99 codegurn http://www.codeguru.cn/

100 得益网 http://www.netyi.net/

101 中国eclipse社区 http://www.eclipseworld.org/bbs/

102 项目管理者联盟 http://www.mypm.net/

103 栖息谷 http://www.21manager.com/

104 J2me开发网 http://www.j2medev.com/bbs/index.asp

105 卓越亚马逊 http://www.amazon.cn/

WEB技术:

WEB前端开发 http://www.css88.com/

Ext JS官方网 http://www.extjs.com/

Ext JS中文资料 http://www.extjs.org.cn/

义:不同的地理信息系统或地理信息系统与其他信息系统之间实施数据双向交换时采用的数据格式

引自百度百科

据百度百科上的描述数据交换这个词最早是在《地理信息系统名词》第二版,很明显不是用来做编程的。在编程方面数据交换格式仅仅是一种格式,当前主流使用的格式有 3 种 : XML、JSON、YAML

既然是一种格式,那么它就需要标准,因为通过标准可以限定各个格式中的具体内容

XML

XML(全称EXtensible Markup Language),在我看来它是一种古老的数据交换格式,因为从我接触到编程开始它就已经存在了

标准所在网址:https://www.w3.org/TR/1998/REC-xml-19980210

最新文档地址:https://www.w3.org/TR/REC-xml/

其实XML的标准一直是1.0,至少我没有见过其他的,一般情况下我们在编写XML文档的时候都需要遵循一个约束文件,这个约束文件中规定了你可以编写的内容。约束文件存在的方式也有两种,原来是 DTD 格式现在主流的是 Schema

XML 如果想完整的学习还是比较费劲的,不过一般情况下要求约束文档能看懂,XML内容会编写即可

参考网址:https://www.w3school.com.cn/x.asp

Delphi解析可使用 TXMLDocument(Delphi自带),此外也可以使用微软的 MSXML2 我没有这种需求所以并没有深入研究

官方文档:http://docwiki.embarcadero.com/Libraries/Sydney/en/Xml

JSON

JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。相比于XML格式JSON更为简单明了

标准文档地址:http://www.json.org/json-zh.html

具体的语法规则可以参考上面网址的文档内容,中文的

Delphi官方(当前最新版本DelphiXE10.4.2)已经支持对于JSON的解析了,官方文档地址

http://docwiki.embarcadero.com/Libraries/Sydney/en/System.JSON

需要注意的是有些类是Tokyo 10.2新增的,在使用的时候需要检查一下自己的版本

YAML

YAML (全称YAML Ain’t Markup Language),YAML不是标记语言的意思,YAML是便于人阅读基于unicode 编码的各种语言的序列号标准。

YAML语言的设计参考了JSON,XML和SDL等语言。YAML 强调以数据为中心,简洁易读,编写简单

官网地址:http://yaml.org

一个让人头皮发麻的站点

学习的话可以参考 阮一峰 老师的博客内容,地址:https://www.ruanyifeng.com/blog/2016/07/yaml.html

没有找到官方支持,不过在GitHub上有一个开源库是支持Delphi解析YAML格式数据的,有兴趣的朋友可以去研究

地址:https://github.com/neslib/Neslib.Yaml

最后我想说我非常讨厌这种数据格式,和python一样依靠缩进和空格控制语法。。。

JSON解析案例

将原来视频中讲解的代码在DelphiXE10.4.2上进行了重构

uses
    System.JSON, System.Generics.Collections, System.JSON.Serializers,
    System.SysUtils;

type
    { 实体类,主要是用于JSON字符串和类对象的互相转换 }
    TStudent=class(TObject)
    private
        FName: string;
        FAge: Integer;
    public
        property Name: string read FName write FName;
        property Age: Integer read FAge write FAge;
        constructor Create; overload;
        constructor Create(FName: string; FAge: Integer); overload;

    end;

constructor TStudent.Create;
begin

end;

constructor TStudent.Create(FName: string; FAge: Integer);
begin
    Self.FName :=FName;
    Self.FAge :=FAge;
end;

begin
    { 定义一个JSON字符串 }
    var
    UserJson :='{"FName":"小黑","FAge":18}';
    { 创建序列化对象 }
    var
    Serializer :=TJsonSerializer.Create();

    { 反序列化,其实就将字符串转为对象 }
    var
    Student :=Serializer.Deserialize<TStudent>(UserJson);
    Writeln('反序列化:' + Student.Name + ',' + Student.Age.ToString);

    { 列表转换,将TLIst容器转为字符串,也可以说是数组转换 }

    var
    List :=TList<TStudent>.Create;
    List.Add(TStudent.Create('小白', 30));
    List.Add(TStudent.Create('萧蔷', 30));
    // 创建序列化对象
    Serializer :=TJsonSerializer.Create();

    Writeln('序列化:' + Serializer.Serialize < TList < TStudent >> (List));

    var
        { 一个比较复杂的json字符串 }
    Users :='{"FListHelper":{"FCount":2},"FItems":[{"FName":"小白","FAge":30},{"FName":"萧蔷","FAge":30}],"FComparer":{}}';
    // 创建序列化对象
    Serializer :=TJsonSerializer.Create();
    { 可以尝试下这里会不会有问题,当字段匹配时居然可以直接转换 }
    var
    UserList :=Serializer.Deserialize < TList < TStudent >> (Users);

    for var Stu in UserList do begin
        Writeln('反序列化:' + Stu.Name + ',' + Stu.Age.ToString);
    end;

    { 获取指定字段 }
    Writeln(TJSONObject.ParseJSONValue(Users).GetValue<TJSONObject>
      ('FListHelper').GetValue<string>('FCount'));

    Writeln(TJSONObject.ParseJSONValue(Users).GetValue<TJSONArray>('FItems')
      .Count.ToString);

    Readln;

end.

其实Delphi自带的JSON解析已经够用了,如果不能满足你的话有一个开源库你可以尝试,不过我看它最近一次更新代码是 3 年前....

Github地址:https://github.com/hgourvest/superobject

学习资料(万一老师的博客):https://www.cnblogs.com/del/category/215158.html