Namespaces
Variants

C++ named requirements: UnorderedAssociativeContainer (since C++11)

From cppreference.net
C++ named requirements

Неупорядоченные ассоциативные контейнеры — это Container ы , которые обеспечивают быстрый поиск объектов по ключам. В худшем случае сложность составляет линейную, но в среднем большинство операций выполняется значительно быстрее.

Неупорядоченные ассоциативные контейнеры параметризуются Key ; Hash , функциональным объектом Hash , который выступает в качестве хеш-функции для Key ; и Pred , BinaryPredicate , оценивающим эквивалентность между Key . std::unordered_map и std::unordered_multimap также имеют связанный с Key тип T .

Если два Key равны согласно Pred , Hash должен возвращать одинаковое значение для обоих ключей.

Если оба Hash::is_transparent и Pred::is_transparent существуют и каждый именует тип, функции-члены find , contains , count , equal_range , и bucket принимают аргументы типов, отличных от Key , и ожидают, что Hash может быть вызван со значениями этих типов, и что Pred является прозрачной функцией сравнения, такой как std::equal_to<> .

(начиная с C++20)

std::unordered_map и std::unordered_set могут содержать не более одного элемента с заданным ключом, тогда как std::unordered_multiset и std::unordered_multimap могут содержать несколько элементов с одинаковым ключом (которые при итерациях всегда должны быть смежными).

Для std::unordered_set и std::unordered_multiset тип значения совпадает с типом ключа, и оба типа iterator и const_iterator являются константными итераторами. Для std::unordered_map и std::unordered_multimap тип значения представляет собой std:: pair < const Key, T > .

Элементы в неупорядоченном ассоциативном контейнере организованы в сегменты (buckets), ключи с одинаковым хешем попадают в один и тот же сегмент. Количество сегментов увеличивается при росте размера контейнера, чтобы поддерживать среднее количество элементов в каждом сегменте ниже определённого значения.

Перехеширование делает итераторы недействительными и может привести к перераспределению элементов по разным сегментам, но не делает недействительными ссылки на элементы.

Неупорядоченные ассоциативные контейнеры удовлетворяют требованиям AllocatorAwareContainer . Для std::unordered_map и std::unordered_multimap требования к value_type в AllocatorAwareContainer применяются к key_type и mapped_type (а не к value_type ).

Содержание

Требования

Легенда
X Неупорядоченный ассоциативный контейнерный класс
a Значение типа X
a2 Значение типа с узлами, совместимыми с типом X
b Значение типа X или const X
a_uniq Значение типа X когда X поддерживает уникальные ключи
a_eq Значение типа X когда X поддерживает эквивалентные ключи
a_tran Значение типа X или const X когда квалифицированные идентификаторы X::key_equal::is_transparent и X::hasher::is_transparent оба являются валидными и обозначают типы
i , j Входные итераторы, которые ссылаются на value_type
[ i , j ) Допустимый диапазон
rg (начиная с C++23) Значение типа R , которое моделирует container-compatible-range <value_type>
p , q2 Корректные константные итераторы для a
q , q1 Корректные разыменовываемые константные итераторы для a
r Корректный разыменовываемый итератор для a
[ q1 , q2 ) Допустимый диапазон в a
il Значение типа std:: initializer_list < value_type >
t Значение типа X::value_type
k Значение типа key_type
hf Значение типа hasher или const hasher
eq Значение типа key_equal или const key_equal
ke Значение, для которого
  • eq ( r1, ke ) == eq ( ke, r1 ) ,
  • hf ( r1 ) == hf ( ke ) если eq ( r1, ke ) равно true , и
  • если любые два из eq ( r1, ke ) , eq ( r2, ke ) , и eq ( r1, r2 ) равны true , то все три равны true ,

где r1 и r2 являются ключами элементов в a_tran

kx (начиная с C++23) Значение, для которого
  • eq ( r1, kx ) == eq ( kx, r1 ) ,
  • hf ( r1 ) == hf ( kx ) если eq ( r1, kx ) равно true ,
  • если любые два из eq ( r1, kx ) , eq ( r2, kx ) и eq ( r1, r2 ) равны true , то все три равны true , и
  • kx не конвертируется ни в iterator , ни в const_iterator ,

где r1 и r2 - ключи элементов в a_tran

n Значение типа size_type
z Значение типа float
nh (начиная с C++17) Rvalue типа X :: node_type

Типы членов

Название Тип Требования Примечания
X::key_type Key
X::mapped_type T std::unordered_map и std::unordered_multimap только
X::value_type Key std::unordered_set и std::unordered_multiset только. Erasable в X
std:: pair < const Key, T > std::unordered_map и std::unordered_multimap только. Erasable в X
X::hasher Hash Hash
X::key_equal Pred CopyConstructible ; BinaryPredicate который принимает два аргумента типа Key и выражает отношение эквивалентности
X::local_iterator LegacyIterator Категория и типы совпадают с X::iterator Может использоваться для итерации по одному сегменту, но не между сегментами
X::const_local_iterator LegacyIterator Категория и типы совпадают с X::const_iterator
X::node_type (since C++17) Специализация шаблона класса node-handle Публичные вложенные типы совпадают с соответствующими типами в X

Функции-члены и операторы

**Примечание:** В данном HTML-фрагменте весь текст внутри тегов ` ` является C++ кодом, который согласно инструкциям не подлежит переводу. Вне этих тегов отсутствует текст для перевода. HTML-разметка полностью сохранена в оригинальном виде. **Примечание:** Весь текст в данном фрагменте находится внутри тегов ` `, которые обозначают код на C++. Согласно инструкциям, код C++ не переводится, поэтому перевод не требуется. HTML-структура и форматирование полностью сохранены. **Примечание:** Весь текст в данном HTML-фрагменте находится внутри тегов ` `, которые содержат C++ код. Согласно инструкциям, код на C++ не подлежит переводу, поэтому весь текст сохранен в оригинальном виде. HTML-структура и форматирование полностью сохранены. **Примечание:** В данном фрагменте HTML не содержится текста для перевода - только HTML-теги, атрибуты и код на C++ внутри тегов ` `, который согласно инструкциям не подлежит переводу. **Примечание:** В данном фрагменте HTML весь текст внутри тегов ` ` представляет собой C++ код, который согласно инструкциям не подлежит переводу. Единственный элемент, который мог бы быть переведен - это сокращение "il" (предположительно от "initializer list"), но поскольку это C++ специфический термин, он также сохранен без изменений.
Выражение Результат Предусловия Эффекты Возвращает Сложность
X ( n, hf, eq ) Создает пустой контейнер как минимум с n сегментами, используя hf в качестве хеш-функции и eq в качестве предиката проверки равенства ключей O ( n )
X ( n, hf ) key_equal является DefaultConstructible Создает пустой контейнер как минимум с n корзинами, используя hf как хеш-функцию и key_equal ( ) как предикат равенства ключей O ( n )
X ( n ) hasher и key_equal являются DefaultConstructible Создает пустой контейнер с как минимум n корзинами, используя hasher ( ) в качестве хеш-функции и key_equal ( ) в качестве предиката равенства ключей O ( n )
X a = X ( ) ;
X a ;
hasher и key_equal являются DefaultConstructible Создает пустой контейнер с неуказанным количеством сегментов, используя hasher ( ) в качестве хеш-функции и key_equal ( ) в качестве предиката равенства ключей Константная
X ( i, j, n, hf, eq ) value_type является EmplaceConstructible в X из * i Создает пустой контейнер как минимум с n корзинами, используя hf как хэш-функцию и eq как предикат равенства ключей, и вставляет элементы из [ i , j ) в него В среднем случае O(N) ( N равно std:: distance ( i, j ) ), в худшем случае O(N 2 )
X ( i, j, n, hf ) key_equal является DefaultConstructible . value_type является EmplaceConstructible в X из * i Создает пустой контейнер как минимум с n корзинами, используя hf как хеш-функцию и key_equal ( ) как предикат равенства ключей, и вставляет элементы из [ i , j ) в него Средний случай O(N) ( N это std:: distance ( i, j ) ), худший случай O(N 2 )
X ( i, j, n ) hasher и key_equal являются DefaultConstructible . value_type является EmplaceConstructible в X из * i Создает пустой контейнер как минимум с n корзинами, используя hasher ( ) в качестве хеш-функции и key_equal ( ) в качестве предиката равенства ключей, и вставляет элементы из [ i , j ) в него В среднем O(N) ( N это std:: distance ( i, j ) ), в худшем случае O(N 2 )
X ( i, j ) hasher и key_equal являются DefaultConstructible . value_type является EmplaceConstructible в X из * i Создает пустой контейнер с неуказанным количеством сегментов, используя hasher ( ) как хеш-функцию и key_equal ( ) как предикат равенства ключей, и вставляет элементы из [ i , j ) в него Средняя сложность O(N) ( N это std:: distance ( i, j ) ), худший случай O(N 2 )
X ( std:: from_range ,
rg, n, hf, eq )

(начиная с C++23)
value_type является EmplaceConstructible в X из * ranges:: begin ( rg ) Создает пустой контейнер как минимум с n корзинами, используя hf как хэш-функцию и eq как предикат равенства ключей, и вставляет элементы из rg в него В среднем случае O(N) ( N это ranges:: distance ( rg ) ), в худшем случае O(N 2 )
X ( std:: from_range ,
rg, n, hf )

(начиная с C++23)
key_equal является DefaultConstructible . value_type является EmplaceConstructible в X из * ranges:: begin ( rg ) Создает пустой контейнер как минимум с n корзинами, используя hf как хеш-функцию и key_equal ( ) как предикат сравнения ключей, и вставляет элементы из rg в него В среднем случае O(N) ( N это ranges:: distance ( rg ) ), в худшем случае O(N 2 )
X ( std:: from_range ,
rg, n )

(начиная с C++23)
hasher и key_equal являются DefaultConstructible . value_type является EmplaceConstructible в X из * ranges:: begin ( rg ) Создает пустой контейнер как минимум с n корзинами, используя hasher ( ) как хеш-функцию и key_equal ( ) как предикат равенства ключей, и вставляет элементы из rg в него В среднем случае O(N) ( N это ranges:: distance ( rg ) ), в худшем случае O(N 2 )
X ( std:: from_range ,
rg )

(начиная с C++23)
hasher и key_equal являются DefaultConstructible . value_type является EmplaceConstructible в X из * ranges:: begin ( rg ) Создает пустой контейнер с неуказанным количеством сегментов, используя hasher ( ) как хеш-функцию и key_equal ( ) как предикат равенства ключей, и вставляет элементы из rg в него В среднем O(N) ( N это ranges:: distance ( rg ) ), в худшем случае O(N 2 )
X ( il ) X ( il. begin ( ) , il. end ( ) )
X ( il, n ) X ( il. begin ( ) , il. end ( ) , n )
X ( il, n, hf ) X ( il. begin ( ) , il. end ( ) , n, hf )
X ( il, n, hf, eq ) X ( il. begin ( ) , il. end ( ) , n, hf, eq )
X ( b ) Container ; Копирует хэш-функцию, предикат и максимальный коэффициент заполнения В среднем линейно от b. size ( ) , в худшем случае O(N 2 )
a = b X& Container ; копирует хэш-функцию, предикат и максимальный коэффициент заполнения В среднем линейно от b. size ( ) , в худшем случае O(N 2 )
a = il X& value_type является CopyInsertable в X и CopyAssignable Присваивает диапазон [ il. begin ( ) , il. end ( ) ) в a . Все существующие элементы a либо присваиваются, либо уничтожаются В среднем линейно от il. size ( ) , в худшем случае O(N 2 )
b. hash_function ( ) hasher b 's хеш-функция Константа
b. key_eq ( ) key_equal b 's предикат сравнения ключей Константа
a_uniq. emplace ( args ) std:: pair <
iterator,
bool >
value_type является EmplaceConstructible в X из args Вставляет объект value_type t , созданный с помощью std:: forward < Args > ( args ) ... тогда и только тогда, когда в контейнере нет элемента с ключом, эквивалентным ключу t Компонент bool возвращаемой пары равен true тогда и только тогда, когда вставка произошла, а компонент-итератор пары указывает на элемент с ключом, эквивалентным ключу t В среднем O(1) , в худшем случае O ( a_uniq. size ( ) )
a_eq. emplace ( args ) iterator value_type является EmplaceConstructible в X из args Вставляет объект value_type t , сконструированный с помощью std:: forward < Args > ( args ) ... Итератор, указывающий на вновь вставленный элемент В среднем случае O(1) , в худшем случае O ( a_eq. size ( ) )
a. emplace_hint ( p, args ) iterator value_type является EmplaceConstructible в X из args a. emplace (
std:: forward < Args > ( args ) ... )
Итератор, указывающий на элемент с ключом, эквивалентным ключу вновь вставленного элемента. const_iterator p является подсказкой, указывающей, с какого места следует начинать поиск. Реализациям разрешено игнорировать подсказку В среднем случае O(1) , в худшем случае O ( a. size ( ) )
a_uniq. insert ( t ) std:: pair <
iterator,
bool >
Если t является неконстантной rvalue, value_type должен быть MoveInsertable в X ; иначе value_type должен быть CopyInsertable в X Вставляет t тогда и только тогда, когда в контейнере нет элемента с ключом, эквивалентным ключу t Компонент bool возвращаемой пары указывает, произошла ли вставка, а компонент iterator указывает на элемент с ключом, эквивалентным ключу t В среднем O(1) , в худшем случае O ( a_uniq. size ( ) )
a_eq. insert ( t ) iterator Если t является неконстантной rvalue, value_type должен быть MoveInsertable в X ; иначе value_type должен быть CopyInsertable в X Вставляет t Итератор, указывающий на вновь вставленный элемент В среднем случае O(1) , в худшем случае O ( a_eq. size ( ) )
a. insert ( p, t ) iterator Если t является неконстантной rvalue, value_type должен быть MoveInsertable в X ; иначе value_type должен быть CopyInsertable в X a. insert ( t ) . Итератор p является подсказкой, указывающей, с какого места следует начинать поиск. Реализациям разрешено игнорировать подсказку Итератор, указывающий на элемент с ключом, эквивалентным ключу t В среднем случае O(1) , в худшем случае O ( a. size ( ) )
a. insert ( i, j ) void value_type является EmplaceConstructible в X из * i . Ни i , ни j не являются итераторами в a a. insert ( t ) для каждого элемента в
[ i , j )
В среднем случае O(N) , где N это std:: distance ( i, j ) , в худшем случае O ( ( a. size ( ) + 1 ) )
a. insert_range ( rg )
(начиная с C++23)
void value_type является EmplaceConstructible в X из * ranges:: begin ( rg ) . rg и a не пересекаются a. insert ( t ) для каждого элемента t в rg В среднем O(N) , где N это ranges:: distance ( rg ) , в худшем случае O ( ( a. size ( ) + 1 ) )
a. insert ( il ) a. insert ( il. begin ( ) , il. end ( ) )
a_uniq. insert ( nh )
(начиная с C++17)
insert_return_type nh пуст или

a_uniq. get_allocator ( )
==
nh. get_allocator ( )
равно true

Если nh пуст, не оказывает эффекта. В противном случае вставляет элемент, принадлежащий nh тогда и только тогда, когда в контейнере нет элемента с ключом, эквивалентным nh. key ( ) . Гарантирует: Если nh пуст, inserted равно false , position равно end ( ) , и node пуст. В противном случае, если вставка произошла, inserted равно true , position указывает на вставленный элемент, и node пуст; если вставка не удалась, inserted равно false , node имеет предыдущее значение nh , и position указывает на элемент с ключом, эквивалентным nh. key ( ) В среднем случае O(1) , в худшем случае O ( a_uniq. size ( ) )
a_eq. insert ( nh )
(начиная с C++17)
iterator nh пуст или

a_eq. get_allocator ( )
==
nh. get_allocator ( )
равно true

Если nh пуст, не оказывает эффекта и возвращает a_eq. end ( ) . В противном случае вставляет элемент, принадлежащий nh , и возвращает итератор, указывающий на вновь вставленный элемент. Гарантирует: nh становится пустым В среднем O(1) , в худшем случае O ( a_eq. size ( ) )
a. insert ( q, nh )
(начиная с C++17)
iterator nh пуст или

a. get_allocator ( )
==
nh. get_allocator ( )
равно true

Если nh пуст, не оказывает эффекта и возвращает a. end ( ) . В противном случае вставляет элемент, принадлежащий nh тогда и только тогда, когда в контейнерах с уникальными ключами нет элемента с ключом, эквивалентным nh. key ( ) ; всегда вставляет элемент, принадлежащий nh в контейнерах с эквивалентными ключами. Итератор q является подсказкой, указывающей, с какого места следует начинать поиск. Реализациям разрешено игнорировать подсказку. Гарантирует: nh становится пустым при успешной вставке, остается неизменным при неудачной вставке Итератор, указывающий на элемент с ключом, эквивалентным nh. key ( ) В среднем случае O(1) , в худшем случае O ( a. size ( ) )
a. extract ( k )
(начиная с C++17)
node_type Удаляет элемент в контейнере с ключом, эквивалентным k Объект node_type , владеющий элементом, если найден, иначе пустой node_type Средняя сложность O(1) , худший случай O ( a. size ( ) )
a_tran. extract ( kx )
(начиная с C++23)
node_type Удаляет элемент в контейнере с ключом, эквивалентным kx Объект node_type , владеющий элементом, если он найден, иначе пустой node_type В среднем O(1) , в худшем случае O ( a_tran. size ( ) )
a. extract ( q )
(начиная с C++17)
node_type Удаляет элемент, на который указывает q Объект node_type , владеющий этим элементом В среднем O(1) , в худшем случае O ( a. size ( ) )
a. merge ( a2 )
(начиная с C++17)
void a. get_allocator ( )
==
a2. get_allocator ( )
Пытается извлечь каждый элемент из a2 и вставить его в a , используя хэш-функцию и предикат равенства ключей контейнера a . В контейнерах с уникальными ключами, если в a уже существует элемент с ключом, эквивалентным ключу элемента из a2 , то этот элемент не извлекается из a2 . Гарантирует: указатели и ссылки на перемещенные элементы a2 ссылаются на те же элементы, но как на члены контейнера a . Итераторы, ссылающиеся на перемещенные элементы, и все итераторы, ссылающиеся на a , становятся недействительными, но итераторы элементов, оставшихся в a2 , остаются действительными. В среднем случае O(N) , где N это a2. size ( ) , в худшем случае O ( ( a. size ( ) + 1 ) )
a. erase ( k ) size_type Удаляет все элементы с ключом, эквивалентным k Количество удалённых элементов В среднем O ( a. count ( k ) ), в худшем случае O ( a. size ( ) )
a_tran. erase ( kx )
(начиная с C++23)
size_type Удаляет все элементы с ключом, эквивалентным kx Количество удалённых элементов В среднем O ( a_tran. count ( kx ) ), в худшем случае O ( a_tran. size ( ) )
a. erase ( q ) iterator Удаляет элемент, на который указывает q Итератор, следующий непосредственно за q до удаления Средний случай O(1) , худший случай O ( a. size ( ) )
a. erase ( r )
(начиная с C++17)
iterator Удаляет элемент, на который указывает r Итератор, следующий непосредственно за r до удаления В среднем O(1) , в худшем случае O ( a. size ( ) )
a. erase ( q1, q2 ) iterator Удаляет все элементы в диапазоне
[ q1 , q2 )
Итератор, следующий сразу за удалёнными элементами до удаления В среднем линейно от std:: distance ( q1, q2 ) , в худшем случае O ( a. size ( ) )
a. clear ( ) void Удаляет все элементы в контейнере. Гарантирует: a. empty ( ) возвращает true Линейная сложность от a. size ( )
b. find ( k ) iterator ; const_iterator для константного b Итератор, указывающий на элемент с ключом, эквивалентным k , или b. end ( ) , если такого элемента не существует В среднем O(1) , в худшем случае O ( b. size ( ) )
a_tran. find ( ke )
(начиная с C++17) ?
iterator ; const_iterator для константного a_tran Итератор, указывающий на элемент с ключом, эквивалентным ke , или a_tran. end ( ) если такого элемента не существует В среднем O(1) , в худшем случае O ( a_tran. size ( ) )
b. count ( k ) size_type Количество элементов с ключом, эквивалентным k В среднем случае O ( b. count ( k ) ), в худшем случае O ( b. size ( ) )
a_tran. count ( ke )
(начиная с C++17) ?
size_type Количество элементов с ключом, эквивалентным ke В среднем случае O ( a_tran. count ( ke ) ), в худшем случае O ( a_tran. size ( ) )
b. contains ( k )
(начиная с C++20) ?
b. find ( k ) ! = b. end ( )
a_tran. contains ( ke )
(начиная с C++20) ?
a_tran. find ( ke ) ! = a_tran. end ( )
b. equal_range ( k ) std:: pair <
iterator,
iterator > ;

std:: pair <
const_iterator,
const_iterator > для константного b

Диапазон, содержащий все элементы с ключами, эквивалентными k . Возвращает

std:: make_pair (
b. end ( ) , b. end ( ) )
если таких элементов не существует

В среднем O ( b. count ( k ) ), в худшем случае O ( b. size ( ) )
a_tran. equal_range ( ke )
(начиная с C++20) ?
std:: pair <
iterator,
iterator > ;

std:: pair <
const_iterator,
const_iterator > для константного a_tran

Диапазон, содержащий все элементы с ключами, эквивалентными ke . Возвращает

std:: make_pair (
a_tran. end ( ) ,
a_tran. end ( ) )
если таких элементов не существует

В среднем O ( a_tran. count ( ke ) ), в худшем случае O ( a_tran. size ( ) )
b. bucket_count ( ) size_type Количество сегментов, которые содержит b Константа
b. max_bucket_count ( ) size_type Верхняя граница количества сегментов, которые b может содержать Константа
b. bucket ( k ) size_type b. bucket_count ( ) > 0 Индекс корзины, в которой находились бы элементы с ключами, эквивалентными k , если бы такие элементы существовали. Возвращаемое значение находится в диапазоне [ 0 , b. bucket_count ( ) ) Константная сложность
a_tran. bucket ( ke ) size_type a_tran.
bucket_count ( ) > 0
Индекс корзины, в которой находились бы элементы с ключами, эквивалентными ke , если бы такие элементы существовали. Возвращаемое значение должно находиться в диапазоне [ 0 , a_tran. bucket_count ( ) ) Константная
b. bucket_size ( n ) size_type n находится в [ 0 , b. bucket_count ( ) ) Количество элементов в n -ой корзине O ( b. bucket_size ( n ) )
b. begin ( n ) local_iterator ; const_local_iterator для константного b n находится в [ 0 , b. bucket_count ( ) ) Итератор, ссылающийся на первый элемент в корзине. Если корзина пуста, то b. begin ( n ) == b. end ( n ) Константная
b. end ( n ) local_iterator ; const_local_iterator для константного b n находится в [ 0 , b. bucket_count ( ) ) Итератор, который является конечным значением для сегмента Константа
b. cbegin ( n ) const_local_iterator n находится в [ 0 , b. bucket_count ( ) ) Итератор, ссылающийся на первый элемент в сегменте. Если сегмент пуст, то b. cbegin ( n ) == b. cend ( n ) Константное время
b. cend ( n ) const_local_iterator n находится в [ 0 , b. bucket_count ( ) ) Итератор, который является конечным значением для сегмента Константный
b. load_factor ( ) float Среднее количество элементов на сегмент Константная
b. max_load_factor ( ) float Положительное число, которое контейнер пытается поддерживать в качестве верхней границы коэффициента заполнения. Контейнер автоматически увеличивает количество сегментов по мере необходимости, чтобы поддерживать коэффициент заполнения ниже этого числа Константа
a. max_load_factor ( z ) void z положительное число. Может изменить максимальный коэффициент загрузки контейнера, используя z в качестве подсказки Константная
a. rehash ( n ) void Гарантирует:

a. bucket_count ( ) >=
a. size ( ) / a. max_load_factor ( )
и a. bucket_count ( ) >= n

В среднем линейно от a. size ( ) , в худшем случае O(N 2 )
a. reserve ( n ) a. rehash ( std:: ceil (
n / a. max_load_factor ( ) ) )

Стандартная библиотека

Следующие контейнеры стандартной библиотеки удовлетворяют требованиям UnorderedAssociativeContainer :

коллекция уникальных ключей, хэшируемых по ключам
(шаблон класса)
коллекция ключей, хэшируемых по ключам
(шаблон класса)
коллекция пар ключ-значение, хэшируемых по ключам, ключи уникальны
(шаблон класса)
коллекция пар ключ-значение, хэшируемых по ключам
(шаблон класса)

Отчеты о дефектах

Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены задним числом к ранее опубликованным стандартам C++.

DR Applied to Behavior as published Correct behavior
LWG 2156 C++11 the load factor after rehashing could only be
strictly lower than the maximum load factor
allowed to be equal