Array-based implementation of the Map interface. This implementation requires a Indexer, which provides a unique index for each key object that could be put into this map. Since the indexer maintains the mappings between objects and indexes, this map does not need to store the ke
| 49 | * TODO: add mod count |
| 50 | */ |
| 51 | public class IndexMap<K, V> extends AbstractMap<K, V> |
| 52 | implements Serializable { |
| 53 | |
| 54 | private static final String NULL_VALUE_MSG = "IndexMap does not permit null values"; |
| 55 | |
| 56 | private final Indexer<K> indexer; |
| 57 | |
| 58 | private V[] values; |
| 59 | |
| 60 | private int size = 0; |
| 61 | |
| 62 | /** |
| 63 | * The cache of {@link IndexMap#entrySet()}. |
| 64 | */ |
| 65 | private transient Set<Entry<K, V>> entrySet; |
| 66 | |
| 67 | /** |
| 68 | * The cache of {@link IndexMap#keySet()}. |
| 69 | */ |
| 70 | private transient Set<K> keySet; |
| 71 | |
| 72 | public IndexMap(Indexer<K> indexer, int initialCapacity) { |
| 73 | this.indexer = indexer; |
| 74 | this.values = (V[]) new Object[initialCapacity]; |
| 75 | } |
| 76 | |
| 77 | public int capacity() { |
| 78 | return values.length; |
| 79 | } |
| 80 | |
| 81 | @Override |
| 82 | public int size() { |
| 83 | return size; |
| 84 | } |
| 85 | |
| 86 | @Override |
| 87 | public boolean isEmpty() { |
| 88 | return size == 0; |
| 89 | } |
| 90 | |
| 91 | @Override |
| 92 | public boolean containsKey(Object key) { |
| 93 | int index = indexer.getIndex((K) key); |
| 94 | return isValidIndex(index) && values[index] != null; |
| 95 | } |
| 96 | |
| 97 | private boolean isValidIndex(int index) { |
| 98 | return 0 <= index && index < values.length; |
| 99 | } |
| 100 | |
| 101 | @Override |
| 102 | public V get(Object key) { |
| 103 | int index = indexer.getIndex((K) key); |
| 104 | return isValidIndex(index) ? values[index] : null; |
| 105 | } |
| 106 | |
| 107 | @Override |
| 108 | public V put(K key, V value) { |
nothing calls this directly
no outgoing calls
no test coverage detected