This is my code:
I've identified the line with the problem and I know exactly why, and this is what I did.
I took this line
and made it several lines and printed their values:
The problem is now this line
According to the Java API, https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html#get-java.lang.Object-
Class HashMap wrote:get
public V get(Object key)
Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
More formally, if this map contains a mapping from a key k to a value v such that (key==null ? k==null : key.equals(k)), then this method returns v; otherwise it returns null. (There can be at most one such mapping.)
A return value of null does not necessarily indicate that the map contains no mapping for the key; it's also possible that the map explicitly maps the key to null. The containsKey operation may be used to distinguish these two cases.
The key value is not an int, but it is an object and in this case it is a String.
As a result your random int or any int will not work for you.
You cannot retrieve a value from a HashMap using an index like you would an array or ArrayList.
I'm not too sure how one goes about getting a random key from a HashMap.
However I suspect that people have asked that question before or something similar.
Current program looks messy enough already. I'd stop adding new features or fixing anything.
Instead - would clean it up by decomposing all that code into small methods, so one could at least follow it.
I don't see a lot benefit in doing it clearly in a wrong way. I think even complete starter can be taught to write programs in more organized, structured way.
All such comments needs to be pointed out - are usless and should not be written that way anymore.
Is it assignment?
Unfortunately, that will lose you marks.
Daniel Stallard wrote:. . . Yes, it is an assignment I'm sorry that my code is messy. . . .
I suggest you start by reading about Maps in the Java™ Tutorials. In the first instance try populating the Map by hand. Then consider populating it from the file, but that is a different task, and should be done separately. I think you will find it much easier to write good code if you divide the assignment into smaller parts.
Daniel Stallard wrote:I'm sorry that my code is messy.
That is bad for you, not for me, so no worries
Daniel Stallard wrote:I'm no very familiar with using maps and it seems pretty complicated to get a random key.
It isn't about the map. It is about the environment where you fiddling with those maps. Everything around is messy.
As a real life example, imagine for a moment surgeon's scalpel, in your case it is a Map, but have you ever had a chance to see how the things are organised in a surgery room?
 Everything have their precise place
 All the time they are in the same place
 There are no unnecessary things
That is all about that.
Now think if everything would be like in a flea market, I think you wouldn't like even to think about the idea in having any kind of business with such surgery room.
Program's organisation and slight pedanticism isn't something you need to study for years in order to learn. I think this is something you can pick up right away and help yourself a lot.
All the comments you wrote - they add extra noise and disturb you from seeing actual code.
Example of useless comment you wrote:
As you see it adds absolutely no extra information to what actual code line tells you. So why to add it?
However, in your code there is only one comment which in my opinion is quite useful:
What it tells me as a reader, that it is your intention to do nothing after you catch the exception at line 67. If such comment wasn't there, I'd think you might forgot to add handling part. As an improvement of this comment you could write why there is an empty handling part.
So, only by removing all useless comments, your program would look way better. That's one.
Second. Variable names.
As you see, you trade in clarity for saving the keystroke - that's a bad idea. you should pay attention to clarity, always. Imagine you have a big project and you are discussing with your fellow colleague about the code snippet where state capitals are handled. So you ask him to have a look. How one could know how to find that part? In IDE's there are tools to look up for text match within a project, and if you were name it stateCapital or other sensible name which you use in spoken language with your fellow colleague, that would be very easy for him/her to find it. You don't tell him about the code, look, there is a problem with sta cap map. What?!? I mean there is a problem with state capital... Oh, this is what you mean... So why not to use clear, unambiguous names?
One of your methods is 50 lines long. I have in mind readText(). You could break it down slightly, so you'd have 2 or 3 methods out of this 1. The good part about breaking down problem into smaller problems is, that if you know that there is a problem in adding capitals to some kind of data structure, you are worrying only about the method (small), which is responsible for that, rather than searching through all 50 lines and thinking if there are no overlapping logic or similar. Deal with small things is always easier than with bigger. Unless you are aiming with a bow at target
I'm not forcing or giving you a pressure, but just think it through, you might will find some ideas useful.