【问题标题】:How to find the size of an Iterable Object? [duplicate]如何找到可迭代对象的大小? [复制]
【发布时间】:2012-07-09 21:34:38
【问题描述】:

我正在编写 MR Job。但是我遇到了一个与 Iterable 对象相关的问题。我需要找到它的大小。我将它转换为 List 对象,但这是错误的。(List 可以转换为 Iterable,但不能进行反转。)还有另一种方法,即对对象使用 Iterator 并为每个值增加一个计数器。但这不是最佳解决方案。有人可以提出更好的方法吗?

请帮助我。 提前致谢。

【问题讨论】:

  • 请在此处写下您的代码,以便我们查看。
  • 这个问题真的不像是编辑中链接的问题的副本

标签: java iterator


【解决方案1】:

Collection 接口提供了一个size() 方法,它扩展了Iterable。如果你的迭代器碰巧来自一个集合,你可以询问它的大小,否则你就不走运了,你只需要迭代到最后。

这是一个实现此功能的 hack:

public int size(Iterable<?> it) {
  if (it instanceof Collection)
    return ((Collection<?>)it).size();

  // else iterate

  int i = 0;
  for (Object obj : it) i++;
  return i;
}

【讨论】:

    【解决方案2】:

    您必须遍历迭代器并计算项目。 例如,

                while (iterator.hasNext()) {
                iterator.next();
                count++;
            }
    

    这不是很干净,但迭代器用于迭代目的并且没有为此提供任何特定的api。

    但是,迭代器是在哪里创建的?如果它来自另一个对象,例如 Collection 对象,您可以确定源的大小,而不是迭代器本身。

    【讨论】:

    • 这在可迭代的情况下不起作用。
    【解决方案3】:

    Iterator 上没有 size(),但一些从中派生 Iterator 的 Collections 有一个 size(),例如 java.util.LinkedList.size()。因此,在某些情况下您可能需要进行迭代。

    【讨论】:

    • 问题出在reducer函数上:protected final void reduce(final Text key, final Iterable values, final Context context) throws IOException, InterruptedException { ...... } 这里的“值”是一个可迭代对象。我需要在不迭代的情况下找到它的大小。但这是不可能的,因为它不是集合对象。我需要在找到大小后做一些其他操作。如果我正在迭代这个对象,那么在迭代之后,迭代器将指向它的最后一个值。我需要重置它。所以我使用了一个 ResettableIterator 以便在迭代后我可以重置它。
    • 您应该可以从Iterable 中多次请求iterator(),这就是为什么您在reduce 中得到Iterable 而不是Iterator 的原因。所以Iterator&lt;Text&gt; a = values.iterator(), b = values.iterator(); 是完全有效的,只要你不调用remove(),它们应该是独立的。
    猜你喜欢
    • 2018-08-19
    • 2013-02-24
    • 1970-01-01
    • 2011-04-19
    • 2015-11-07
    • 2019-06-19
    • 1970-01-01
    • 2013-03-07
    • 2011-05-17
    相关资源
    最近更新 更多