使用<ArrayList>数据填充TreeMap <String,ArrayList(不同长度)>

时间:2019-10-01 22:22:41

标签: java arraylist treemap

我的函数接收一个Scanner并返回一个TreeMap map,其中Strings作为键,而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"

应返回:

{"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]}

编辑:链接的答案不涉及任何实现,也不完全回答我想做的事情。

1 个答案:

答案 0 :(得分:1)

就像Failed test case, what am I doing wrong?的重复代码一样
正在为每个状态修改和设置相同的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;
}