在开发过程中使用到了一个需要以整数作为key的哈希表,不知道是否大家也有类似需要,发布在这里供大家参考一下。这个哈希表非线程安全,使用的时候需要注意。如果有什么错误的地方,希望大家批评指正。
/**
* 自己写的简单哈希表,以int值作为key,key值不能大于0x7fffffff。非线程安全。
* 使用的时候需要注意:因为这里使用的哈希算法太过简单,所以作为key值分布和预留的缓冲区长度之间的关系会影响存取速度。
*
* @author cuilichen
*
*/
public class HashtableInt {
/**
* 对象列表
*/
private Item[] table;
/**
* 总数量
*/
private int count;
/**
* rehash的阀值
*/
private int threshold;
/**
* 构造函数
*/
public HashtableInt() {
this(32);
}
/**
* 构造函数
*/
public HashtableInt(int cap) {
if (cap < 16) {
cap = 16;
}
this.table = new Item[cap];
this.threshold = cap * 75 / 100;
}
/**
* 根据key,得到对象
*
* @param key
* @return
*/
public Object get(int key) {
int index = key % table.length;
for (Item e = table[index]; e != null; e = e.next) {
if (e.key == key) {
return e.value;
}
}
return null;
}
/**
* 添加对象
*
* @param key
* @param value
*/
public void put(int key, Object value) {
int index = key % table.length;
for (Item e = table[index]; e != null; e = e.next){
if (e.key == key) {
e.value = value;
return;
}
}
if (this.count >= this.threshold) {
rehash();
put(key, value);
return;
}
Item e = new Item();
e.key = key;
e.value = value;
e.next = table[index];
table[index] = e;
this.count += 1;
}
/**
* 根据key,删除对象
*
* @param key
* @return
*/
public Object remove(int key) {
int index = key % table.length;
Item e = table[index];
for (Item prev = null; e != null;) {
if (e.key == key) {
if (prev != null) {
prev.next = e.next;
} else {
table[index] = e.next;
}
this.count -= 1;
return e.value;
}
prev = e;
e = e.next;
}
return null;
}
/**
* rehash
*/
protected void rehash() {
int oldCapacity = this.table.length;
Item[] oldTable = this.table;
int newCapacity = oldCapacity * 2 + 1;
Item[] newTable = new Item[newCapacity];
this.threshold = (newCapacity * 75 / 100);
this.table = newTable;
int i = oldCapacity;
while (i-- > 0) {
for (Item old = oldTable[i]; old != null;) {
Item e = old;
old = old.next;
int index = e.key % newCapacity;
e.next = newTable[index];
newTable[index] = e;
}
}
}
/**
* 清空哈希表
*/
public void clear() {
for (int index = table.length; --index >= 0;) {
table[index] = null;
}
this.count = 0;
}
/**
* 得到哈希表的长度
*
* @return
*/
public int size() {
return this.count;
}
/**
* 判断哈希表是否是空的
*
* @return
*/
public boolean isEmpty() {
return count == 0;
}
/**
* 判断哈希表中是否有某个对象
*
* @param value
* @return
*/
public boolean contains(Object value) {
int i = table.length;
while (i-- > 0) {
for (Item e = table[i]; e != null; e = e.next) {
if (e.value.equals(value)) {
return true;
}
}
}
return false;
}
/**
* 判断哈希表中是否有某个key
*
* @param key
* @return
*/
public boolean containsKey(int key) {
int index = key % table.length;
for (Item e = table[index]; e != null; e = e.next) {
if (e.key == key) {
return true;
}
}
return false;
}
/**
* 得到哈希表中所有的key
*
* @return
*/
public int[] keys() {
int[] keys = new int[count];
int ind = 0;
for (int i = 0; i < table.length; i++) {
for (Item old = table[i]; old != null;) {
Item e = old;
old = old.next;
keys[ind] = e.key;
ind++;
if (ind >= count) {
break;
}
}
}
return keys;
}
/**
* 将哈希表中的所有数据打印到控制台
*/
public void debug() {
for (int i = 0; i < table.length; i++) {
System.out.print(i + "/t");
if (table[i] == null) {
System.out.print("null");
System.out.print('/n');
} else {
for (Item old = table[i]; old != null;) {
Item e = old;
old = old.next;
System.out.print(e.key + ":" + e.value + "/t");
}
System.out.print('/n');
}
}
}
/**
* 哈希表中的每个项
*
* @author cuilichen
*
*/
private class Item {
int key;
Object value;
Item next;
}
/**
* 测试
*
* @param args
*/
public static void main(String[] args) {
HashtableInt table = new HashtableInt(40);
for (int i = 0; i < 20; i++) {
table.put(i, "" + i);
}
for (int i = 0; i < 10; i++) {
table.put(40 + i, "" + (40 + i));
}
table.put(81, "" + 81);
table.debug();
table.remove(0);
System.out.println("");
table.debug();
System.out.println("");
System.out.println(table.size());
System.out.println(table.contains("31"));
System.out.println(table.contains("41"));
System.out.println(table.get(10));
}
}