Reputation: 71
I have a Java assignment where we are to program a "database" of books and journals using the ArrayList class to store them as objects of type Reference.
One of the requirements from this assignment is that we split the titles of the books in the database and save them into a HashMap to allow for keyword searching later.
My hashmap is declared like this:
private HashMap <String, Reference> titles = new HashMap <String,Reference> (10);
I know through testing that the way I add titles and References to the HashMap works. What does not work is my search function.
private void searchBooks(String callNumber, String[] keywords, int startYear, int endYear) {
Set<String>commonKeys = new HashSet<String>();
for(int i = 0; i < keywords.length; i ++)
{
commonKeys.add(keywords[i]);
}
titles.keySet().retainAll(commonKeys);
System.out.println(titles);
This is code I've pieced together based off of my knowledge, and similar problems I've been able to find on this sites various threads.
Am I approaching this right? Is there something I'm missing?
Upvotes: 2
Views: 1813
Reputation: 4313
Your search function is also permanently damaging your "titles" hashMap. A search function should only look at your map, but it is also altering it. Note how, after every search, you wiped out all the entries that didn't match. Your next search won't find those, maybe this is the reason. If you are adding a new entry after searching, this would explain perfectly why only one entry is being found - all the others were wiped out in the previous search.
Upvotes: 1
Reputation: 111
Let's say you have two books. One is titled "Book One" and the other is titled "Book Two". If I understand your question correctly, you are populating the titles map with something like the below.
for each title
split on " " character
titles.put(title word, reference to the book)
If I got that right, the problem isn't with your searching code, but rather the data structure of the titles object itself. If we run the example above through the pseudocode I wrote above, what does the map look like at the end?
Book -> Book Two
One -> Book One
Two -> Book Two
Now, if you search for "Book" you will get the behavior described.
How do you solve this? You need something more than a simple map. One option is a map of lists, in your case
Map<String, List<Reference>>
You would populate this nearly the same way you already are, but instead of
titles.put(title word, reference to the book)
You would do:
if (titles.containsKey(title word)) {
titles.get(title word).add(reference to the book);
} else {
titles.put(new List<Reference>() { reference to the book };
}
Another option would be the Multimap class from the GS Collections library, but the code above is a simple starting point.
Upvotes: 2