DoubleKeyMap_实现
来源:互联网 发布:敏捷软件开发 pdf 编辑:程序博客网 时间:2024/06/16 08:10
DoubleKeyMap接口类
package cs601.collections;import java.util.List;/** A Map (Dictionary) just like Java's Map<K,V> interface except that * this interface has 2 keys instead of just one. Otherwise it works * the same way. */public interface DoubleKeyMap<K1,K2,V> { /** Add (key1,key2,value) to dictionary, overwriting previous * value if any. key1, key2, and value must all be non-null. * If any is null, throw IllegalArgumentException. * @return the previous value associated with <tt>key</tt>, or * <tt>null</tt> if there was no mapping for <tt>key</tt>. * */ V put(K1 key1, K2 key2, V value); /** Return the value associated with (key1, key2). Return null if * no value exists for those keys. key1, key2 must be non-null. * If any is null, throw IllegalArgumentException. The value * should be just the value added by the user via put(), and * should not contain any of your internal bookkeeping * data/records. */ V get(K1 key1, K2 key2); /** Remove a value if present. Return previous value if any. * Do nothing if not present. */ V remove(K1 key1, K2 key2); /** Return true if there is a value associated with the 2 keys * else return false. * key1, key2 must be non-null. If either is null, return false. */ boolean containsKey(K1 key1, K2 key2); /** Return list of a values in the map/dictionary. Return an * empty list if there are no values. The values should be just * the values added by the user via put(), and should not contain * any of your internal bookkeeping data/records. */ List<V> values(); /** Return how many elements there are in the dictionary. */ int size(); /** Reset the dictionary so there are no elements. */ void clear();}
DoubleKeyHashMap 内部构建了一个hashtable实现
package cs601.collections;import java.util.*;public class DoubleKeyHashMap<K1, K2, V> implements DoubleKeyMap<K1, K2, V> { private float loadFactor; private int threshold; private LinkedList<Entry<K1, K2, V>>[] table; private int count; private static final int MAX_TABLE_SIZE = Integer.MAX_VALUE - 8; public static class Entry<K1, K2, V> { final int hash; final K1 key1; final K2 key2; V value; protected Entry(int hash, K1 key1, K2 key2, V value) { this.hash = hash; this.key1 = key1; this.key2 = key2; this.value = value; } public K1 getKey1() { return key1; } public K2 getKey2() { return key2; } public V getValue() { return value; } public V setValue(V value) { if (value == null) { throw new IllegalArgumentException("Entry setValue must be non-nil"); } V oldValue = this.value; this.value = value; return oldValue; } } public DoubleKeyHashMap() { this(11); } public DoubleKeyHashMap(int initialCapacity) { this(initialCapacity, 0.75f); } public DoubleKeyHashMap(int initialCapacity, float loadFactor) { if (initialCapacity < 0) { throw new IllegalArgumentException("initialCapacity must be non-0"); } if (loadFactor <= 0 || Float.isNaN(loadFactor)) { throw new IllegalArgumentException("Illegal Load: " + loadFactor); } if (initialCapacity == 0) { initialCapacity = 1; } this.loadFactor = loadFactor; table = (LinkedList<Entry<K1, K2, V>>[]) new LinkedList[initialCapacity]; this.threshold = (int) (loadFactor * initialCapacity); } Map<K1, Map<K2, V>> data = new HashMap<K1, Map<K2, V>>(); List<V> values; private void checkKeys(K1 key1, K2 key2) { if (key1 == null) { throw new IllegalArgumentException("key1 must be non-nil"); } if (key2 == null) { throw new IllegalArgumentException("key2 must be non-nil"); } } @Override public V put(K1 key1, K2 key2, V value) { checkKeys(key1, key2); LinkedList<Entry<K1, K2, V>>[] tab = table; int hash = Math.abs(key1.hashCode() * 37 + key2.hashCode()); int index = (hash & 0x7FFFFFFF) % tab.length; LinkedList<Entry<K1, K2, V>> entrys = tab[index]; if (entrys != null) { int entrySize = entrys.size(); for (int i = 0; i < entrySize; i++) { Entry<K1, K2, V> entry = entrys.get(i); if (key1.equals(entry.key1) && key2.equals(entry.key2) && hash == entry.hash) { V oldValue = entry.setValue(value); return oldValue; } } } if (count >= threshold) { rehash(); tab = table; hash = Math.abs(key1.hashCode() * 37 + key2.hashCode()); index = (hash & 0x7FFFFFFF) % tab.length; } if (entrys == null) { entrys = new LinkedList<Entry<K1, K2, V>>(); } entrys.addFirst(new Entry<K1, K2, V>(hash, key1, key2, value)); tab[index] = entrys; count++; return null; } private void rehash() { int oldCapacity = table.length; LinkedList<Entry<K1, K2, V>>[] oldTable = table; int newCapacity = (oldCapacity << 1) + 1; if (newCapacity - MAX_TABLE_SIZE > 0) { if (oldCapacity == MAX_TABLE_SIZE) { return; } newCapacity = MAX_TABLE_SIZE; } LinkedList<Entry<K1, K2, V>>[] newTable = (LinkedList<Entry<K1, K2, V>>[]) new LinkedList[newCapacity]; threshold = (int) Math.min(newCapacity * loadFactor, MAX_TABLE_SIZE + 1); table = newTable; for (int i = oldCapacity; i-- > 0; ) { LinkedList<Entry<K1, K2, V>> oldEntrys = oldTable[i]; if (oldEntrys == null) { continue; } for (int j = 0; j < oldEntrys.size(); j++) { Entry<K1, K2, V> entry = oldEntrys.get(j); int index = (entry.hash & 0x7FFFFFFF) % newCapacity; LinkedList<Entry<K1, K2, V>> indexEntrys = newTable[index]; if (indexEntrys == null) { indexEntrys = new LinkedList<Entry<K1, K2, V>>(); } indexEntrys.addFirst(entry); newTable[index] = indexEntrys; } } } @Override public V get(K1 key1, K2 key2) { checkKeys(key1, key2); LinkedList<Entry<K1, K2, V>>[] tab = table; int hash = Math.abs(key1.hashCode() * 37 + key2.hashCode()); int index = (hash & 0x7FFFFFFF) % tab.length; LinkedList<Entry<K1, K2, V>> entrys = tab[index]; if (entrys == null) { return null; } for (int i = 0; i < entrys.size(); i++) { Entry<K1, K2, V> entry = entrys.get(i); if (key1.equals(entry.key1) && key2.equals(entry.key2) && hash == entry.hash) { return entry.value; } } return null; } @Override public V remove(K1 key1, K2 key2) { if (key1 == null || key2 == null) { return null; } LinkedList<Entry<K1, K2, V>>[] tab = table; int hash = Math.abs(key1.hashCode() * 37 + key2.hashCode()); int index = (hash & 0x7FFFFFFF) % tab.length; LinkedList<Entry<K1, K2, V>> entrys = tab[index]; if (entrys == null) { return null; } for (int i = 0; i < entrys.size(); i++) { Entry<K1, K2, V> entry = entrys.get(i); if (key1.equals(entry.key1) && key2.equals(entry.key2) && hash == entry.hash) { entrys.remove(entry); if (entrys.isEmpty()) { tab[index] = null; } return entry.value; } } return null; } @Override public boolean containsKey(K1 key1, K2 key2) { if (key1 == null || key2 == null) { return false; } LinkedList<Entry<K1, K2, V>>[] tab = table; int hash = Math.abs(key1.hashCode() * 37 + key2.hashCode()); int index = (hash & 0x7FFFFFFF) % tab.length; LinkedList<Entry<K1, K2, V>> entrys = tab[index]; if (entrys == null) { return false; } for (int i = 0; i < entrys.size(); i++) { Entry<K1, K2, V> entry = entrys.get(i); if (key1.equals(entry.key1) && key2.equals(entry.key2) && hash == entry.hash) { return true; } } return false; } @Override public List<V> values() { if (values == null) { values = new ArrayList<V>(); } values.clear(); LinkedList<Entry<K1, K2, V>>[] tab = table; for (int i = 0; i < tab.length; i++) { LinkedList<Entry<K1, K2, V>> entrys = tab[i]; if (entrys == null) { continue; } for (Entry<K1, K2, V> entry : entrys) { values.add(entry.value); } } return values; } @Override public int size() { return values().size(); } @Override public void clear() { LinkedList<Entry<K1, K2, V>>[] tab = table; for (int i = tab.length; i-- >= 0; ) { tab[i] = null; } }}
0 0
- DoubleKeyMap_实现
- 实现
- 实现
- 红黑树实现 实现代码
- java实现排列组合实现
- 实现Runnable 实现线程
- 实现ViewPager多种实现
- 双向LSTM实现实现
- 实现缓存 java实现
- 三子棋的实现的实现的实现
- 四则运算实现
- 继承实现
- 重载实现
- 实现缩略图
- split实现
- 实现缩略图
- wmi实现
- 实现缩略图
- 13--信号量,共享内存和消息队列
- 子曰不在词
- 【android 开发知识积累】——属性(Attribute)资源的使用和自定义View组件
- Failed to load the JNI shared library
- String 类
- DoubleKeyMap_实现
- Minimum Path Sum
- OK6410(s3c6410)存储方式之NAND FLASH
- javascript正则表达式
- Jdon Framework
- POJ 3181 Dollar Dayz 01完全背包问题
- XDOJ1264 - 递推5
- 初识android的广播BroadCast
- Jdon