【问题标题】:In Java 8, how can I iterate through two arrays at one time?在 Java 8 中,如何一次遍历两个数组?
【发布时间】:2016-11-07 20:33:44
【问题描述】:

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

下面是我传统上使用 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 方法

标签: java arrays java-stream


【解决方案1】:

在 vanilla Java 8 中最接近这一点的可能是

 IntStream.range(0, nextLine.length())
    .boxed()
    .collect(toMap(i -> headerRow[i], i -> dataElements[i]));

【讨论】:

  • 没有headerRow::[] +1
  • @PeterLawrey 也认为这将是一个简洁的符号。
  • Guava 21 将拥有 Streams.zip,但我认为之后将其变为 Map 不会比这更好。
  • 不知何故,OP 的nextLine.length 已变异为nextLine.length(),但我仍然不知道nextLine 是什么……此外,您的代码缺少StringDouble 的转换。
  • 拳击免费解决方案:IntStream.range(0, nextLine.length) .collect(HashMap::new, (m,i) -&gt; m.put(headerRow[i], Double.valueOf(dataElements[i])), Map::putAll);
【解决方案2】:

您可以使用 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();
        }       
    }

【讨论】:

  • 这是一个非常奇怪的扭曲流用法。中间的.collect(Collectors.toList()) .stream() 步骤有什么意义?它们不会为操作添加任何有用的东西,只会增加开销。您可以简单地删除两者。此外,如果您知道collect,为什么最后还要诉诸forEach?为什么要先创建 BiFunction,只是为了在另一个 lambda 表达式中使用它,而不是在 mapToObj 步骤中的 lambda 表达式中直接编写预期代码?
  • @Holger 感谢您的发言。我会尽快检查并反馈
猜你喜欢
  • 2010-10-04
  • 2015-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-16
  • 2020-09-17
  • 1970-01-01
  • 2015-07-11
相关资源
最近更新 更多