【问题标题】:How to map two arrays to one HashMap in Java?如何在 Java 中将两个数组映射到一个 HashMap?
【发布时间】:2015-05-20 03:16:26
【问题描述】:

我有两个字符串数组。一个有短名字的。

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

另一个名字很长。

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

两者具有相同数量的元素。如何在 HashMap 中将短名称映射为 KEY 并将长名称映射为 VALUE?

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

我知道,我可以通过循环来制作。有没有更好的办法?

【问题讨论】:

  • 我认为在这种情况下循环是最好的方法——当这两个数组的大小相同时。
  • 为什么首先存储在数组中?

标签: java arrays arraylist hashmap


【解决方案1】:

有很多方法可以做到这一点。一个相当容易理解和应用的方法是使用 Java 8 流和收集器从索引流映射到键值对:

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

有一些第三方 Java 库包含一个“zip”函数来获取两个流并生成一个从一个流到另一个的映射。但实际上,它们只是实现与上述代码相同的更简洁的方法。

【讨论】:

  • 那么 java 7 及以下版本呢?
  • @10sw33 在 Java 8 以下(升级除外!)您仍然有一些选择。使用第三方库或使用Arrays.toList(shortNames).forEach 浏览一个数组中的所有项目并添加地图条目。我知道这实际上只是另一个名称的迭代,但流也是如此!
  • @sprinter 很好的答案,但他需要 boxed() 就像 Jens 下面所说的那样。
【解决方案2】:

accepted answer 对我不起作用,因为 IntStream 不提供单参数 collect 方法。

要从toMap 收集器中受益,您必须首先将int 原语装箱到Integer 对象中。如果您想保留元素顺序,请使用toMap 的扩展版本和LinkedHashMap::new,如下所示:

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);
    }
}

另见:Why don't primitive Stream have collect(Collector)?

【讨论】:

    【解决方案3】:

    您可以使用org.apache.commons.lang3.ArrayUtils

    这是一个例子:

    Map colorMap = ArrayUtils.toMap(new String[][] {
        {"RED", "#FF0000"},
        {"GREEN", "#00FF00"},
        {"BLUE", "#0000FF"}});
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-07
      • 2019-09-13
      • 1970-01-01
      • 2021-11-05
      • 1970-01-01
      • 2020-10-24
      • 2011-04-18
      • 1970-01-01
      相关资源
      最近更新 更多