包含Iterable和Iterator的方法?

时间:2014-10-27 14:01:16

标签: java collections iterator iterable

是否有一个简单的方法来检查一个元素是否包含在迭代或迭代器中,类似于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;
}

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

5 个答案:

答案 0 :(得分:8)

在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);

答案 1 :(得分:4)

Guava具有您想要的功能Iterables.containsIterators.contains。您可以查看the source以了解如何自行实施这些内容。

答案 2 :(得分:3)

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

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

另一方面,iterable只是一个告诉编译器有迭代的东西的接口。在大多数情况下,可迭代对象将是集合本身。如果你要添加&#34; contains&#34;等方法。在Iterable接口上你会得到一个(简化的)Collection接口版本 - 它已经存在。所以没有必要这样做。

如果您在某个可以引用可迭代但需要集合功能的地方遇到代码,那么您应该考虑重构代码。您应该始终如一地使用界面集合,或者问自己为什么最好不要在此时调用集合方法。所以你的问题很可能是代码设计欠佳的结果。

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

答案 3 :(得分:0)

Iterator就像是指向集合中元素的指针/引用。 集合本身。因此,您无法使用iterator.contains()。此外,Iterable接口用于使用 for-each 循环对集合进行迭代。集合和迭代器/ Iterable是不同的。

答案 4 :(得分:0)

来自JavaDoc for Iterable

  

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

我很遗憾地说你要做的事情是不可能的。

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