Introduction
Hello,
I'm working on a java application that makes use of several bidirectional hash-maps and observable lists. My code works but I've come across a bizarre quirk that I can't seem to get rid of. I can't find any information on this online so I thought I'd share it and see if anyone else has ever seen this before.
When the code first opens, there is a method that makes a query to a MySQL database and pulls the names of a list of authors (the program is a library database application) whose names are broken up into separate parts; First Name, Middle Name and Last Name. This method then goes through the cached row set and combines them together then adding them to the bidirectional hash-map and the observable list I mentioned before. These are then used throughout the code for a variety of purposes.
The issue occurs anytime the lists are refreshed after the initial creation. From time to time while the program is running, new queries are made to the database and the list is refreshed to ensure that the most up to date information is available. The first time the method is run, it does all of these steps I mentioned and takes around 8 milliseconds to complete. But when the refreshes are made, that time jumps to around 1,400 milliseconds. Notably, the time gets longer the more refreshes are made. Obviously this is a major spike in time but there's nothing in the code that I can see to indicate what is causing this. I'll explain how I determined that it was the observable list below...
I've linked a picture below to show an example of what I'm talking about.
Notice that the number of authors being processed are the same. The other printouts were additonal information that I was testing for at the same time and isn't relevant to this post.
This is the code for the method.
public void createAuthorHashMap() throws Exception { String authorFirstName, authorMiddleName, authorLastName, authorFullName; int ID;
// Get the Cached Row Set for all Authors in the database
CachedRowSet authorList = connectionCommands.readDatabase(sqlCommands.selectAllAuthor);
// Reset the contents of the hashmap and observable list
bookAttributes.bidiMapAuthors.clear();
bookAttributes.listAuthors.clear();
choiceBoxAuthor.setItems(null);
// Combine the sperate parts of the names from the cached rowset
while (authorList.next()) {
ID = authorList.getInt(1);
authorFirstName = authorList.getString(2);
authorMiddleName = authorList.getString(3);
authorLastName = authorList.getString(4);
if (authorMiddleName == null) {
authorFullName = (authorFirstName + " " + authorLastName);
} else {
authorFullName = (authorFirstName + " " + authorMiddleName + " " + authorLastName);
}
// Add the authors to the hashmap and list
bookAttributes.bidiMapAuthors.put(ID, authorFullName);
bookAttributes.authors.add(authorFullName);
}
// Add the list to the choiceBox and auto-complete textfield
choiceBoxAuthor.setItems(bookAttributes.authors);
TextFields.bindAutoCompletion(textFieldAuthor, bookAttributes.listAuthors);
}
And this is the code for the hashmaps and Observable lists.
// Lists
public static ObservableList<String> FictionGenres = FXCollections.observableArrayList();
public static ObservableList<String> NonFictionGenres = FXCollections.observableArrayList();
public static ObservableList<String> blankList=FXCollections.observableArrayList();
public static ObservableList<String> authors = FXCollections.observableArrayList();
public static ObservableList<String> publishers = FXCollections.observableArrayList();
public static ObservableList<String> languages = FXCollections.observableArrayList();
public static ObservableList<String> series = FXCollections.observableArrayList();
// Hashmaps
public static BidiMap<Integer, String> bidiMapAuthors = new TreeBidiMap<>();
public static BidiMap<Integer, String> bidiMapPublishers = new TreeBidiMap<>();
public static BidiMap<Integer, String> bidiMapFictionGenres = new TreeBidiMap<>();
public static BidiMap<Integer, String> bidiMapNonFictionGenres = new TreeBidiMap<>();
public static BidiMap<Integer, String> bidiMapLanguages = new TreeBidiMap<>();
public static BidiMap<Integer, String> bidiMapSeries = new TreeBidiMap<>();
An important note is that the hashmaps and lists are created and stored in a separate class so that they can be accessed across multiple controllers during the program's runtime.
The code itself isn't complicated and is reasonably easy to follow but the part I'd like to draw your attention to are the two lines following the while loop. These are the two lines that add the author's name to the hash-map and list.
bookAttributes.bidiMapAuthors.put(ID, authorFullName);
bookAttributes.authors.add(authorFullName);
Testing
My testing went as such. I put timers around separate sections of the method and ran it multiple times and narrowed the cause of the slow-down to the two lines of code I mentioned before. It should be noted that the timings I got for every other part of the method were exactly what I expected them to be.
I then commented out the line that adds the names to the hash-map and the issue persisted but once I reversed it and commented out the line that adds the names to the list then the issue instantly disappeared and never came back regardless of the number of times I ran the method.
bookAttributes.authors.add(authorFullName);
Would there be any cause for what is going on here or is there an obvious mistake that I overlooked and I'm just an idiot? I'm very curious and I appreciate any information!