I have been struggling all day with this seemlesly unimportant issue, but I need to get it sorted. I will post all my code and explain it. I need to parse a CSV into a HashMap with structure {key, value} where value is an ArrayList of ArrayLists of Strings.
HashMap<String, ArrayList<ArrayList<String>>>
In the back, using AsyncTask, I get the data correctly into the map using a CSV document where I have the information stored. Here is my AsyncTask, just in case, but I can 99% say it works just fine.
public class ReadAllPaths extends AsyncTask<Integer, Double, HashMap<String, ArrayList<ArrayList<String>>>> {
public interface AsyncResponse {
void processFinish(HashMap<String, ArrayList<ArrayList<String>>> output);
}
public static final String TAG = "ReadAllPaths";
public AsyncResponse delegate;
@SuppressLint("StaticFieldLeak")
private final Context context;
public ReadAllPaths(Context context, AsyncResponse delegate) {
this.context = context;
this.delegate = delegate;
}
@Override
protected HashMap<String, ArrayList<ArrayList<String>>> doInBackground(Integer... allPaths) {
return readData(allPaths[0]);
}
@Override
protected void onProgressUpdate(Double... progress) {
DecimalFormat df = new DecimalFormat();
df.setMaximumFractionDigits(2);
}
@Override
protected void onPostExecute(HashMap<String, ArrayList<ArrayList<String>>> result) {
delegate.processFinish(result);
}
private HashMap<String, ArrayList<ArrayList<String>>> readData(int allPaths) {
InputStream is = context.getResources().openRawResource(allPaths);
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, StandardCharsets.UTF_8));
String line = "";
HashMap<String, ArrayList<ArrayList<String>>> all_paths = new HashMap<>();
ArrayList<ArrayList<String>> value_date;
try {
while ((line = reader.readLine()) != null) {
if (isCancelled()) break;
value_date = new ArrayList<>();
// Split the line into different tokens
String[] tokens = line.split(";");
String key_date = tokens[0];
value_date.add(new ArrayList<>(Arrays.asList(tokens[1].split("\\s*,\\s*"))));
value_date.add(new ArrayList<>(Arrays.asList(tokens[2].split("\\s*,\\s*"))));
value_date.add(new ArrayList<>(Arrays.asList(tokens[3].split("\\s*,\\s*"))));
all_paths.put(key_date, value_date);
}
} catch (IOException e) {
Log.d(TAG, "Error " + line, e);
e.printStackTrace();
return null;
}
return all_paths;
}
}
In my main Activity I make a call to it and its onPostExecute method. Again, posting it just in case,
ReadAllPaths readAllPaths = (ReadAllPaths) new ReadAllPaths(this, output -> {
// Here you will receive the result fired from async class
// of onPostExecute(result) method.
Log.d(TAG, "processFinish: Process finished!");
everyPath = output;
Log.d(TAG, "onCreate: output: " + output);
}).execute(R.raw.all_paths);
What is strange is wat happens now. I can make a log.d, or print or whatever and print my output, and it will print my data perfectly. On the next stage, I need to "dynamically" access the map, so I use this simple function (level is just a avlue from 0 to 2):
private ArrayList<String> getPath(String date, int level) {
// Example of structure
// {"19-05-2022": [[path1], [path2], [path3]}]}
return everyPath.get(date).get(level);
}
Now this works perfeclty everytime except for the first element in my CSV. I know maps don't have an order, so I tried changing my CSV and the exception keeps occurring on the first line of my CSV though it is correctly displayed when I do my log.d. Also I have tried checking if key exists via:
everyPath.containsKey(date);
And also returns false only on the first row of my CSV. At first I thought this could be due to dealing with headers in the CSV, but again, the data is correctly displayed when I print the output of my AsyncTask. Only the part where I need to fetch the data is not working. Also I found a way around, which is duplicating my first row of the CSV, but I would rather understand what is going on here. Thank you!