使用 <ArrayList> 数据填充 TreeMap<String, ArrayList(of different lengths) >

Populating TreeMap<String, ArrayList(of different lengths) > with <ArrayList> data

我的函数接受一个 Scanner 和 returns 一个 TreeMap map,其中字符串作为键,ArrayList 作为值。这些 ArrayList 可以有不同的长度。我已将 Scanner 解析为新的 ArrayList textData 以便于迭代。程序应该如下:

  1. 如果元素是字符串,则将其作为下一个 TreeMap 条目的新键(存储为 String state)并清除临时数组
  2. 如果元素可解析为 Double,则将其添加到临时 ArrayList statePopData
  3. 承诺 map

理想情况下,使用扫描仪:

"Utah\t6.0\t60\n" + "California\t5\t30\n" + "Nevada\t3"

应该return:

{"Utah",[6.0, 60.0], "California",[5.0, 30.0], "Nevada",[3.0],}

这是我目前的情况:

 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;}

我对这些片段很有信心,但我似乎永远无法在正确的时间 运行 map.put() 语句提交正确的值。比如我现在程序的结果是:{California=[3.0], Nevada=[3.0], Utah=[3.0]}

编辑:链接的答案不涉及任何实现,也没有完全回答我正在尝试做的事情。

看起来像
的重复代码 为每个状态修改和设置相同的 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;

状态后跟多个数字的更新解决方案:

// 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;
}