1

I want to convert given 2d array to map using java 8. Input - { { 1, 0 }, { 2, 0 }, { 3, 1 }, { 3, 2 } } The output should be of form Map<Integer, List> map = new HashMap<>(); Output - {1=[0], 2=[0], 3=[1, 2]}

Below is my solution

for (int[] prereq : prerequisites) {
            map.computeIfAbsent(prereq[0], k -> new ArrayList<>()).add(prereq[1]);
        }

Any better approach, if for loop can be replaced with streams.

  • Your approach looks fine. If you are on java 9+ and you don't plan to change the list, in such case you can do the following change `map.computeIfAbsent(prereq[0], k -> List.of(prereq[1]);` – Govinda Sakhare Jul 18 '20 at 09:45

2 Answers2

6

To collect into a Map that contains multiple values by key use Collectors.groupingBy.

int[][] prerequisites = {{1, 0}, {2, 0}, {3, 1}, {3, 2}};
Map<Integer, List<Integer>> res = Arrays.stream(prerequisites).collect(
        Collectors.groupingBy(x -> x[0], Collectors.mapping(x -> x[1], Collectors.toList())));

Output:

{1=[0], 2=[0], 3=[1, 2]}
Eklavya
  • 17,618
  • 4
  • 28
  • 57
  • 1
    Map> res = Arrays.stream(prerequisites).collect( Collectors.toMap(x -> x[0], x -> Arrays.asList(x[1]), (x1, x2) -> Arrays.asList(x1.get(0), x2.get(0)))); – Shashank Agrawal Jul 18 '20 at 10:34
  • 1
    @ShashankAgrawal Acutually groupingBy is better choice when map key has multiple value, toMap used generally for single value map and when you want merge function by own. Read more details [here](https://stackoverflow.com/questions/45231351/differences-between-collectors-tomap-and-collectors-groupingby-to-collect-in/45231743) – Eklavya Jul 18 '20 at 10:53
3

Since your array rows always consist of a pair of numbers and you consider the first element as key and the second as value, it would be obvious at first glance if you map them to SimpleEntry:

int[][] prerequisites = { { 1, 0 }, { 2, 0 }, { 3, 1 }, { 3, 2 } };
    Map<Integer,List<Integer>> map = 
            Arrays.stream(prerequisites)
                  .map(arr -> new AbstractMap.SimpleEntry<>(arr[0], arr[1]))
                  .collect(Collectors.groupingBy(
                            Map.Entry::getKey,
                            Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
Eritrean
  • 15,851
  • 3
  • 22
  • 28