Создание неупорядоченной карты <char, int> в Java

Поэтому мне нужно иметь какой-нибудь мультимножество символов, в котором добавление повторяющегося символа увеличивает количество элементов на 1, а множественность символов не должна резко увеличивать объем памяти, занимаемой объектом.

Это будет реализовано с помощью некоторой карты, где символы являются ключами, которые содержат значение, представляющее номер этого символа, представленного в наборе.

Тем не менее, я изо всех сил пытаюсь выяснить, какая коллекция будет лучше для этого (я смотрел на hashmap) и как объявить этот тип данных. Я делал что-то вроде этого

Map m = new HashMap(char, int);

Но вышеупомянутое - неправильная декларация, и я не уверен, как точно подойти к этому.

5 ответов

Решение

Попробуйте это объявление:

Map<Character, Integer> m = new HashMap<Character, Integer>();

Затем вы можете добавить символы как таковые:

char c = //...;
if (m.containsKey(c))
    m.put(c, m.get(c) + 1);
else
    m.put(c, 1);

Я бы реализовал это используя int[] (для ASCII) или int[][] для юникода. Учитывая объем памяти для хранения целых чисел в штучной упаковке в хэш-карте со всеми конфликтами хеширования, введенными с использованием чисел, а символы являются ничем иным, как числами, в качестве ключей.

public class CharacterBag {

    private int[][] data = new int[255][];

    public void add(char ch) {
        int[] bin = data[ch >> 8];
        if (bin == null) bin = data[ch >> 8] = new int[255];
        bin[ch & 0xFF]++;
    }

    public int frequency(char ch) {
        int[] bin = data[ch >> 8];
        if (bin == null) return 0;
        return bin[ch & 0xFF];
    }

}

Это начинается с объема памяти, равного нулю, и добавляет 2 КБ для каждой страницы Unicode. Обычно в тексте используются символы одной или двух страниц Юникода.

Для сравнения, использование HashMap будет иметь все издержки хранения примитивов в штучной упаковке в списке связанных списков. Для каждого персонажа найдется объект Entry класс с двумя указателями, указывающими на коробочный ключ, и связанный объект списка со всеми его полями, который содержит объект класса Node с указателем вперед и назад и который имеет указатель на целое в штучной упаковке... я должен идти?;)

Map<Character, Integer> charCount = new HashMap<Character, Integer>();

public void addCharacter(char c) {
    Integer value = charCount.get(c);
    if (value == null) {
        charCount.put(c, 1);
    } else {
        charCount.put(c, value + 1);
    }
}

Коллекции Java не позволяют вам создавать коллекцию примитивных типов, скорее, вы должны использовать их соответствующий класс-оболочку (например, класс-оболочка для int - это Integer).

Map<Character,Integer> hashMap = new HashMap<Character,Integer>();

Вот как вы объявляете карту. больше примеров и объяснений смотрите здесь

На мой взгляд, лучший способ - использовать конструктор:

Map<Key, Value> orgMap = new HashMap<Key, Value>();
Map<Key, Value> copyMap;
copyMap= new HashMap<Key, Value>(map);

Будь проще.

Другие вопросы по тегам