【问题标题】:reducer with iterator error具有迭代器错误的减速器
【发布时间】:2016-11-04 09:06:04
【问题描述】:

我在 hadoop 中有一个减速器,代码如下:

public void reduce(Text key, Iterator<Text> values, Context context) throws IOException, InterruptedException {
/*some code*/
String followers = ""; 
  while(values.hasNext()){
        followers = followers + values.next().toString() + ",";
  }
/*some code*/
}

我想为某个节点创建一个关注者列表,但是当我运行它时,我得到了这个:

Error: java.lang.ArrayIndexOutOfBoundsException: 1

如果 values 是 Iterable 类型,那么我没有问题,但为什么会发生这种情况?

提前致谢。

【问题讨论】:

  • 我猜你打的是max string length,但我不知道迭代器中有多少值/值有多大
  • 我正在尝试一个非常小的输入,所以我认为我没有达到最大字符串长度。
  • 不是你的问题的答案,而是几点:1)你可以做followers += values... 2)你可以做...values.next() + ",";,因为toString()被隐式调用3)你通常应该在循环中连接字符串时使用StringBuilder
  • 感谢您的提示 :)

标签: java hadoop iterator iterable


【解决方案1】:

如果您要扩展 org.apache.hadoop.mapreduce.Reducer (Java Docs),则用于 reduce() 的方法签名不正确。当您实现 reduce() 方法时,您将覆盖 Reduce 类中的实现。

你有:

reduce(Text key, Iterator&lt;Text&gt; values, Context context)

应该是:

reduce(Text key, Iterable&lt;Text&gt; values, Context context)

注意IteratorIterable 之间的区别。这可能意味着您的 reduce 实际上没有被调用。

您可以在方法中添加@Override 注释以帮助防止这种情况发生。

【讨论】:

  • 但是我什么时候应该使用迭代器,什么时候可以在 hadoop 中迭代?
  • 你的方法签名必须使用Iterable,否则它实际上不会被调用。
  • 我不确定我是否理解。我们谈论的是方法签名,该签名是固定的。如果是Iterable,您可以使用for (Text t : values) { } 轻松循环。如果你曾经在 reduce 方法签名中看到 Iterator,那他们就搞错了。
猜你喜欢
  • 2015-07-28
  • 1970-01-01
  • 2020-03-06
  • 1970-01-01
  • 2017-05-09
  • 1970-01-01
  • 2021-11-25
  • 2021-11-21
  • 2016-07-10
相关资源
最近更新 更多