我一直在努力使它起作用,但是我不确定我要去哪里出错。稍微用一下测试用例就可以了。关于我在做什么的一些事情。该列表必须包含一个或多个行。如果没有至少一行,则抛出IllegalArgumentException。每行都有某种字符串,然后是一个制表符,然后是一个双精度字,然后是一个换行符。如果任何行不遵循此模式,则也会抛出IllegalArgumentException。理想情况下,如果您创建了任意数量的列表,此方法都应该起作用,所以这就是为什么我这样尝试过
基本上,该程序应该获得一个列表,例如...
California 6
Nevada 11
California 1
California 14
Arizona 21
Utah 2
California 7
Utah 10
Nevada 3
Utah 2
,并应返回如下内容:
California {6, 1, 14, 7}
Arizona {21}
Utah {2, 10, 2}
Nevada {11, 3}
请注意,在本示例中,我仅使用了四个。我正在尝试使其能够与任意数量的列表一起使用。 这是我的代码...
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;
}
对于列表中所有其他状态,我一直在为所有值获取相同的值,而对于为什么会发生这种情况我感到困惑。
这是我之前提到的测试用例...
@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);
}
}
我是一名新程序员,因此任何建议将不胜感激!我很想知道自己在做什么错,以便我可以学习更多。 :)
答案 0 :(得分:1)
我认为主要问题是您正在为每个州修改并插入相同的ArrayList
实例。没有健壮性检查的简单版本可能是:
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;
computeIfAbsent
允许您在看到新状态(Java 8+)时添加新的ArrayList
。
另一个问题是assertEquals
。由于期望号码列表数据的顺序与实际顺序不同,因此ArrayLists
不相等。您可以像这样验证键和值:
assertEquals(expected.keySet(), actual.keySet());
expected.forEach((state, list) -> {
Collections.sort(list);
Collections.sort(actual.get(state));
assertEquals(list, actual.get(state));
});
答案 1 :(得分:0)
您的代码每次有新字符串时都会清除statePopData,所以即使您看到:
California 1
California 2
California 3
您只会看到一张显示加利福尼亚的地图:3,因为map.put()将用您提供的任何内容替换键“加利福尼亚”的当前值。
每次看到状态时,您都需要调出该状态数组的当前版本,然后在重新插入该状态之前将新数据附加到该数组中。