包含 Iterable 和 Iterator 的方法?

Posted

技术标签:

【中文标题】包含 Iterable 和 Iterator 的方法?【英文标题】:Contains method for Iterable and Iterator? 【发布时间】:2014-12-22 17:35:31 【问题描述】:

是否有一种简单的方法来检查元素是否包含在可迭代或迭代器中,类似于Collection.contains(Object o) 方法?

即而不必写:

Iterable<String> data = getData();
for (final String name : data) 
    if (name.equals(myName)) 
        return true;
    

我想写:

Iterable<String> data = getData(); 
if (Collections.contains(data, myName)) 
    return true;

我真的很惊讶没有这样的事情。

【问题讨论】:

如果你受限于 JDK 库,我认为没有直接的方法可以做到这一点。 【参考方案1】:

Guava 具有 Iterables.contains 和 Iterators.contains 的功能,可以满足您的需求。您可以查看the source 以了解如何自己实现它们。

【讨论】:

【参考方案2】:

在 Java 8 中,您可以将 Iterable 转换为 Stream 并在其上使用 anyMatch

String myName = ... ;
Iterable<String> data = getData();

return StreamSupport.stream(data.spliterator(), false)
                    .anyMatch(name -> myName.equals(name));

或使用方法引用,

return StreamSupport.stream(data.spliterator(), false)
                    .anyMatch(myName::equals);

【讨论】:

【参考方案3】:

迭代器是一种可以在任何元素集合的元素上移动的光标。所以它的内部状态主要是指向当前元素的指针。如果您要尝试找出它是否“包含”某个元素,则必须移动光标并因此修改内部状态。通过简单地问一个问题来修改状态肯定是一件坏事。

这甚至是提到的番石榴的问题。它将通过简单地调用 contains 方法来修改迭代器对象。

另一方面,可迭代对象只是一个接口,告诉编译器有一些东西需要迭代。在大多数情况下,可迭代对象将是集合本身。如果您将“包含”之类的方法添加到接口 Iterable 中,您将获得 Collection 接口的(简化)版本 - 它已经存在。所以没有必要。

如果您的代码被困在某个引用可迭代但需要集合功能的地方,您应该考虑重构您的代码。您应该始终如一地使用接口集合,或者问自己为什么此时最好不要调用集合方法。因此,您的问题很可能是次优代码设计的结果。

另一方面,我认为使用 Iterable 作为参数或变量的类型是一件奇怪的事情。从技术上讲,您可以这样做,但我认为它只能在循环中使用。

【讨论】:

我使用 Guava Splitter 获得了一个 Iterable,我不能使用较新的 splitToList,因为我们在公司使用的是旧版本。 那么糟糕的代码设计是由谷歌设计的,他们现在自己意识到了 ;-) 我认为 Collections 类可以添加一个接受 Iterable 的 contains 方法。我说的是集合,而不是集合。 如果您将“包含”之类的方法添加到接口 Iterable 中,您将获得 Collection 接口的(简化)版本 - 它已经存在。所以没有必要。 有必要。考虑到PathIterable 但不是Collection,因此能够检查Path 是否包含某个元素是有意义的。【参考方案4】:

来自JavaDoc for Iterable:

实现这个接口允许一个对象成为“foreach”语句的目标

很抱歉,您尝试做的事情是不可能的。

.contains 是接口 Collection 的一个方法,而不是 Iterable,所以也许你可以使用该接口。

【讨论】:

【参考方案5】:

Iterator 类似于集合中元素的指针/引用。 不是集合本身。所以,你不能使用iterator.contains()。此外,Iterable 接口用于使用 for-each 循环对集合进行迭代。集合和 Iterator / Iterable 是不同的。

【讨论】:

以上是关于包含 Iterable 和 Iterator 的方法?的主要内容,如果未能解决你的问题,请参考以下文章

生成器和迭代(Generator: iterable , iterator, iteration)

Python中的iterable和iterator

Iterator 和 Iterable 之间的区别

请问java中的Iterator和Iterable有些啥区别啊?

如何理解 Java 中的 `Iterable` 和 `Iterator`? [复制]

python generator iterator和iterable object