RAD Studio VCL Reference
ContentsIndex
PreviousUpNext
TCustomComparer Class

TCustomComparer is a generic base for classes that implement the IComparer and IEqualityComparer interfaces.

Pascal
TCustomComparer<T> = class(TSingletonImplementation, IComparer<T>, IEqualityComparer<T>);
C++
template <T>
class TCustomComparer : public TSingletonImplementation, public IComparer<T>, public IEqualityComparer<T>;

Use TCustomComparer as a base for classes that have to support both comparison and equality checking. The Compare, Equals, and GetHashCode methods are abstract and thus must be implemented in descendant classes.  

Delphi Examples: 

 

{
This example demonstrates the usage of TCustomComparer.
The example assumes two memos and two buttons are present on the form.
}

type
  { Declare a custom string comparer descendant from TCustomComparer }
  TCustomStringComparer = class(TCustomComparer<String>)
  public
    function Compare(const Left, Right: String): Integer; override;
    function Equals(const Left, Right: String): Boolean; override;
    function GetHashCode(const Value: String): Integer; override;
  end;

{ TCustomStringComparer }

function TCustomStringComparer.Compare(const Left, Right: String): Integer;
begin
  { Make a case insensitive comparison }
  Result := CompareText(Left, Right);
end;

function TCustomStringComparer.Equals(const Left, Right: String): Boolean;
begin
  { Make a case insensitive comparison }
  Result := CompareText(Left, Right) = 0;
end;

function TCustomStringComparer.GetHashCode(const Value: String): Integer;
begin
  { Generate a hash code. Simply return the length of the string
    as its hash code }
  Result := Length(Value);
end;

procedure TForm3.btSortClick(Sender: TObject);
var
  List: TList<String>;
  I: Integer;
begin
  { Create a new list of strings with our custom comparer }
  List := TList<String>.Create(TCustomStringComparer.Create());

  { Populate the list with numbers in the memo }
  for I := 0 to InMemo.Lines.Count - 1 do
    List.Add(InMemo.Lines[I]);

  { Sort the list }
  List.Sort();

  { Copy the list with numbers to the memo }
  OutMemo.Clear;

  for I := 0 to List.Count - 1 do
    OutMemo.Lines.Add(List[I]);

  { Free resources }
  List.Free();
end;

procedure TForm3.btCountClick(Sender: TObject);
var
  Dictionary: TDictionary<String, Cardinal>;
  I: Integer;
  AString: String;
begin
  { Create a new dictionary of string/cardinal }
  Dictionary := TDictionary<String, Cardinal>.Create(TCustomStringComparer.Create());

  { Populate the dictionary with strings in the memo }
  for I := 0 to InMemo.Lines.Count - 1 do
  begin
    { Get the list from the memo }
    AString := InMemo.Lines[I];

    { If the string is already in the dictionary, increase its count
      by one. Otherwise add it with one by default.
    }
    if Dictionary.ContainsKey(AString) then
      Dictionary[AString] := Dictionary[AString] + 1
    else
      Dictionary.Add(InMemo.Lines[I], 1);
  end;

  { Copy the list with numbers to the memo }
  OutMemo.Clear;

  { Now populate the out memo with string and the number of times it was
    present in the initial memo}
  for AString in Dictionary.Keys do
    OutMemo.Lines.Add(AString + ':' + UIntToStr(Dictionary[AString]));

  { Free resources }
  Dictionary.Free();
end;

 

Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
What do you think about this topic? Send feedback!