Raw Types
Okay, your first problem here is that you use a raw LinkedHashMap
, raw Iterator
, and raw Map.Entry
. This will lead to all sorts runtime errors, especially in your code. If you had started by typing everything with the <>
, the compiler would have given you errors that would help you solve a couple problems.
First, let's change that LinkedHashMap
to be typed:
public LinkedHashMap<String, Boolean> generateTab() {
LinkedHashMap<String, Boolean> selectedTabs = new LinkedHashMap<String, Boolean>();
selectedTabs.put("People", true);
selectedTabs.put("Property", true);
selectedTabs.put("Info", false);
selectedTabs.put("Fixture", true);
selectedTabs.put("Fee", true);
selectedTabs.put("Process", true);
return selectedTabs;
}
Next, we'll add it to the Iterator
. From your code, it's clear that you're expecting a Map.Entry
from the Iterator
, so let's start with that.
Iterator<Map.Entry> iterator = tabList.keySet().iterator();
When you enter this into your code, you're going to get an error:
Type mismatch: cannot convert from Iterator<String>
to Iterator<Map.Entry>
This means that your iterator is not typed on Map.Entry
like you thought it was. This is because keySet
returns a Set<K>
from the LinkedHashMap
, not Set<Entry<K, V>>
like you thought. What you want is tabList.entrySet().iterator()
. However, if you enter this, it will tell you:
Type mismatch: cannot convert from Iterator<Map.Entry<String,Boolean>>
to Iterator<Map.Entry>
So we have to add the <String, Boolean>
to the Map.Entry
as well:
Iterator<Map.Entry<String, Boolean>> iterator = tabList.entrySet().iterator();
A couple other little things. Now that we've changed this, we can a) replace your getKey().toString()
call with just getKey()
(since it's a string now) and b) replace your tabList.get(entry.getKey()).equals(true)
with just entry.getValue()
(since it's a boolean now).
There, now that we've sorted that out, your code will look like this (before addressing your problem):
public LinkedHashMap<String, Boolean> generateTab() {
LinkedHashMap<String, Boolean> selectedTabs = new LinkedHashMap<String, Boolean>();
selectedTabs.put("People", true);
selectedTabs.put("Property", true);
selectedTabs.put("Info", false);
selectedTabs.put("Fixture", true);
selectedTabs.put("Fee", true);
selectedTabs.put("Process", true);
return selectedTabs;
}
public String getNextTab(String currentTab) {
String nextTab = null;
Map<String, Boolean> tabList = generateTab();
Iterator<Map.Entry<String, Boolean>> iterator = tabList.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, Boolean> entry = iterator.next();
if (entry.getKey().equals(currentTab)) {
if (entry.getValue()) {
nextTab = entry.getKey();
break;
}
}
}
return nextTab;
}
Getting the Next Tab
So if I understand correctly, you want to find the current tab, then return the tab after that in the map, correct?
Edit: I see now, you want the next one whose hide/show value is true
.
To do this, you already have the iterator, so you can just use that. If you're on the current tab:
- Check if there's something left in the iterator
- If there is, get the next value in the iterator (the next tab, as it were)
- If there isn't, refresh the iterator get the first value (we've reached the end, so loop back around to the beginning)
- Is it visible? If so, return it, otherwise, continue.
This will return the first tab that is visible after the currently selected one. If the tab only visible tab is the one that's selected, this will return that tab again. Be careful about calling this if no tabs are visible. Make sure this won't happen since it will create an infinite loop if all tabs are hidden.
This would change your loop to look like this:
while (iterator.hasNext()) {
Map.Entry<String, Boolean> entry = iterator.next();
if (entry.getKey().equals(currentTab)) {
if (entry.getValue()) {
while (true) {
if (iterator.hasNext()) {
entry = iterator.next();
} else {
// Get a fresh iterator and get its first element
iterator = tabList.iterator();
entry = iterator.next();
}
if (entry.getValue()) {
return entry.getKey();
}
}
}
}
}
And there you go! Note that I had to use return
instead of break
, since breaking out of two loops requires either a) a boolean
variable to make the first loop exit after the second one exits, or b) a label for the break
statement to break to, neither of which are good options, really.