Null pointer exception error in different areas of anagramManager program

I am receiving an nullpointer Exception in a couple of different places in my code. I am sure I have forgotten an exception somewhere but I need some assistance in pointing it out. I have 3 files to go with the entire program. I am creating an anagramManager based on the main file given.

Here is the first class Word

import java.util.*;

public class Word implements Comparable<Word>
{
   private String word;
   private String canonical;

   public Word(String word)
   {
      String lowerCase = word.toLowerCase();
      word = lowerCase;
      canonical = CanonicalForm(word);
   }

   public String getWord()
   {
      return word;
   }

   public String getForm()
   {
      return canonical;
   }

   public String toString()
   {
      return "[" + word + "=" + canonical + "]";
   }

   public int compareTo(Word someWord)
   {
      return getForm().compareTo(someWord.getForm());
   }

   private static String CanonicalForm(String word)
   {
      if(word == null || word.length() < 1) 
      {
         throw new IllegalArgumentException();
      }

      char arr[] = word.toCharArray();
      Arrays.sort(arr);
      return new String(arr);
   }
}

Here is the anagramManager which handles most of the work on the main folder.

import java.util.*;

public class AnagramManager
{
   private Word[] words;
   private Random rand;
   private Map<String,Set<String>> theMap;

   public AnagramManager(List<String> list)
   {
      if (list == null || list.size() < 1)
      {
         throw new IllegalArgumentException();
      }

      rand = new Random();
      words = new Word[list.size()];
      theMap = new TreeMap<String,Set<String>>();

      makeWords(list);
      makeAnagrams();
   }

   public void sortByWord()
   {
      for (Word i : words)
      {
         i.getWord();
      }
      Arrays.sort(words);
   }

   public void sortByForm()
   {
      for(Word c : words)
      {
         c.getForm();
      }
      Arrays.sort(words);
   }

   public String getAnagram(String word)
   {
      String canonWord = CanonicalForm(word);
      if(theMap.containsKey(canonWord))
      {
         Set<String> anagramSet = theMap.get(canonWord);
         String[] match = anagramSet.toArray(new String[anagramSet.size()]);
         return match[rand.nextInt(match.length)];
      }
      else
      {
         return "";
      }
   }

   public Set<String> getAnagrams(String word)
   {
      String canonWord = CanonicalForm(word);
      boolean hasAnagram = theMap.containsKey(canonWord);

      Set<String> anagrams = (hasAnagram) ? theMap.get(canonWord) : new TreeSet<String>();


      return anagrams;
   }


   public String toString()
   {
      String printWords = "";
      int length = words.length;

      if (length < 1)
      {
         printWords += "[]";
      }
      else
      {

         for (int i=0; i < length; i++)
         {
            printWords += words[i];
         }

         printWords += "[...]";

         for(int i = length - 5; i < length; i++)
         {
            printWords += words[i];
         }
      }
      return printWords;
   }         

   private static String CanonicalForm(String word)
   {
      if(word == null || word.length() < 1)
      {
         throw new IllegalArgumentException();
      }

      char arr[] = word.toCharArray();
      Arrays.sort(arr);
      return new String(arr);
   }

   private void makeWords(List<String> list)
   {
      int ind = 0;

      for (String orgWord : list)
      {
         words[ind] = new Word(orgWord);
         ind++;
      }
   }

   private void makeAnagrams()
   {
      for(Word i : words)
      {
         String canon = i.getForm();
         String org = i.getWord();

         if(!theMap.containsKey(canon))
         {
            Set<String> set = new TreeSet<String>();
            set.add(org);
            theMap.put(canon,set);
         }
         else
         {
            theMap.get(canon).add(org);
         }
      }
   }
}

This is the main program. This shouldn't be modified at all.

import java.util.*;
import java.io.*;

public class AnagramMain {
    public static final String DICTIONARY_FILE = "dictionary.txt";

    public static void main(String[] args) throws FileNotFoundException {
        System.out.println("Welcome to the CS145 Anagram Practice");
        System.out.println();

        // open the dictionary file and read dictionary into an ArrayList
        Scanner input = new Scanner(new File(DICTIONARY_FILE));
      Scanner keyboard = new Scanner(System.in);
        List<String> dictionary = new ArrayList<String>();
        while (input.hasNext()) {
            dictionary.add(input.next().toLowerCase());
        }

        // set up the AnagramManager
        List<String> dictionary2 = Collections.unmodifiableList(dictionary);
        AnagramManager catalog = new AnagramManager(dictionary2);

      // Start the program asking for run style
      System.out.println("Press enter to start, or any other input for debug mode");
      String DEBUG = keyboard.nextLine();

      // If in DEBUG mode
      if (!DEBUG.equals("") )
      {
        System.out.println("** The first and last five sorted by word elements are **");
        catalog.sortByWord();
        System.out.println(catalog);
        System.out.println("** The first and last five sorted by form elements are **");
        catalog.sortByForm();
        System.out.println(catalog);
        System.out.println("\n\n\n");
      }

      // Start the Loop
      getAnagram(keyboard, catalog);

    }

    // Executes the primary anagram loop
    public static void getAnagram(Scanner console, AnagramManager theCatalog) 
   {
      String input;
      System.out.println("Please type in a word to anagram or QUIT to quit :");
      input = console.nextLine();

      while (!input.toUpperCase().equals("QUIT") && !input.equals("") ) 
      {
        String result = theCatalog.getAnagram(input);
        if (!result.equals("") )
        {
         System.out.print("One possible anagram of your word " + input );
         System.out.println(" is " +result);
        }
        else
        {
          System.out.println("Your word was not found in the list");
        }

        System.out.print("In fact the list of anagrams for your word are : ");
        System.out.println(theCatalog.getAnagrams(input));

        System.out.println("Please type in a word to anagram or QUIT to quit :");
        input = console.nextLine();
      }
    }
}

The exception looks like this:

Exception in thread "main" java.lang.NullPointerException
    at java.util.TreeMap.compare(TreeMap.java:1294)
    at java.util.TreeMap.put(TreeMap.java:538)
    at java.util.TreeSet.add(TreeSet.java:255)
    at AnagramManager.makeAnagrams(AnagramManager.java:129)
    at AnagramManager.<init>(AnagramManager.java:21)
    at AnagramMain.main(AnagramMain.java:28)

1 answer

  • answered 2018-05-16 06:08 Joachim Sauer

    You've got an error in your constructor of Word:

    public Word(String word) { String lowerCase = word.toLowerCase(); word = lowerCase; canonical = CanonicalForm(word); }

    The second line you re-assign the newly lower-cased value to the parameter word, but I suspect you wanted to assign it to the field with the same name, change that line to this:

    this.word = lowerCase;