How can I store values in a hashmap with <String, List<Integer>>

Viewed 93

I have the following array

I am trying to save the array information in a hashmap.

String[][] students = {{"Bobby", 87}, {"Charles", 100}, {"Eric", 64}, 
                               {"Charles", 22}};

Map<String, List<Integer>> map = new HashMap<>();
List<Integer> score1 = new ArrayList<>();
for(int i=0; i<students.length; i++) {
    score1.add(students[i][1]);
    map.put(students[i][0], score1);
}

But i want to store the information in the map key value pair.

Expected output:

"Bobby" -> 87
"Charles" -> 100,22
"Eric" -> 64

Actual output:

{Charles=[87, 100, 64, 22], Eric=[87, 100, 64, 22], Bobby=[87, 100, 64, 22]}

how can I do this?

5 Answers

Using java-8 you could use the following all in a single line :

Map<String, List<Integer>> collect1 = 
     Arrays.stream(students).collect(Collectors.groupingBy(arr -> arr[0], 
              Collectors.mapping(arr -> Integer.parseInt(arr[1]), Collectors.toList())));

Here we group by the 0th index for the name of the student and the 1st index will hold the marks of the student.

You need to differentiate between already exist and new array:

 List<Integer> currScore = map.get(students[i][0])
 if (currScore != null) {
   currScore.add(students[i][1]);
 } else {
    List<Integer> newScore = new ArrayList<>();
    newScore.add(students[i][1]);
    map.put(students[i][0], newScore);
 }

Also change variables names to meaningful names

You can check why your original code won't even compile here: https://ideone.com/AWgBWl

After several fixes to your code this is a correct way of doing it (following your logic):

// values should be like this {"Bobby", "87"} because you declared it as
// an array of strings (String[][]), this {"Bobby", 87} is a String and an int
String[][] students = {{"Bobby", "87"}, {"Charles", "100"}, {"Eric", "64"}, {"Charles", "22"}};
// the inner list must be of Strings because of the previous comment
Map<String, List<String>> map = new HashMap<>();
// list of strings because of the previous comment
List<String> score1;

for(int i = 0; i < students.length; i++) {
    score1 = map.get(students[i][0]);     // check if there is a previously added list
    if (score1 == null) {
        score1 = new ArrayList<>();      // create a new list if there is not one previously added for that name
        map.put(students[i][0], score1);
    }
    map.get(students[i][0]).add(students[i][1]); // add a new value to the list inside the map
}
System.out.println(map.toString());
// {Charles=[100, 22], Eric=[64], Bobby=[87]}

Demo here: https://ideone.com/SJpTHs

String[][] students = { { "Bobby", "87" }, { "Charles", "100" }, { "Eric", "64" }, { "Charles", "22" } };
Map<String, List<Integer>> map = new HashMap<>();
Stream.of(students).forEach(student -> map.computeIfAbsent(student[0], s -> new ArrayList<>()).add(Integer.parseInt(student[1])));

Since you initialize you list outside the loop and use it for all appends, all entries in your hashmap are referencing the same instance. For each entry in students, you need to check if you already have a list for that student. If so, retrieve that particular list and append to it. If not, create a new list and then append. The code inside you for loop will look something like the following:

String name = students[i][0];
List<Integer> scores = map.get(name);
if (scores == null) {
    scores = new ArrayList<>();
}
scores.add(students[i][1]);
map.put(name, scores);
Related