Создание неупорядоченной карты <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);
Будь проще.