Nyoxide

Adam's Sick Map Tips

Mar 20th, 2020
837
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.28 KB | None | 0 0
  1. /*
  2. BUCKETS
  3. Entries in maps are stored in 'buckets'. To demonstrate with a simple example, you can imagine the following integer array and an imaginary map class:
  4. */
  5.  
  6. int[] nums = new int[]{1, 4, 8, 10};
  7. AdamsMap<Integer,Integer> map = new AdamsMap<>();
  8.  
  9. /*
  10. Now, imagine that we wish to store the 'nums' values into 'map'. We can 'hash' each value, to see which index in the map's underlying structure we should store the value at. For example, a simple hash that would work fine for this limited data set is something like this:
  11. */
  12.  
  13. public int hash(int num) {
  14.         return num;
  15. }
  16.  
  17. // Assume that inside of our map, we have a structure that looks like this:
  18.  
  19. public class SpecialMap<K, V> {
  20.         Node[] nodes = new Node[11];
  21.  
  22.         public void put(K key, V value) {
  23.                 int hash = hash(key);
  24.                 Node node = new Node(key,val);
  25.                 nodes[hash] = node;
  26.         }
  27. }
  28.  
  29. public class Node<K,V> {
  30.         private K key;
  31.         private V val;
  32.         private Node<K,V> next;
  33.  
  34.         public Node(K key, V val) { this.key = key; this.val = val; }
  35. }
  36.  
  37. /*
  38. Now, when we hash each value, the return result will tell us where in the underlying array that we wish to store the value at. So when we hash the first value, 1, we get the index 1. So now we know that we wish to store 1 at the index of 1 inside of our map. You can repeat this process for each value in the example array, and this will lead to a map that has an entry for each of these values. You can imagine that we are preserving some sort of value within the map by using the Node objects, so now we have a very simple key->value mapping that works for any set of integers between 0-10.
  39. */
  40.  
  41. /*
  42. COLLISIONS - Let's make it a little harder now. Imagine an array that instead contains Strings!
  43. */
  44.  
  45. String[] strings = new String[]{"Adam", "Is", "Always", "Cool"}
  46.  
  47. /*
  48. How do we hash this? Well, good question. Don't worry too much about that. hashCode(). But for the sake of example, let's do a much simpler hash. We will have to change our map structure a bit to compensate for this change. Consider this:
  49. */
  50.  
  51. public int hash(String key) {
  52.         return String.valueOf(key.charAt(0)).toLowerCase();
  53. }
  54.  
  55. public class SpecialMap<K, V> {
  56.         Node[] nodes = new Node[123];
  57.  
  58.         public void put(K key, V value) {
  59.                 int hash = hash(key);
  60.                 Node node = new Node(key,val);
  61.                 nodes[hash] = node;
  62.         }
  63. }
  64.  
  65. /*
  66. This is really similar, with the only changes being made to how the hash function works, and the initial size of the map's underlying array. As for the hash function,  now it just looks at the first letter in the string and returns the value of that specific character. Cool, so now we have a similar function like above with the integer array and we can once again just get the index we wish to store each value at. What happens when we attempt to store the 3rd string, "Always"?
  67.  
  68. We have now caused a hash collision! I know! Isn't it fun? Let's imagine what the map looks like after the first two values have been inserted:
  69.  
  70. a = 97
  71. i = 105
  72.  
  73. So we know that the array is full of nulls except at these two indices. Map[97] contains a node with the information from the first element of the array, and Map[105] contains a node with information from the second element. But now we wish to store a value at Map[97] again! So what we do now, is the node at Map[97], the one where we have stored "Adam", we now make that Node into a LinkedList. Because traversing the elements of a LinkedList is very fast ( O(n) ), this allows us to access elements of the Map quickly even when there are many, many entries.
  74.  
  75. So let's rewrite the put() method to work with this new LinkedList idea.
  76. */
  77.  
  78. public class SpecialMap<K, V> {
  79.         Node[] nodes = new Node[123];
  80.  
  81.         public void put(K key, V value) {
  82.                 int index = hashCode.charAt(0) - 'a';
  83.                 Node newNode = new Node(key, value);
  84.                 Node head = nodes[index];
  85.                 if (head == null) {
  86.                         nodes[index] = newNode;
  87.                 } else {
  88.                         while (head.hasNext()) {
  89.                                 head = head.getNext();
  90.                         }
  91.                         head.setNext(newNode);
  92.         }      
  93. }
Advertisement
Add Comment
Please, Sign In to add comment