-
Notifications
You must be signed in to change notification settings - Fork 36
可变类型的 Map
Hprose 除了提供了方便的可变类型的 List,还提供了非常好用的可变类型的 Map。可变类型的 Map 也是基于接口来实现的,因此也具有引用计数的自动内存管理功能。
+----------------+ +-------------------+ +----------------+
| IReadWriteSync | | TInterfacedObject | | IMapEnumerator |
+----------------+ +-------------------+ +----------------+
| |
v v
+------+ +--------------+ +----------------------+
| IMap |--------->| TAbstractMap |<----------| IInvokeableVarObject |
+------+ +--------------+ +----------------------+
| |
| | +-------------------------+
+--------+---------------------+-------------->| ICaseInsensitiveHashMap |
| | | +-------------------------+
| | | |
| v v v
| +----------+ +----------+ +-------------------------+
+--| IHashMap |--------->| THashMap |--------->| TCaseInsensitiveHashMap |
+----------+ +----------+ +-------------------------+
| |
| | +---------------------------+
+---------+---------------------+------------>| ICaseInsensitiveHashedMap |
| | | +---------------------------+
| | | |
| v v v
| +------------+ +------------+ +---------------------------+
+--| IHashedMap |------->| THashedMap |------>| TCaseInsensitiveHashedMap |
+------------+ +------------+ +---------------------------+
同 List 一样,Hprose 提供的所有 Map 类也都是通过接口来存取的,它们都实现了 IMap 接口。
IMap 接口中定义了枚举器操作,因此,在 Delphi 2005 以上或 FreePascal 2.5.1 以上版本中,您可以通过 for...in 语句来操作 IMap 接口的对象。枚举的元素类型为 TMapEntry,该类型是一个记录体,它有 2 个元素:Key 和 Value,这两个元素都是 Variant 类型的。
IMap 接口上定义了添加(Put、PutAll),获取(Get),查找(ContainsKey、ContainsValue),删除(Delete),清空(Clear),复制(Assign),同步(Lock、UnLock)等操作。
IMap 接口还定义了直接通过键值返回元素值的默认属性,可以让您向操作数组一样存取元素值,还定义了通过元素值获取键值的索引属性(Key)。另外,它还定义了元素个数(Count)、所有键值(Keys)和所有元素值(Values)这三个属性。
其定义如下:
IMap = interface(IReadWriteSync)
['{28B78387-CB07-4C28-B642-09716DAA2170}']
procedure Assign(const Source: IMap);
function GetCount: Integer;
function GetKeys: IImmutableList;
function GetValues: IImmutableList;
function GetKey(const AValue: Variant): Variant;
function GetValue(const AKey: Variant): Variant;
procedure PutValue(const AKey: Variant; AValue: Variant);
function Get(const AKey: Variant): Variant; overload;
function Get(const AKey: Variant; out AValue: Variant): Boolean; overload;
procedure Put(const AKey, AValue: Variant); overload;
procedure Put(const AList: IImmutableList); overload;
procedure Put(const AMap: IMap); overload;
procedure Put(const Container: Variant); overload;
procedure Put(const ConstArray: array of const); overload;
function Add(const AKey, AValue: Variant): Boolean;
procedure Clear;
function CompareKey(const Entry1, Entry2: TMapEntry): Integer;
function CompareValue(const Entry1, Entry2: TMapEntry): Integer;
function ContainsKey(const AKey: Variant): Boolean;
function ContainsValue(const AValue: Variant): Boolean;
function Delete(const AKey: Variant): Variant;
function GetEnumerator: IMapEnumerator;
function Join(const ItemGlue: string = ';';
const KeyValueGlue: string = '=';
const LeftPad: string = '';
const RightPad: string = ''): string;
procedure InitLock;
procedure InitReadWriteLock;
procedure Lock;
procedure Unlock;
procedure PutAll(const AList: IImmutableList); overload;
procedure PutAll(const AMap: IMap); overload;
procedure PutAll(const Container: Variant); overload;
procedure PutAll(const ConstArray: array of const); overload;
function ToList(ListClass: TListClass; Sync: Boolean = True;
ReadWriteSync: Boolean = False): IList;
function ToArrayList(Sync: Boolean = True;
ReadWriteSync: Boolean = False): IArrayList;
procedure Sort; overload;
procedure Sort(CompareProc: TMapCompareMethod); overload;
procedure SortByValue;
procedure TrimExcess;
property Count: Integer read GetCount;
property Key[const AValue: Variant]: Variant read GetKey;
property Value[const AKey: Variant]: Variant read GetValue write PutValue; default;
property Keys: IImmutableList read GetKeys;
property Values: IImmutableList read GetValues;
end;后面我们会在介绍具体实现类的时候来详细讲解这些操作。
该类是所有可变类型 Map 的基类,它实现了 IMap 接口上的枚举器,复制和同步操作。它继承自 TInterfacedObject,因此它也继承了接口生存周期管理。它是一个抽象类,您不应该对它进行实例化。
如果您打算实现自己的可变类型 Map,那么您应该直接或间接的继承自它。因为在 Hprose 序列化和反序列化时,判断一个类是否是可变类型的 Map 是通过判断 TAbstractMap 是否是这个类的祖先类的方式完成的。
该类上还实现了一个类方法 Split。但因为 TAbstractMap 是抽象类,所以您只能在它的可实例化子类上调用它。该方法的具体用法,我们在下面介绍 THashMap 类时来详细介绍。
IHashMap = interface(IMap)
['{B66C3C4F-3FBB-41FF-B0FA-5E73D87CBE56}']
end;该接口继承自 IMap 接口,并且没有添加任何操作。你可能会觉得这样定义比较奇怪,因为在平时使用时,该接口似乎是没有什么用处的。
这样做的原因是为了在反序列化列表类型数据时,可以通过指定该具体的接口,来反序列化为具体的实现类对象。
IHashMap 接口对应 THashMap 实现。
IHashedMap 接口对应 THashedMap 实现。
ICaseInsensitiveHashMap 接口对应 TCaseInsensitiveHashMap 实现。
ICaseInsensitiveHashedMap 接口对应 TCaseInsensitiveHashedMap 实现。
如果反序列化时,指定的类型是 IMap 接口类型,那么反序列化时,也会反序列化为 THashMap 实现的具体对象。
关于序列化和反序列化的内容,我们会在后面具体的章节中在详细介绍。