// The code below is licensed under the WTFPL. // Here is a copy for your convenience: // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE // Version 2, December 2004 // // Copyright (C) 2004 Sam Hocevar // // Everyone is permitted to copy and distribute verbatim or modified // copies of this license document, and changing it is allowed as long // as the name is changed. // // DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE // TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION // // 0. You just DO WHAT THE FUCK YOU WANT TO. import java.util.ArrayList; import java.util.List; /** *

* This is a naive implementation of a look up table. Store and retrieve key * value pairs. *

* *

* I had no reason to implement this other than not wanting to go down a rabbit * hole of Java types rather than just using simple functionality. *

* * @author BodgeMaster * * @param The type to be stored */ public class LookUpTable { private List values; private String[] keys; private boolean[] usedSlots; private int storedElements; public LookUpTable() { this.values = new ArrayList(); for (int i = 0; i < 10; i++) { values.add(null); } this.keys = new String[10]; this.usedSlots = new boolean[] { false, false, false, false, false, false, false, false, false, false }; this.storedElements = 0; } /** * Add an element * * @param key * @param value * @throws DuplicateKeyException */ public void add(String key, T value) { // duplicate check for (int i = 0; i < this.keys.length; i++) { if (usedSlots[i]) { if (keys[i].equals(key)) throw new DuplicateKeyException(key); } } // Make bigger arrays when running out of space if (this.storedElements == this.keys.length) { String[] keys = this.keys; boolean[] usedSlots = this.usedSlots; this.keys = new String[keys.length + 10]; this.usedSlots = new boolean[usedSlots.length + 10]; for (int i = 0; i < keys.length; i++) { this.keys[i] = keys[i]; this.usedSlots[i] = usedSlots[i]; } for (int i = 0; i < 10; i++) { // ensure capacity this.values.add(null); } } // Find next unused slot int unusedSlot = 0; for (int i = 0; i < this.usedSlots.length; i++) { if (!this.usedSlots[i]) { unusedSlot = i; break; } } this.keys[unusedSlot] = key; this.values.set(unusedSlot, value); usedSlots[unusedSlot] = true; this.storedElements++; } /** * Get a value by key * * @param key * @return value (null if key not found) */ public T get(String key) { for (int i = 0; i < usedSlots.length; i++) { if (usedSlots[i]) { if (keys[i].equals(key)) return values.get(i); } } return null; } public void set(String key, T value) { for (int i = 0; i < usedSlots.length; i++) { if (usedSlots[i]) { if (keys[i].equals(key)) values.set(i, value); } } } /** *

* Remove an element from the LUT *

* *

* This function marks the position of key as unused. If you actually want to * ensure that the object is removed from the LUT, use * {@link LookUpTable#fullRemove(String)} instead. *

* * @param key */ public void remove(String key) { for (int i = 0; i < usedSlots.length; i++) { if (usedSlots[i]) { if (keys[i].equals(key)) usedSlots[i] = false; } } storedElements--; } /** * Remove an element from the LUT by actually setting it to null. * * @param key */ public void fullRemove(String key) { for (int i = 0; i < usedSlots.length; i++) { if (usedSlots[i]) { if (keys[i].equals(key)) { values.set(i, null); usedSlots[i] = false; } } } storedElements--; } public int storedElements() { return this.storedElements; } /** * Gets a key by its position in the LUT. Unused slots are ignored and do not * count towards the position. * * @param index * @return key */ public String getKey(int index) { int i = 0; int j = 0; while (i < index) { j++; if (usedSlots[j]) i++; } return keys[j]; } public static class DuplicateKeyException extends RuntimeException { public DuplicateKeyException() { super("Tried adding an element with a duplicte key to a LookUpTable."); } public DuplicateKeyException(String key) { super("Tried adding an element with a duplicte key to a LookUpTable: " + key); } } }