问题
I've been trying to get this to work, but I'm not quite sure where I'm going wrong. It'll make sense with the test case in a bit. Some things about what I'm doing. The list must have one or more lines. If there's not at least one line, an IllegalArgumentException is thrown. Each line has some kind of String, then a tab character, then a double, then a newline. If any lines don't follow this pattern, then an IllegalArgumentException would also be thrown. This is ideally supposed to work if you made any number of lists, so that's why I attempted it this way
Basically, the program is supposed to get a list, say something like...
California 6
Nevada 11
California 1
California 14
Arizona 21
Utah 2
California 7
Utah 10
Nevada 3
Utah 2
and should return something like this:
California {6, 1, 14, 7}
Arizona {21}
Utah {2, 10, 2}
Nevada {11, 3}
Note that I only used four for the sake of the example. I'm trying to get it so that it's work with any number of lists. Here is my code...
public static TreeMap<String, ArrayList<Double>> readTable (Scanner dataSource)
{
ArrayList<String> dataFromFile = new ArrayList<String>();
while(dataSource.hasNext()){
dataFromFile.add(dataSource.next());
}
//Populate TreeMap
ArrayList<Double> statePopData = new ArrayList<>();
TreeMap<String, ArrayList<Double>> map = new TreeMap<>();
for (int i = 0; i < dataFromFile.size(); i++) {
boolean isDouble;
String state = "";
try {
Double.parseDouble(dataFromFile.get(i));
isDouble = true;
} catch (NumberFormatException | NullPointerException nfe) {
isDouble = false;
}
if(isDouble) {
statePopData.add(Double.parseDouble(dataFromFile.get(i)));
} else { //means its a string
statePopData.clear();
state = dataFromFile.get(i);
}
if (statePopData.isEmpty()) {
map.put(state, statePopData);
}
} return map;
}
I keep getting one same value for everything for all the other states in the list and I'm confused as to why this is happening.
Here's the test case I mentioned before...
@Test
public void testReadTable ()
{
try (Scanner scn = new Scanner(
"Utah\t10\nNevada\t3\nUtah\t2\nCalifornia\t14\nArizona\t21\nUtah\t2\nCalifornia\t7\nCalifornia\t6\nNevada\t11\nCalifornia\t1\n"))
{
TreeMap<String, ArrayList<Double>> actual = GraphingMethods.readTable(scn);
TreeMap<String, ArrayList<Double>> expected = new TreeMap<>();
ArrayList<Double> azList = new ArrayList<>();
azList.add(21.0);
expected.put("Arizona", azList);
ArrayList<Double> caList = new ArrayList<>();
caList.add(6.0);
caList.add(1.0);
caList.add(14.0);
caList.add(7.0);
expected.put("California", caList);
ArrayList<Double> nvList = new ArrayList<>();
nvList.add(11.0);
nvList.add(3.0);
expected.put("Nevada", nvList);
ArrayList<Double> utList = new ArrayList<>();
utList.add(2.0);
utList.add(10.0);
utList.add(2.0);
expected.put("Utah", utList);
assertEquals(expected, actual);
}
}
I'm a new programmer, so any advice would be greatly appreciated! I'd love to know what I'm doing wrong so that I can learn more. :)
回答1:
I think the main problem is you are modifying and inserting the same ArrayList instance for each state. A simple version, without robustness checking might 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;
The computeIfAbsent allows you to add a new ArrayList when you see a new state (Java 8+).
Another issue is the assertEquals. Since the expected number list data is in a different order than the actual, the ArrayLists are not equal. You could verify the keys and values like this:
assertEquals(expected.keySet(), actual.keySet());
expected.forEach((state, list) -> {
Collections.sort(list);
Collections.sort(actual.get(state));
assertEquals(list, actual.get(state));
});
回答2:
Your code clears statePopData every time there is a new string, so even if you see:
California 1
California 2
California 3
You will only wind up with a map that says California: 3, as map.put() will replace the current value for the key "California" with whatever you provide it.
You need to recall the current version of the state's array each time you see that state, and then append the new data to the array before you re-insert that .
来源:https://stackoverflow.com/questions/58195283/failed-test-case-what-am-i-doing-wrong