有时,将一系列item按特定方式排序也是很有用的,在这种情况下,就可以采用TOrderedList。否则就必须用后面的分类方式,因为TOrderedList本身就是一个抽象的基类(源于TList但却用抽象的方法)。采用公开的Push方式,可以把一个新的item"push"到一个有序列中,就象我们看到了一样。不管这个新item被放在哪儿,有且仅有一个位置可以看见或移动当前item(序列顶部的item)。用Peek可以为这个item获得指针,用Pop可以移除这个item。
下面的例子刚刚编辑好但是运行结果确有一个抽象错误,因为内部PushiItem(也就是所谓的Push法)仍然非常抽象,并没有在源类中执行:
程序TForm1.btnOrderedListClick(Sender: TObject);
var
i: Integer;
OrderedList: TOrderedList;
Begin
OrderedList := TOrderedList.Create;
Try
for i:=0 to Pred(ComponentCount) do
if (Components[i] IS TButton) then
OrderedList.Push(Components[i]);
// Usage of OrderedList...
Memo1.Lines.Clear;
while OrderedList.Count > 0 do
Memo1.Lines.Add(TButton(OrderedList.Pop).Name)
Finally
OrderedList.Free
End
end;
在你想方设法寻找在源类中运行PushItem方法之前,还是先看一看已有的两种工具:stack和queue。
Tstack源于TOrderedList,可以执行PushItem方法,因此它可以把新的item push与Pop和Peek重新放置的统一序列的同一端。这也就是众所周知的LIFO(Last
In First Out,即后进先出)。
如果你想对items, objects, 或components 按照LIFO的顺序运行的话,就可以采用这种办法。而且由于生成的Tstack也是用指针,因此还有一个存储(我猜是这样)Tobjects的TobjectStack,后者仍然支持RTTI,这是我发现最有用的东西。
下面的例子会把表格中所有部分push到ObjectStack,并且在Memo上显示每一部分的名字,这里按照反向顺序列出了所有部分(例如,生成的最后一部分列在最前面)。
程序TForm1.btnStackClick(Sender: TObject);
var
i: Integer;
ObjectStack: TObjectStack;
Begin
ObjectStack := TObjectStack.Create;
Try
for i:=0 to Pred(ComponentCount) do
ObjectStack.Push(Components[i]);
// Usage of OrderedList...
Memo1.Lines.Clear;
while ObjectStack.Count > 0 do
Memo1.Lines.Add((ObjectStack.Pop AS TComponent).Name)
Finally
ObjectStack.Free
End
end;
注意,我用的是RTTI来区分存储在ObjectStack 到Tcomponent(所有部分的基类)的items。因为Tcomponent已经有了命名功能,因此就不必对TButtons,
Tedits等加以区分了。同时还要注意,Tstack和TobjectStack并不拥有它们所存储的objects。