My function takes in a Scanner and returns a TreeMap map
with Strings as keys, and an ArrayList as a value. These ArrayLists can be of different lengths. I've parsed the Scanner to a new ArrayList textData
for easier iteration. The procedure should go as follows:
String state
) and clear the temporary arraystatePopData
.map
.Ideally, with the scanner :
"Utah\t6.0\t60\n"
+ "California\t5\t30\n"
+ "Nevada\t3"
should return:
{"Utah",[6.0, 60.0], "California",[5.0, 30.0], "Nevada",[3.0],}
Here is what I have thus far:
public static TreeMap<String, ArrayList<Double>> readTable (Scanner dataSource)
{
//Parse Scanner to ArrayList
ArrayList<String> textData = new ArrayList<String>();
while(dataSource.hasNext()){
textData.add(dataSource.next());
}
//Populate TreeMap
ArrayList<Double> statePopData = new ArrayList<>();
TreeMap<String, ArrayList<Double>> map = new TreeMap<>();
for (int i = 0; i < textData.size(); i++) {
boolean isDouble;
String state = "";
try {
Double.parseDouble(textData.get(i));
isDouble = true;
} catch (NumberFormatException | NullPointerException nfe) {
isDouble = false;
}
if(isDouble) {
statePopData.add(Double.parseDouble(textData.get(i)));
} else { //means its a string
statePopData.clear();
state = textData.get(i);
}
if (statePopData.isEmpty()) {
map.put(state, statePopData);
}
} return map;}
I feel confident with the pieces, but I can never seem to run the map.put()
statement at the right time with the proper values to commit. For example, my current results of the program are: {California=[3.0], Nevada=[3.0], Utah=[3.0]}
EDIT: The linked answer doesn't involve any implementation nor fully answers what I'm trying to do.
Looks like duplicate code to Failed test case, what am I doing wrong?
The same ArrayList
instance is being modified and set for each state, so it is being cleared and overwritten each time. A simpler approach may be:
TreeMap<String, ArrayList<Double>> map = new TreeMap<>();
while (dataSource.hasNext()) {
String state = dataSource.next();
Double d = Double.parseDouble(dataSource.next());
map.computeIfAbsent(state, k -> new ArrayList<>()).add(d);
}
return map;
Updated solution for state followed by multiple numbers:
// Usually better to use List than ArrayList for declared generic types
public static TreeMap<String, List<Double>> readTable(Scanner dataSource) {
TreeMap<String, List<Double>> map = new TreeMap<>();
String state = null;
while (dataSource.hasNext()) {
String next = dataSource.next(); // Should never be null
try {
Double d = Double.parseDouble(next);
// Ignores numbers received before state is set
if (state != null)
// If state has been set, list that must have been initialized
map.get(state).add(d);
} catch (NumberFormatException e) {
// Assumes any non-double is a state
state = next;
// Initialize map entry with empty list
map.put(state, new ArrayList<>());
}
}
return map;
}