0

I am creating a program in which I read the 50 states and their capitals from a .txt file. I then run a while loop and store each of the states in an ArrayList and each of the capitals in another ArrayList. I convert those two ArrayList's to regular arrays, and then run a for loop to store each state as a key in a map, and each capital as a value in the map. My issue is that when I use the map.get() method to return the capital of a particular state it simply returns "null" and I am not sure why that would be the case. Here is my code:

import java.util.*;
import java.io.File;
import java.io.FileNotFoundException;



public class ChapterOneBasics {
    public static void main(String[] args) throws FileNotFoundException {
        Map<String, String> usCapitals = new HashMap<String, String>();
        ArrayList<String> aList = new ArrayList<>();
        ArrayList<String> bList = new ArrayList<>();
        int x = 0;
        File file = new File("C:\\Private\\Private\\Private\\capitals.txt");
        Scanner sc = new Scanner(file);
        while(sc.hasNextLine()) {
           if(x % 2 == 0) {
                aList.add(sc.nextLine());
           }
           else
                bList.add(sc.nextLine());
           x++;

}
              String[] usStates = aList.toArray(new String[aList.size()]);
              String[] uSCapitals = bList.toArray(new String[bList.size()]);
              for(int y = 0; y < uSCapitals.length; y++) {
                 usCapitals.put(usStates[y], uSCapitals[y]);

      }
               System.out.println(usCapitals.get("Montana"));
  }
}

As you can see, I have stored each state to the Map in string format, but whenever I call a state to look up a capital city I get this as the output:

null

I am not sure what the issue is.

8
  • 3
    print the key and value of the map after inserting everything and see if the key is present in map or not Commented Jul 18, 2018 at 11:29
  • 4
    Use your debugger, or just add println() in the code, to see what your map actually contains. Commented Jul 18, 2018 at 11:30
  • 1
    I would remove half the code e.g. the Lists and the arrays, but if you want to know where the issue is, a debugger to see what it is you are loading should help. Commented Jul 18, 2018 at 11:30
  • 1
    be careful to hiding space, use .trim() maybe when put Commented Jul 18, 2018 at 11:33
  • 2
    Your keys need to match exactly. They need to be in same case, any trailing whitespace will be considered, etc. Commented Jul 18, 2018 at 11:36

2 Answers 2

1

Your problem is in the for loop where you want to put in the map your states and capitals:

 usCapitals.put(usStates[y], uSCapitals[y]);

You have two options:

  1. either you change the way to try to get your values from the map, instead of doing get("Montana"), you search for state as the key get("MT")

  2. If you want to do get("Montana"), then you want to flip the order of the key and value in order for that to be possible.

Then you change the map into this:

 usCapitals.put(uSCapitals[y], usStates[y]);
Sign up to request clarification or add additional context in comments.

2 Comments

@SimeonIkudabo, glad I could help.
The "answer" seems absolutely nonsense, given that we do not have any information about the naming of your states in the file capitals.txt and there is no mentioning of the acronyms being included therein. The flipping of key and value does not make any sense either. If you want the capital of Montana, it would be wrong to have the capital as the key and the state as the value.
1

The mentioned trimming of whitespace should be done. Then the result would be:

    Map<String, String> usCapitals = new HashMap<>();
    Path file = Paths.get("C:\\Private\\Private\\Private\\capitals.txt");
    List<String> lines = Files.readAllLines(path, Charset.defaultCharset());
    for (int i = 0; i < lines.size() - 1; i += 2) {
        String state = lines.get(i).trim();
        String capital = lines.get(i + 1).trim();
        usCapitals.put(state, capital);
    }

If usCapitals.get(state) returns null, that could be due to misspelling or uppercase/lowercase. A fuzzy match would be nice.

public String getCapital(String state) {
    state = state.trim();
    String capital = usCapitals.get(state);
    if (capital == null) {
        Map.Entry<String, String> bestEntry = null;
        int bestScore = 0;
        for (Map.Entry<String, String> e : usCapitals.entrySet()) {
            int score = match(state, e.getKey());
            if (bestEntry == null | score >= bestScore) {
                bestEntry = e;
                bestScore = score;
            }
        }
        capital = bestEntry.getValue();
        Logger.getLogger(getClass().getName()).warning("State not found: " + state 
                + "; best match: " + bestEntry.getKey() + " with capital " + capital);
    }
    return capital;
}

private static int match(String s, String t) {
    if (s.isEmpty() || t.isEmpty()) {
        return 0;
    }
    char sch = s.charAt(0);
    char tch = t.charAt(0);
    if (Character.toUpperCase(sch) == Character.toUpperCase(tch)) {
        return 1 + match(s.substring(1), t.substring(1));
    }
    int ms = match(s, t.substring(1));
    int mt = match(s.substring(1), t);
    return Math.max(ms, mt);
}

1 Comment

Thanks a lot! I see what you mean in terms of trimming the whitespace and why that could be an issue here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.