IComparer<T> 接口用于定义比较两个对象的方法。这个方法通常返回一个整数,其值的含义如下:

  • 小于 0:表示第一个对象(Left)小于第二个对象(Right)。在排序操作中,这通常意味着第一个对象应该在第二个对象之前。
  • 等于 0:表示两个对象相等。在排序操作中,它们的相对顺序可能不会改变,或者它们可能被视为可互换的。
  • 大于 0:表示第一个对象(Left)大于第二个对象(Right)。在排序操作中,这通常意味着第一个对象应该在第二个对象之后。

即: 升序的话 就是 left - right; 倒序的话就是: right - left;

用TList< T > 来测试

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Generics.Defaults, System.Generics.Collections,
  Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    btn1: TButton;
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  /// <summary>
  /// 定义一个类用于测试
  /// </summary>
  TPerson = class
  private
    name: string;
    age: Integer;
  public
    constructor Create(name: string; age: Integer);
  end;

  /// <summary>
  /// 定义排序类,实现排序接口,这种方法,比使用官方的
  /// TComparer + 一个方法清晰明了(TComparer<TPerson>.Construct(MyFunc2));
  /// </summary>
  TPersonComparer = class(TInterfacedObject, IComparer<TPerson>)
  public
    function Compare(const Left, Right: TPerson): Integer;
  end;

var
  Form1: TForm1;
  persons: TList<TPerson>;//定义列表容器,测试

implementation

{$R *.dfm}

constructor TPerson.Create(name: string; age: Integer);
begin
  inherited Create;
  Self.name := name;
  Self.age := age;
end;

function TPersonComparer.Compare(const Left, Right: TPerson): Integer;
begin
  //年龄升序
  //Result := Left.age - Right.age;

  //年龄倒序
  Result := Right.age - Left.age;
end;

procedure TForm1.btn1Click(Sender: TObject);
var
  p: TPerson;
begin
  persons.Add(TPerson.Create('小李', 1));
  persons.Add(TPerson.Create('小李', 3));
  persons.Add(TPerson.Create('小李', 4));
  persons.Add(TPerson.Create('小李', 2));

  //看下Add后是否自动排序了
  persons.Sort; //Add后 没有自动排序,需要调用Sort才会排序
  for p in persons do
  begin
    OutputDebugString(PChar(p.name + '-' + p.age.ToString));
  end;
end;

initialization

  ReportMemoryLeaksOnShutdown := True;

  //初始化容器,TPersonComparer.Create 是一个接口,故不用关心释放的问题
  persons := TList<TPerson>.Create(TPersonComparer.Create);

finalization

  persons.Free;

end.

image

image

image

启动程序,什么都不操作(不点击btn1),然后关闭程序,并不报内存泄漏,说明排序器是自动内存管理释放的;

persons := TList<TPerson>.Create(TPersonComparer.Create); //不要担心这里会有内存泄漏,不会的;

测试程序下载:https://files.cnblogs.com/files/del88/IComparer.zip

posted on 2024-02-27 08:22  del88  阅读(10)  评论(0编辑  收藏  举报