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:
codice:
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 {
......................
	}
}
e questa è la classe Nodo
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;
	}
}
Per esempio se nel tester ho una cosa simile:
codice:
SeparateChainingHashTable<Integer, String> h = new SeparateChainingHashTable<Integer, String>();
		h.put(012345, "John");
il programma si arresta non appena tenta di invocare il metodo put.
Sapete dirmi dove sbaglio?