💡 Инструкция: В каждом вопросе выберите один ответ из пяти. На весь тест отведено 70 минут. Код лучше сначала разобрать вручную: правильный вариант должен объяснять механизм, а не только совпадать с одним запуском.
Вопрос 14 из 25
Почему `ContainsKey(K2)` возвращает `True`, хотя подписи `K1.LabelText` и `K2.LabelText` различаются?
Pascal Delphi / Pascal · Сравнение и хеширование Копировать
// Пользовательские Equals и GetHashCode используют один и тот же признак ключа.
program HashContract;
{$APPTYPE CONSOLE}
uses System.Generics.Collections, System.Generics.Defaults;
type
TKey = record
Id: Integer;
LabelText: string;
end;
TKeyComparer = class(TEqualityComparer<TKey>)
public
function Equals(const Left, Right: TKey): Boolean; override;
function GetHashCode(const Value: TKey): Integer; override;
end;
function TKeyComparer.Equals(const Left, Right: TKey): Boolean;
begin
Result := Left.Id = Right.Id;
end;
function TKeyComparer.GetHashCode(const Value: TKey): Integer;
begin
Result := Value.Id;
end;
var
D: TDictionary<TKey, string>;
K1, K2: TKey;
begin
D := TDictionary<TKey, string>.Create(TKeyComparer.Create);
try
K1.Id := 7;
K1.LabelText := 'first';
D.Add(K1, 'stored');
K2.Id := 7;
K2.LabelText := 'second';
Writeln(D.ContainsKey(K2));
finally
D.Free;
end;
end.
Если два ключа равны по comparer, их хеши могут различаться: словарь дополнительно переберёт все корзины.
Ключ можно менять после добавления, если его адрес не изменился.
Равные ключи могут иметь разные хеши: словарь всё равно найдёт их полным перебором.
Comparer обязан сравнивать только хеши и не должен проверять фактическое равенство.
Comparer считает ключи равными по `Id` и вычисляет хеш из того же `Id`; подпись в равенстве не участвует.
Вопрос 18 из 25
В `DictionaryModes` сначала встречается `D := TDictionary<string, Integer>.Create;`, а затем `if D.TryGetValue('a', N) then`. Какое наблюдаемое следствие относится именно к сценарию DictionaryModes?
Pascal Delphi / Pascal · Словари TDictionary Копировать
// Отделите правило языка от удачного запуска DictionaryModes.
program DictionaryModes;
{$APPTYPE CONSOLE}
uses System.Generics.Collections;
var
D: TDictionary<string, Integer>;
N: Integer;
begin
D := TDictionary<string, Integer>.Create;
try
D.Add('a', 1);
D.AddOrSetValue('a', 2);
if D.TryGetValue('a', N) then
Writeln(N);
finally D.Free; end;
end.
`Add` словаря заменяет существующее значение так же, как `AddOrSetValue`.
Индексатор словаря возвращает значение по умолчанию, если ключа нет.
`TryGetValue` нельзя отличить отсутствие ключа от сохранённого нулевого значения.
`TDictionary<TKey,TValue>` различает добавление нового ключа и замену значения.
`Add` словаря заменяет значение существующего ключа.