Я бы цикл по коллекции вставки в картах с структурой данные следующей логикой:
- Если число еще не было включено в карту, а затем вставить ключ = целое число, значение = 1.
- Если ключ существует, увеличьте значение.
Есть две карты в Java можно использовать - HashMap и TreeMap - это сравниваются ниже:
HashMap против TreeMap
Вы можете пропустить подробное объяснение прыжок прямо к просмотр если желаете.
HashMap - это карта, в которой хранятся пары ключ-значение в массиве.Индекс, используемый для ключа к является:
Иногда две совершенно разные клавиши будут в конечном итоге в том же индексе. Чтобы решить эту проблему, каждое местоположение в массиве является действительно связанным списком, что означает, что каждый поиск всегда должен пересекать связанный список и проверять равенство с помощью метода k.equals (other). В худшем случае все ключи хранятся в одном месте, а HashMap становится необъявленным списком.
Поскольку HashMap получает больше записей, вероятность этих столкновений возрастает, а эффективность структуры уменьшается. Чтобы решить эту проблему, когда число записей достигает критической точки (определяемый loadFactor аргумента в конструктор), структура изменяется:
- Новый массив выделяется примерно в два раза текущего размера
- A цикл выполняется по всем существующим ключей
- расположение ключа пересчитывается для нового массива
- пара ключ-значение вставляется в новую структуру
Как вы можете видеть, это может стать относительно дорогостоящим, если есть много размеров.
Эта проблема может быть решена, если вы можете предварительно выделить HashMap в соответствующем размере до начала, например map = new HashMap (input.size() * 1.5). Для больших наборов данных это может значительно уменьшить износ памяти.
Поскольку ключи по существу беспорядочно расположены в HashMap, итератор ключа будет перебирать их в случайном порядке. Java предоставляет ссылку LinkedHashMap, которая будет итератором в том порядке, в котором были вставлены ключи.
Performance для HashMap:
- Учитывая правильный размер и хорошее распределение хэш, поиск является постоянная временем.
- С плохим распределением производительность падает до (в худшем случае) линейного поиска - O (n).
- С плохой начальной калибровкой производительность становится переделкой. Я не могу тривиально вычислить это, но это не хорошо.
OTOH TreeMap хранит записи в сбалансированном дереве - добавляется динамическая структура, которая постепенно увеличивается, поскольку пары ключ-значение добавляются. Вставка зависит от глубины дерева (log (tree.size()), но предсказуема - в отличие от HashMap, нет перерывов и нет краевых условий, при которых производительность падает.
Каждая вставка и поиск дороже с учетом хорошо распределенной HashMap.
Кроме того, чтобы вставить ключ в дерево, каждый ключ должен быть сопоставим с любым другим ключом, требующим метода k.compare (другого) из интерфейса Comparable. вопрос о целых числах, это не проблема.
Производительность на TreeMap:
- Вставка из п элементов О (п § п)
- просмотра является O (журнал N)
Резюме
Первый мысли: Размер данных:
- Если маленький (даже в 1000-х и 10 000-х годах) действительно не имеет значения на каком-либо современном оборудовании
- Если большой, чтобы привести к тому, что машина исчерпала память, тогда TreeMap может быть единственным вариантом
- в противном случае, размер, вероятно, не является определяющим фактором
в данном конкретном случае, ключевым фактором является ли ожидаемое число уникальных целых чисел велико или мало по сравнению с общим размером набора данных?
- Если мало, то общее время будет доминировать поиска ключей в небольшого набора, поэтому оптимизация не имеет никакого значения (вы можете остановиться здесь).
- Если большой, то общее время будет доминировать вставки, и решение лежит на нескольких факторов:
- Dataset является известного размера?
- Если да: HashMap может быть предварительно выделен, и поэтому отбраковка памяти будет устранена. Это особенно важно, если метод хэш-код() дорого (не в нашем случае)
- Если нет: A TreeMap обеспечивает более предсказуемую производительность и может быть лучшим выбором
- предсказуема производительность без больших киосков требуется , например, в системах реального времени или в потоке событий графического интерфейса?
- Если да: A TreeMap обеспечивает гораздо лучшую предсказуемость без каких-либо киосков
- Если нет: HashMap лучше, вероятно, обеспечивает лучшую производительность для всего вычисления
Один последний момент, если не является ошеломляющей точкой сверху:
- Является ли отсортированный список ключей?
- Если да (например, для печати гистограмму): A TreeMap уже отсортирован ключи, и поэтому удобно
Однако, если производительность важна, единственный способ решить бы чтобы реализовать интерфейс карты, затем профиль и HashMap и TreeMap, чтобы увидеть, что на самом деле лучше в вашей ситуации. Premature optimization - корень большого зла :)
Чтобы избежать путаницы, вы можете изменить слово «установить» на «сборку», поскольку термин «набор» имеет определенное значение в Java, и дублирование не допускается с помощью наборов Java. Подумайте об использовании 'HashMap', чтобы удерживать номер (ключ) и его частоту (значение). –
Вы действительно вставляете значения в набор целых чисел? или они исходят из какого-то внешнего источника. –
Я указал его явно в круглых скобках, но я сделаю это на всякий случай. – Erol