将静态的二维字符串数组转换为HashMap

5
什么是将字符串的二维数组转换为HashMap的最简单方法?
例如,这样做:
final String[][] sheetMap = { /* XSD Name,  XSL Sheet Name */
                              {"FileHeader", "FileHeader"}, 
                              {"AccountRecord", "AccountRecord"}, 
                              {"DriverCardRecord", "DriverCardRecord"}, 
                              {"AssetCardRecord", "AssetCardRecord"},
                              {"SiteCardRecord", "SiteCardRecord"}
                            };
这很可能会从文件中加载,并且会更大。

我应该补充说明的是,除了现在正在做的循环遍历元素之外,是否有一种集合方法可以将这个二维数组直接传递到HashMap实例中? - Casey
1
据我所知,没有这样的方法 - 而且我认为实现比简单循环遍历所有数组元素更有效率的方法是不可能的。因此,您不会获得任何优势,除了一些简洁性,您可以通过将其放入自己的“Utils”类型类中再次复制。 - Andrzej Doyle
7个回答

23
final Map<String, String> map = new HashMap<String, String>(sheetMap.length);
for (String[] mapping : sheetMap)
{
    map.put(mapping[0], mapping[1]);
}

6
如果您只是想以一种方便的方式初始化地图,您可以使用“双括号初始化”(double brace initialization):(参考链接)
Map<String, String > sheetMap = new HashMap<String, String >() {{
   put( "FileHeader", "FileHeader" ); 
   put( "AccountRecord", "AccountRecord" ); 
   put( "DriverCardRecord", "DriverCardRecord" ); 
   put( "AssetCardRecord", "AssetCardRecord" );
   put( "SiteCardRecord", "SiteCardRecord" );
}};

这可能会带来一些负面影响,被广泛认为是一种反模式--https://blog.jooq.org/2014/12/08/dont-be-clever-the-double-curly-braces-anti-pattern/ - Jamie Bisotti
更不用说,它实际上并没有回答问题。它不会转换甚至涉及到二维数组。 - Tim M.

4
作为比tradeJmark答案略为简洁的替代方案:
String[][] arr = // your two dimensional array
Map<String, String> arrMap = Arrays.stream(arr).collect(Collectors.toMap(e -> e[0], e -> e[1]));

// Sanity check!
for (Entry<String, String> e : arrMap.entrySet()) {
    System.out.println(e.getKey() + " : " + e.getValue());
}

哇,这比我的好多了,我简直不敢相信我不知道这个存在!太棒了,谢谢! - Tim M.

2

现有的答案当然很好,但为了不断更新本网站的新信息,以下是一种在Java 8中实现它的方法:

String[][] arr = {{"key", "val"}, {"key2", "val2"}};
HashMap<String, String> map = Arrays.stream(arr)
        .collect(HashMap<String, String>::new,
                (mp, ar) -> mp.put(ar[0], ar[1]),
                HashMap<String, String>::putAll);

Java 8的Stream非常棒,我鼓励你查阅更详细的信息,但是对于这个特定的操作,以下是基本操作:

  • Arrays.stream会获得一个Stream<String[]>
  • collect获取你的Stream并将其减少为一个收集所有成员的单个对象。它需要三个函数。第一个函数是供应商,它生成一个收集成员的新对象实例,在我们的案例中,只需使用标准方法创建一个HashMap 。第二个函数是累加器,它定义如何将Stream的成员包括到目标对象中,例如在你的情况下,我们只想把键和值(每个数组的第一个和第二个值)作为map的键值对put到Map中。第三个函数是合成器,它可以组合两个目标对象,以防万一JVM决定使用多个HashMap(在此情况下或其他情况下使用其他目标对象)进行积累步骤,然后需要将它们组合成一个对象,这主要用于异步执行,尽管这通常不会发生。

2
使用流更加简洁的写法如下:
 import static java.util.Arrays.stream;
 import static java.util.stream.Collectors.toMap;
 import java.util.Map;

     ...

 public static Map<String, String> asMap(String[][] data) {
     return stream(data).collect(toMap( m->m[0], m->m[1] ));
 }

     ...

2

等等,如果这个要从文件中加载,不要经过中间数组步骤!你必须先全部加载它,然后创建数组,不然你不知道数组的大小。只需创建一个HashMap,并在读取时添加每个条目。


是的,这就是计划。然而,我目前不知道信息将存储在哪里,所以我只是将其硬编码到数组中。这确实引出了一个问题,即是否Collections框架已经包含了一个实现此任务的实用程序方法,尽管它很容易实现。我宁愿在可能的情况下使用集合中的方法。 - Casey
啊,好吧,是的,它不行。如果可以的话,它会接受一些集合,而不是一个数组。也许是Map.Entry的集合。但这并不是非常有用的。循环更好。 - Kevin Bourrillion

0

Java 8 的方式

  public static Map<String, String> convert2DArrayToMap(String[][] data){
    return Arrays.stream(data).collect(Collectors.toMap(m -> m[0], m -> m[1]));
  }

使用循环

public static Map<String, String> convert2DArrayToMap(String[][] data)
  {
    Map<String, String> map = new HashMap<>();
    for (String[] m : data)
    {
      if (map.put(m[0], m[1]) != null)
      {
        throw new IllegalStateException("Duplicate key");
      }
    }
    return map;
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接