Заполнение TreeMapс данными <ArrayList> - PullRequest
1 голос
/ 02 октября 2019

Моя функция принимает сканер и возвращает TreeMap map со строками в качестве ключей и ArrayList в качестве значения. Эти ArrayLists могут быть разной длины. Я проанализировал сканер для нового 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 Ответ

1 голос
/ 02 октября 2019

Похоже, дубликат кода Неудачный тестовый пример, что я делаю не так?
Один и тот же экземпляр 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;
}
...