Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как пользовать TEqualityComparer для TDictionary? / 11 сообщений из 11, страница 1 из 1
11.07.2017, 08:26:59
    #39486215
Devillio
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как пользовать TEqualityComparer для TDictionary?
Добрый день!

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

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

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

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

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


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