Devo implementare una mappa attraverso una HashTable tramite l'utilizzo di un'array di liste concatenate per la gestione delle collisioni. Bene o male i metodi sono riuscito a crearli solo che ogni volta che accedo ai metodi dell'array di linked-list mi lancia un NullPointerException in esecuzione. In pratica il programma si arresta non appena chiamo un metodo di bucket.
Vi posto il codice:
e questa è la classe Nodocodice:public class SeparateChainingHashTable<K,V> implements Map<K,V> { /** * Classe innestata per LinkedList di HashTable. **/ public static class LinkedList<K,V> { /** Testa della lista. */ public Node<K,V> head; /** Dimensione della lista*/ protected long size; /** Costruttore */ public LinkedList() { head = null; size = 0; } /** * Restituisce il valore associato alla chiave. * @param key la chiave per cui si cerca il valore. * @return il valore associato alla chiave. **/ public V get(K key) { for (Node<K,V> temp = head; temp != null; temp = temp.getNext()) { if (temp.getKey().equals(key)) return temp.getValue(); } return null; } /** * Aggiunge o aggiorna una nuova Entry alla lista e restituisce il vecchio * valore associato alla chiave se già presente. * @param key la chiave da inserire. * @param value il valore da inserire. * @return il vecchio valore dell'Entry. */ public V add(K key, V value) { for (Node<K,V> temp = head; temp != null; temp = temp.getNext()) { if (temp.getKey().equals(key)) { // Se la chiave è già presente aggiorna V oldValue = temp.setValue(value); return oldValue; } } Node<K,V> n = new Node<K,V>(key, value, head); // Aggiunge un nodo all'inizio della catena head = n; size++; return null; } /** * Rimuove l'Entry con chiave key e restituisce il valore associato ad essa. * @param key la chiave da rimuovere. * @return il valore associato alla chiave rimossa. */ public V remove(K key) { ..................... } /** Numero di elementi nella hash table */ protected int n = 0; /** Prime factor e capacity dei bucket array */ protected int prime, capacity; /** Bucket array */ protected LinkedList<K,V>[] bucket; /** Fattori shift e scale */ protected long scale, shift; /** Costruttore default, con prime factor 109345121 e capacity 1000. */ public SeparateChainingHashTable() { this(109345121,1000); } /** Costruttore con prime factor e capacity come parametri in ingresso. */ public SeparateChainingHashTable(int p, int cap) { prime = p; capacity = cap; bucket = (LinkedList<K,V>[]) new LinkedList[capacity]; java.util.Random rand = new java.util.Random(); scale = rand.nextInt(prime-1) + 1; shift = rand.nextInt(prime); } /** * Verifica se la chiave è valida. * @param k la chiave da convalidare. */ protected void checkKey(K k) { if (k == null) throw new InvalidKeyException("Invalid key: null."); } /** * Funzione Hash che applica il metodo MAD (multiply, add, divide) allo hash code di default * @param key la chiave su cui calcolare l'hash code. * @return l'hash code generato. */ public int hashValue(K key) { return (int) ((Math.abs(key.hashCode()*scale + shift) % prime) % capacity); } public int size() { return n; } public boolean isEmpty() { return (n == 0); } /** * Restituisce il valore associato alla chiave. * @param key la chiave di cui si vuole cercare il valore. * @return il valore associato alla chiave. * @throws InvalidKeyException **/ public V get(K key) throws InvalidKeyException { checkKey(key); return (bucket[hashValue(key)].get(key)); } /** * Inserisci una coppia chiave, valore nella hash map, sostituendo il valore precedente se * k è già nella mappa. * @param key la chiave da inserire. * @param value il valore da inserire. * @return il valore della vecchia entry (se esistente). * @throws InvalidKeyException **/ public V put(K key, V value) throws InvalidKeyException { checkKey(key); V oldValue = bucket[hashValue(key)].add(key, value); if (oldValue == null) // new entry n++; return oldValue; } /** * Cancella l'entry con chiave k. * @param key la chiave da cancellare. * @return il valore della chiave cancellata * @throws InvalidKeyException **/ public V remove (K key) throws InvalidKeyException { ...................... } }
Per esempio se nel tester ho una cosa simile:codice:public class Node<K,V> implements Entry<K,V> { private K key; private V value; private Node<K,V> next; /** Costruttore. */ public Node(K k, V v, Node<K,V> n) { key = k; value = v; next = n; } public K getKey() { return key; } public V getValue() { return value; } public Node<K,V> getNext() { return next; } public V setValue(V val) { V oldValue = value; value = val; return oldValue; } public void setNext(Node<K,V> newNext) { next = newNext; } }
il programma si arresta non appena tenta di invocare il metodo put.codice:SeparateChainingHashTable<Integer, String> h = new SeparateChainingHashTable<Integer, String>(); h.put(012345, "John");
Sapete dirmi dove sbaglio?

Rispondi quotando