您可能必须创建自己的 T/IOrderedDictionary 类/接口
界面可能如下所示:
Based on Spring4D - IDictionary/IList
unit OrderedDictionary;
interface
uses
Spring,
Generics.Collections,
Generics.Defaults,
Spring.Collections,
Spring.Collections.Dictionaries,
Spring.Collections.Lists;
type
IOrderedDictionary<K,V> = interface(IDictionary<K,V>)
function Add(const item: TPair<K,V>): Integer;
{$REGION 'Property Accessors'}
function GetCapacity: Integer;
function GetCount: Integer;
function GetItem(index: Integer): TPair<K,V>;
procedure SetCapacity(value: Integer);
procedure SetCount(value: Integer);
procedure SetItem(index: Integer; const item: TPair<K,V>);
{$ENDREGION}
/// <summary>
/// Inserts an item to the IList<TPair<K,V>> at the specified index.
/// </summary>
/// <param name="index">
/// The zero-based index at which item should be inserted.
/// </param>
/// <param name="item">
/// The element to insert into the IList<TPair<K,V>>.
/// </param>
procedure Insert(index: Integer; const item: TPair<K,V>);
procedure InsertRange(index: Integer; const values: array of TPair<K,V>); overload;
procedure InsertRange(index: Integer; const collection: IEnumerable<TPair<K,V>>); overload;
/// <summary>
/// Removes the item at the specified index.
/// </summary>
/// <param name="index">
/// The zero-based index of the item to remove.
/// </param>
/// <exception cref="ArgumentOutOfRangeException">
/// <i>index</i> is not a valid index in the IList<TPair<K,V>>.
/// </exception>
procedure Delete(index: Integer);
procedure DeleteRange(index, count: Integer);
/// <summary>
/// Extracts the item at the specified index.
/// </summary>
/// <param name="index">
/// The zero-based index of the item to extract.
/// </param>
/// <exception cref="ArgumentOutOfRangeException">
/// <i>index</i> is not a valid index in the IList<TPair<K,V>>.
/// </exception>
function ExtractAt(index: Integer): TPair<K,V>;
function ExtractRange(index, count: Integer): TArray<TPair<K,V>>; overload;
/// <summary>
/// Creates a new list that contains a range of the elements in the
/// original list.
/// </summary>
/// <param name="index">
/// The zero-based index at which the range starts.
/// </param>
/// <param name="count">
/// The number of elements in the range.
/// </param>
/// <remarks>
/// If the list contains reference types the elements in the returned
/// list point to the same instance as the elements in the original list.
/// Also if the original list is a <see cref="Spring.Collections.Lists|TObjectList<TPair<K,V>>" />
/// it still owns the objects.
/// </remarks>
function GetRange(index, count: Integer): IList<TPair<K,V>>;
procedure Exchange(index1, index2: Integer);
procedure Move(currentIndex, newIndex: Integer);
procedure Reverse; overload;
procedure Reverse(index, count: Integer); overload;
procedure Sort; overload;
procedure Sort(const comparer: IComparer<K>); overload;
procedure Sort(const comparer: TComparison<K>); overload;
procedure Sort(const comparer: IComparer<K>; index, count: Integer); overload;
procedure Sort(const comparer: TComparison<K>; index, count: Integer); overload;
/// <summary>
/// Determines the index of a specific item in the IList<TPair<K,V>>.
/// </summary>
/// <param name="item">
/// The element to locate in the IList<TPair<K,V>>.
/// </param>
/// <returns>
/// The index of <i>item</i> if found in the list; otherwise, -1.
/// </returns>
/// <remarks>
/// If an element occurs multiple times in the list, the IndexOf method
/// always returns the first instance found.
/// </remarks>
function IndexOf(const Key: K): Integer; overload;
function IndexOf(const Key: K; index: Integer): Integer; overload;
function IndexOf(const Key: K; index, count: Integer): Integer; overload;
function AsList: IList;
/// <summary>
/// Returns the list as read-only list.
/// </summary>
/// <remarks>
/// This method will not perform a copy but will return the same instance
/// as IReadOnlyList<TPair<K,V>>.
/// </remarks>
function AsReadOnlyList: IReadOnlyList<TPair<K,V>>;
procedure TrimExcess;
property Capacity: Integer read GetCapacity write SetCapacity;
property Count: Integer read GetCount write SetCount;
property Items[index: Integer]: TPair<K,V> read GetItem write SetItem; default;
end;
如果您知道(或可以控制)字典如何存储其项目,则可以将 List 设置为 TArray<Integer> 以保存字典使用的存储的索引号或 TArray<pointer to TPair<K,V>>。
如果K 和V 很小,最好只复制列表。
更好的选择可能是使用 B+Tree 来存储您的项目,语义上它位于字典和列表之间。