Delphi 动态数组利器:TList 与 TList<T> 完全指南

Delphi 动态数组利器:TList 与 TList<T> 完全指南

1. 前言

在 Delphi 开发中,动态数组是高频使用的数据结构。传统 TList 和现代泛型 TList<T> 各有优势,但如何选择?本文将从基本用法性能对比实际示例,带你全面掌握这两种列表的用法,并给出最佳实践建议。


2. TList:经典的指针动态数组

TList 是 Delphi 早期的动态数组实现,存储 Pointer 类型,适合需要直接操作内存的场景。

2.1 基本用法

var
  MyList: TList;
  P: Pointer;
begin
  MyList := TList.Create;
  try
    P := Pointer(42); // 存储整数(需类型转换)
    MyList.Add(P);    // 添加元素

    // 访问元素(需强制转换)
    IntegerValue := Integer(MyList[0]);
  finally
    MyList.Free; // 需手动释放
  end;
end;

2.2 优缺点

  • 优点
    • 轻量级,无泛型开销。
    • 兼容旧版 Delphi。
  • 缺点
    • 类型不安全,需手动转换。
    • 不自动管理对象,易内存泄漏。

3. TList<T>:类型安全的现代泛型列表

从 Delphi 2009 开始引入的 TList<T>(位于 System.Generics.Collections),提供编译时类型检查,更安全易用。

3.1 基本用法

var
  IntList: TList<Integer>;
begin
  IntList := TList<Integer>.Create;
  try
    IntList.Add(100);       // 直接添加整数
    FirstItem := IntList[0]; // 直接访问(无需转换)
  finally
    IntList.Free; // 自动管理内存(若 T 是托管类型)
  end;
end;

3.2 核心功能

操作 代码示例 说明
添加元素 IntList.Add(42) 末尾添加
删除元素 IntList.Delete(0) 按索引删除
查找元素 IntList.IndexOf(100) 返回索引(-1 表示不存在)
排序 IntList.Sort 默认升序
遍历 for Item in IntList do ... 支持 for-in 循环

3.3 高级技巧

(1) 自定义排序

IntList.Sort(
  TComparer<Integer>.Construct(
    function(const A, B: Integer): Integer
    begin
      Result := B - A; // 降序排序
    end
  )
);

(2) 二分查找(需先排序)

IntList.Sort;
if IntList.BinarySearch(100, FoundIndex) then
  WriteLn('Found at index: ', FoundIndex);

4. 性能对比与选型建议

4.1 性能对比

场景 TList TList<T>
类型安全性 ❌ 需手动转换 ✅ 编译时检查
内存管理 需手动释放 自动管理(部分类型)
执行速度 ⚡ 更快 ⚡ 稍慢(泛型开销)
代码可读性

4.2 选型建议

  • TList<T> 如果
    • 需要类型安全(如存储字符串、接口、记录等)。
    • 开发新项目,或使用 Delphi 2009+。
  • TList 如果
    • 维护旧代码,或需要极致性能(如高频操作裸指针)。

5. 实战示例:对象列表管理

假设需要管理 TStudent 对象列表:

type
  TStudent = class
  public
    Name: string;
    Age: Integer;
  end;

var
  Students: TList<TStudent>;
  Student: TStudent;
begin
  Students := TList<TStudent>.Create;
  try
    // 添加学生
    Student := TStudent.Create;
    Student.Name := 'Alice';
    Student.Age := 20;
    Students.Add(Student);

    // 遍历输出
    for Student in Students do
      WriteLn(Student.Name, ' (', Student.Age, ')');

    // 释放对象(需手动)
    for Student in Students do
      Student.Free;
  finally
    Students.Free;
  end;
end;

注意TList<T> 不会自动释放对象,需手动遍历 Free


6. 总结

  • TList:适合底层指针操作,但需谨慎管理内存。
  • TList<T>:推荐大多数场景,类型安全、易维护。
  • 最佳实践
    • 新项目优先用 TList<T>
    • 涉及对象时,记得手动释放内存。
    • 高频操作考虑预分配 Capacity 提升性能。

进一步学习

希望这篇指南能帮助你高效使用 Delphi 的动态数组!如果有问题,欢迎留言讨论。 🚀

posted @ 2025-05-21 08:36  我是狂草  阅读(431)  评论(0)    收藏  举报