所以我需要某种多字符集,其中添加重复字符会使基数增加 1,并且字符的多样性不应大幅增加对象占用的内存。
这将通过某种映射来实现,其中字符是键,它保存一个值,该值表示该字符在集合中的数量。
但是,我正在努力找出最适合此的集合(我正在查看 hashmap)以及如何声明此数据类型。我正在做这样的事情
Map m = new HashMap(char, int);
但以上是一个不正确的声明,我不确定如何准确地解决这个问题。
所以我需要某种多字符集,其中添加重复字符会使基数增加 1,并且字符的多样性不应大幅增加对象占用的内存。
这将通过某种映射来实现,其中字符是键,它保存一个值,该值表示该字符在集合中的数量。
但是,我正在努力找出最适合此的集合(我正在查看 hashmap)以及如何声明此数据类型。我正在做这样的事情
Map m = new HashMap(char, int);
但以上是一个不正确的声明,我不确定如何准确地解决这个问题。
试试这个声明:
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[][]
unicode 来实现它。考虑到将装箱整数存储在哈希映射中的内存占用以及使用数字引入的所有哈希冲突,并且字符只不过是数字作为键。
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];
}
}
这从零内存占用开始,并为每个 unicode 页增加 2K。通常,文本使用一两个 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 的包装类是整数)。
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);
把事情简单化。