-
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 实现的具体对象。
关于序列化和反序列化的内容,我们会在后面具体的章节中在详细介绍。
该类直接继承自 TAbstractMap,它是最常用的 Map。与其它语言中的 HashMap 不同,它的 Hash 存取是基于 THashedList 实现的,因此它不但可以高速存取数据,还可以保持数据插入的顺序。
THashMap 有多个构造方法,其中一部分继承自 TAbstractMap:
constructor Create(ACapacity: Integer = 16; Factor: Single = 0.75; Sync: Boolean = True; ReadWriteSync: Boolean = False); overload; override;
constructor Create(ACapacity: Integer; Sync: Boolean; ReadWriteSync: Boolean = False); overload; virtual;
constructor Create(Sync: Boolean; ReadWriteSync: Boolean = False); overload; virtual;
constructor Create(const AList: IImmutableList; Sync: Boolean = True; ReadWriteSync: Boolean = False); overload; virtual;
constructor Create(const AMap: IMap; Sync: Boolean = True; ReadWriteSync: Boolean = False); overload; virtual;
constructor Create(const Container: Variant; Sync: Boolean = True; ReadWriteSync: Boolean = False); overload; virtual;
constructor Create(const ConstArray: array of const; Sync: Boolean = True; ReadWriteSync: Boolean = False); overload; virtual;