在Java 8中,我如何同时迭代两个数组?

4

我正在编写一个Java程序,从CSV文件中获取数据。对于每一行数据,我需要使用相应的标题作为键将每个数据元素放入映射中。例如,headerRow [7]和dataElements [7]应该是映射中的键值对。

以下是我传统使用Java编写的代码:

private Map<String, Double> readLine(String[] headerRow, String[] dataElements) {
    Map<String, Double> headerToDataMap = new HashMap<>(); 
    for (int i=0; i < nextLine.length; i++) {
        headerToDataMap.put(headerRow[i], Double.valueOf(dataElements[i]));
    }
    return headerToDataMap;
}

是否有一种方法可以使用Java 8流编写此代码-请记住我同时迭代两个数组?


很遗憾,没有内置的Zip方法。 - flakes
2个回答

9
在Java 8中,最接近这种功能的可能是:
 IntStream.range(0, nextLine.length())
    .boxed()
    .collect(toMap(i -> headerRow[i], i -> dataElements[i]));

1
没有 headerRow::[] +1。 - Peter Lawrey
1
@PeterLawrey 也认为这将是一个不错的表示法。 - flakes
Guava 21将拥有Streams.zip,但我认为之后将其转换为Map并不比现在更好。 - Louis Wasserman
不知何故,OP的 nextLine.length 已经变成了 nextLine.length(),但我仍然不知道 nextLine 是什么…… 另外,你的代码缺少将 String 转换为 Double 的步骤。 - Holger
无需装箱的解决方案:IntStream.range(0, nextLine.length) .collect(HashMap::new, (m,i) -> m.put(headerRow[i], Double.valueOf(dataElements[i])), Map::putAll); - Holger

1
你可以使用BiFunction接口使某些东西变得稍长。
private Map<String, Double> readLine(String[] headerRow, String[] dataElements) {
        Map<String, Double> headerToDataMap = new HashMap<>();  
        BiFunction<String,String, KeyValue> toKeyValuePair = (s1,s2) -> new KeyValue(s1,s2);
        IntStream.range(0, nextLine.length)
                .mapToObj(i -> toKeyValuePair.apply(headerRow[i], dataElements[i]) )
                .collect(Collectors.toList())
                .stream()
                .forEach(kv -> {
                    headerToDataMap.put(kv.getKey(), Double.valueOf(kv.getValue()));
                });
        return headerToDataMap;
    }

KeyValue 类型是一个简单的键值实例生成器(以下为代码)。
private class KeyValue {
        String key;
        String value;
        public String getKey() {
            return key;
        }
        public void setKey(String key) {
            this.key = key;
        }
        public String getValue() {
            return value;
        }
        public void setValue(String value) {
            this.value = value;
        }
        public KeyValue(String key, String value) {
            super();
            this.key = key;
            this.value = value;
        }
        public KeyValue() {
            super();
        }       
    }

1
这是一个非常奇怪的流使用方式。中间的.collect(Collectors.toList()) .stream()步骤有什么意义?它们对操作没有任何有用的贡献,只会增加开销。你可以简单地将它们都删除。此外,如果你知道collect,为什么还要在最后使用forEach?为什么要先创建那个BiFunction,然后在另一个lambda表达式中使用它,而不是直接在mapToObj步骤的lambda表达式中编写预期的代码? - Holger
@Holger,感谢您的评论。我会尽快检查并反馈。 - alainlompo

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