限制Java中HashMap的最大大小

我想限制HashMap的最大大小,以便对我正在实现的各种散列算法采用指标。 我在HashMap的一个重载构造函数中查看了loadfactor。

 HashMap(int initialCapacity, float loadFactor) 

我尝试在构造函数中将loadFactor设置为0.0f(意味着我不希望HashMap的大小增长为EVER),但javac将此调用为无效:

 Exception in thread "main" java.lang.IllegalArgumentException: Illegal load factor: 0.0 at java.util.HashMap.(HashMap.java:177) at hashtables.CustomHash.(Main.java:20) at hashtables.Main.main(Main.java:70) Java Result: 1 

有没有其他方法来限制HashMap的大小,所以它不会增长?

有时候更简单更好。

 public class InstrumentedHashMap implements Map { private Map map; public InstrumentedHashMap() { map = new HashMap(); } public boolean put(K key, V value) { if (map.size() >= MAX && !map.containsKey(key)) { return false; } else { map.put(key, value); return true; } } ... } 

您可以创建一个这样的新类来限制HashMap的大小:

 public class MaxSizeHashMap extends LinkedHashMap { private final int maxSize; public MaxSizeHashMap(int maxSize) { this.maxSize = maxSize; } @Override protected boolean removeEldestEntry(Map.Entry eldest) { return size() > maxSize; } } 

简单的解决方案通常是最好的,因此使用不可修改或不可变的 hashmap。

如果你不能改变元素的数量,那么大小将被修复 – 问题解决了。

 public class Cache { private LinkedHashMap Cache = null; private final int cacheSize; private ReadWriteLock readWriteLock=null; public Cache(LinkedHashMap psCacheMap, int size) { this.Cache = psCacheMap; cacheSize = size; readWriteLock=new ReentrantReadWriteLock(); } public void put(String sql, String pstmt) throws SQLException{ if(Cache.size() >= cacheSize && cacheSize > 0){ String oldStmt=null; String oldSql = Cache.keySet().iterator().next(); oldStmt = remove(oldSql); oldStmt.inCache(false); oldStmt.close(); } Cache.put(sql, pstmt); } public String get(String sql){ Lock readLock=readWriteLock.readLock(); try{ readLock.lock(); return Cache.get(sql); }finally{ readLock.unlock(); } } public boolean containsKey(String sql){ Lock readLock=readWriteLock.readLock(); try{ readLock.lock(); return Cache.containsKey(sql); }finally{ readLock.unlock(); } } public String remove(String key){ Lock writeLock=readWriteLock.writeLock(); try{ writeLock.lock(); return Cache.remove(key); }finally{ writeLock.unlock(); } } public LinkedHashMap getCache() { return Cache; } public void setCache( LinkedHashMap Cache) { this.Cache = Cache; } } 

put HashMap类的方法是负责将元素添加到HashMap中的方法,它通过调用名为addEntry的方法来完成,其代码如下:

  void addEntry(int hash, K key, V value, int bucketIndex) { Entry e = table[bucketIndex]; table[bucketIndex] = new Entry(hash, key, value, e); if (size++ >= threshold) resize(2 * table.length); } 

正如您在此方法中所看到的,如果已超出阈值,则调整HashMap的大小,因此我将尝试扩展类HashMap并为putaddEntry编写自己的方法以删除resize。 就像是:

 package java.util; public class MyHashMap extends HashMap { private V myPutForNullKey(V value) { for (Entry e = table[0]; e != null; e = e.next) { if (e.key == null) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; myAddEntry(0, null, value, 0); return null; } public V myPut(K key, V value) { if (key == null) return myPutForNullKey(value); if (size < table.length) { int hash = hash(key.hashCode()); int i = indexFor(hash, table.length); for (Entry e = table[i]; e != null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; myAddEntry(hash, key, value, i); } return null; } void myAddEntry(int hash, K key, V value, int bucketIndex) { Entry e = table[bucketIndex]; table[bucketIndex] = new Entry(hash, key, value, e); size++; } } 

你需要编写自己的方法,因为putaddEntry不能覆盖,你也需要对putForNullKey做同样的putForNullKey因为它在put内部被调用。 如果表已满,则需要validationput以validation我们没有尝试放置对象。