How to map two arrays to one HashMap in Java?

17,767

Solution 1

There are lots of ways you can do this. One that is fairly easy to understand and apply is using Java 8 streams and collectors to map from a stream of indices to key value pairs:

Map<String, String> days = IntStream.range(0, shortNames.length).boxed()
    .collect(Collectors.toMap(i -> shortNames[i], i -> longNames[i]));

There are some third party Java libraries that include a 'zip' function to take two streams and produce a map from one to the other. But really they are just neater ways of achieving the same thing as the code above.

Solution 2

The accepted answer did not work for me, as the IntStream does not provide a one-argument collect method.

To nevertheless benefit from the toMap collector you have to box the int primitives into Integer objects first. If you like to preserve the element order, use the extended version of toMap together with LinkedHashMap::new like shown below:

package learning.java8;

import static java.util.stream.Collectors.*;
import static org.junit.Assert.*;

import java.time.DayOfWeek;
import java.time.format.TextStyle;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.stream.IntStream;

import org.junit.Test;

public class IntStreamLT {

    @Test
    public void q30339679() {

        final String[] shortNames = getDayOfWeekNamesInEnglish(TextStyle.SHORT);
        final String[] longNames = getDayOfWeekNamesInEnglish(TextStyle.FULL);

        final Map<String, String> days = IntStream.range(0, shortNames.length).boxed()
                .collect(toMap(i -> shortNames[i], i -> longNames[i]));

        System.out.println(days);

        final Map<String, String> sorted = IntStream.range(0, shortNames.length).boxed()
                .collect(toMap(
                        i -> shortNames[i], i -> longNames[i],
                        (i, j) -> i, LinkedHashMap::new));

        System.out.println(sorted);

        assertEquals("{Mon=Monday, Tue=Tuesday, Wed=Wednesday, Thu=Thursday, "
                + "Fri=Friday, Sat=Saturday, Sun=Sunday}", sorted.toString());
    }

    private static String[] getDayOfWeekNamesInEnglish(final TextStyle style) {

        return Arrays.stream(DayOfWeek.values())
                .map(day -> day.getDisplayName(style, Locale.ENGLISH))
                .toArray(String[]::new);
    }
}

see also: Why don't primitive Stream have collect(Collector)?

Solution 3

You can use org.apache.commons.lang3.ArrayUtils.

Here is an example:

Map colorMap = ArrayUtils.toMap(new String[][] {
    {"RED", "#FF0000"},
    {"GREEN", "#00FF00"},
    {"BLUE", "#0000FF"}});
Share:
17,767
Madan Sapkota
Author by

Madan Sapkota

I am a highly skilled PHP and JavaScript developer with ten years of experience in programming for a multitude of web based projects.

Updated on June 17, 2022

Comments

  • Madan Sapkota
    Madan Sapkota about 2 years

    I have two String arrays. One having short name.

    // days short name
    String[] shortNames = {"SUN", "MON", "...", "SAT"};
    

    The other having long name.

    // days long name
    String[] longNames = {"SUNDAY", "MONDAY", "....", "SATURDAY"};
    

    Both having same number of elements. How can I map short name as KEY and long name as VALUE in HashMap?

    HashMap<String, String> days = new HashMap<>();
    

    I know, I can make by looping. Is there a better way?

  • Sindhoo Oad
    Sindhoo Oad about 9 years
    and what about java 7 and below?
  • sprinter
    sprinter about 9 years
    @10sw33 Below Java 8 (other than upgrading!) you still have a few options. Use a third party library or use Arrays.toList(shortNames).forEach to go through all the items in one array and add the map entries. I know this is really just iteration by another name but then so also are streams!
  • Nick Ziebert
    Nick Ziebert over 7 years
    @sprinter Good answer, but he needs boxed() as Jens said below.