包含Iterable和Iterator的方法?

问题描述 投票:9回答:5

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

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

java collections iterator iterable
5个回答
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);

4
投票

番石榴有Iterables.containsIterators.contains的功能,可以做你想要的。您可以查看the source以了解如何自己实现它们。


3
投票

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

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

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

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

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


0
投票

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


0
投票

来自JavaDoc for Iterable

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.