powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как пользовать TEqualityComparer для TDictionary?
11 сообщений из 11, страница 1 из 1
Как пользовать TEqualityComparer для TDictionary?
    #39486215
Devillio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день!

Суть такая, ключ бы мне для TDictionary из двух ShortString. Можно, конечно, две строки объединить просто в одну и радоваться, но для общего развития, так сказать, хочется разобраться.
Нашел на просторах, наваял
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
type
  TMyNames = record
    Short: ShortString;
    Name: ShortString;

    class function Create(const AShort: ShortString; const AName: ShortString): TMyNames; static;
  end;

type
  TMyNamesComparer = class(TEqualityComparer<TMyNames>)
    function Equals(const Left, Right: TMyNames): Boolean; override;
    function GetHashCode(const Value: TMyNames): Integer; override;
  end;

function TMyNamesComparer.Equals(const Left, Right: TMyNames): Boolean;
begin
  Result := (Left.Short = Right.Short) and (Left.Name = Right.Name);
end;

function TMyNamesComparer.GetHashCode(const Value: TMyNames): Integer;
begin
  Result := 0;
  Result := BobJenkinsHash(Value.Short[1], Length(Value.Short) * SizeOf(Char), Result);
  Result := BobJenkinsHash(Value.Name[1], Length(Value.Name) * SizeOf(Char), Result);
end;

//тестирую так:
var
  My1,My2: TMyNames;
begin
  MyTest := TDictionary<TMyNames,Integer>.Create;
  My1 := TMyNames.Create('TEST', 'KOSTYA');
  MyTest.Add(My1, 1);
  My2 := TMyNames.Create('TEST', 'KOSTYA');
  MyTest.Add(My2, 1);

  if MyTest.ContainsKey(TMyNames.Create('TEST', 'KOSTYA')) then MessageDlg('', mtWarning, [mbok], 0);

//нет, и ключ создается второй раз, и warning не появляется




Что я делаю не так?
Спасибо!
...
Рейтинг: 0 / 0
Как пользовать TEqualityComparer для TDictionary?
    #39486228
__Avenger__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Надо примерно так:
Код: pascal
1.
TDictionary<TRecGUID, TRecInfo>.Create(1024, TGUIDComparer.Create);
...
Рейтинг: 0 / 0
Как пользовать TEqualityComparer для TDictionary?
    #39486242
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Devillio,

В конструктор TDictionary надо передать экземпляр компаратора
...
Рейтинг: 0 / 0
Как пользовать TEqualityComparer для TDictionary?
    #39486245
Devillio
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Попробовал так:

MyTest := TDictionary<TMyNames,Integer>.Create(TMyNamesComparer.Create);

Ничего не изменилось, второй ключ создается, warning не появляется.
Может еще что-то?
...
Рейтинг: 0 / 0
Как пользовать TEqualityComparer для TDictionary?
    #39486265
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Devillio,

Второй Add у тебя должен вызвать эксепшн
Трейси, почему этого не произошло. GetBucketIndex смотри
...
Рейтинг: 0 / 0
Как пользовать TEqualityComparer для TDictionary?
    #39486469
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DevillioMyTest := TDictionary<TMyNames,Integer>.Create(TMyNamesComparer.Create);Это прямая утечка памяти. Экземпляр TMyNamesComparer никогда не освободится
...
Рейтинг: 0 / 0
Как пользовать TEqualityComparer для TDictionary?
    #39486520
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_Это прямая утечка памяти. Экземпляр TMyNamesComparer никогда не освободится
Освободится.
...
Рейтинг: 0 / 0
Как пользовать TEqualityComparer для TDictionary?
    #39486556
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_DevillioMyTest := TDictionary<TMyNames,Integer>.Create(TMyNamesComparer.Create);Это прямая утечка памяти. Экземпляр TMyNamesComparer никогда не освободитсяТам интерфейс через const передается, значит счетчик ссылок не инкрементируется. Поэтому - освободится на выходе из вызывающей функции.
...
Рейтинг: 0 / 0
Как пользовать TEqualityComparer для TDictionary?
    #39486594
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КвейдТам интерфейс через const передается, значит счетчик ссылок не инкрементируется. Поэтому - освободится на выходе из вызывающей функции
Он освободится не поэтому. Для вызывающей функции это и не интерфейс вовсе, а объект. Счётчик начнёт работать после сохранения компарера в конструкторе. Если бы сохранения небыло то это действительно была бы утечка.
...
Рейтинг: 0 / 0
Как пользовать TEqualityComparer для TDictionary?
    #39486614
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Точно, я неверно расписал поведение
...
Рейтинг: 0 / 0
Как пользовать TEqualityComparer для TDictionary?
    #39486874
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev AlexeyСчётчик начнёт работать после сохранения компарера в конструктореДа. Виноват. Дую уже на холодное :)
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как пользовать TEqualityComparer для TDictionary?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]