Search code examples
javasqlhashmap

Filling a Java HashMap from a database table


I have a table that has two columns, one is string and other is double type. for example,

+========+=============+
| Center | Efficiency  |
+========+=============+
| A1     | 0.603576904 |
+--------+-------------+
| A2     | 0.557877389 |
+--------+-------------+
| A3     |  0.70911818 |
+--------+-------------+
| A4     | 0.048944132 |
+--------+-------------+
| A1     | 0.064781491 |
+--------+-------------+
| A2     | 0.192317935 |
+--------+-------------+
| A3     | 0.316078683 |
+--------+-------------+
| A4     | 0.121362541 |
+--------+-------------+
| A1     | 0.815996499 |
+--------+-------------+
| A2     | 0.032305255 |
+--------+-------------+
| A3     | 0.750355015 |
+--------+-------------+
| A4     | 0.071286058 |
+--------+-------------+

I'm trying to read all the values and load them into a Java HashMap<String, Double[]>

I don't have any problem with reading table data but can not place them into the HashMap as I wanted.

I wrote a sample code to populate a HashMap from two different arrays of string and double but still confused to work with the value part of the Hashmap which is an array.

  String[] names = { "8A", "8C", "8J", "8A", "8C", "8J", "8A", "8C", "8J", "8A", "8C", "8J", };

  Double[] metrics = { 0.60, 0.55, 0.70, 0.04, 0.06, 0.19, 0.31, 0.12, 0.81, 0.03, 0.75, 0.07 };

  for (int i = 0; i < 12; i++)
  {
     if (values.get(names[i]) == null)
     {
        values.put(names[i], new ArrayList<Double>(Arrays.asList(metrics[i])));
     }
     else
        values.get(names[i]).add(metrics[i]);
  }

  System.out.println(values);

Any suggestion how can I handle with the value part of the HashMap which is an array and the size will depend on the table row numbers.


Solution

  • Nowadays Map has some convenience methods and you can use computeIfAbsent:

    Map<String, List<Double>> values = new HashMap<>();
            for (int i = 0; i < 12; i++) {
                List<Double> items = values.computeIfAbsent(names[i], k -> new ArrayList<>());
                items.add(metrics[i]);
            }
    

    There's a more elaborate post about that here.

    But if you want to have an Map<String, double[]> then that's very inconvenient during loading, since arrays have fixed size and you'd need to copy them over and over. You could arrive at double[] using the list version for loading and eventually convert it

    Map<String, double[]> dvalues = new HashMap<>();
    values.forEach((k, v) -> dvalues.put(k, v.stream().mapToDouble(i -> i).toArray()));
    

    Or if it should be a Double[]

    Map<String, Double[]> dvalues = new HashMap<>();
    values.forEach((k, v) -> dvalues.put(k, v.toArray(new Double[v.size()])));
    

    The only alternative I see is to iterate over the raw data twice, first calculating the number of values for each key, create a map from that with properly sized arrays, iterate again over the raw data keeping track of the maxIdx in each value array as they fill up ... very complicated.