是否有一个简单的方法来检查元素是否包含在迭代或迭代器中,类似于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 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);
番石榴有Iterables.contains和Iterators.contains的功能,可以做你想要的。您可以查看the source以了解如何自己实现它们。
迭代器是一种游标,可以在任何元素集合的元素上移动。所以它的内部状态主要是指向当前元素的指针。如果你试图找出它是否“包含”某个元素,你必须移动光标,因此修改内部状态。通过简单地提出问题来修改状态肯定是一件坏事。
这甚至是上面提到的番石榴的问题。它将通过简单地调用contains方法来修改迭代器对象。
另一方面,iterable只是一个告诉编译器有迭代的东西的接口。在大多数情况下,可迭代对象将是集合本身。如果你要在Iterable接口上添加像“contains”这样的方法,你会得到一个(简化的)Collection接口版本 - 它已经存在。所以没有必要这样做。
如果您在某个可以引用可迭代但需要集合功能的地方陷入代码,那么您应该考虑重构代码。您应该始终如一地使用界面集合,或者问自己为什么最好不要在此时调用集合方法。所以你的问题很可能是代码设计欠佳的结果。
另一方面,我认为使用Iterable作为参数或变量的类型是一件奇怪的事情。从技术上讲,你可以做到这一点,但我认为它只是用于循环。
Iterator
就像是指向集合中元素的指针/引用。它不是集合本身。所以,你不能使用iterator.contains()
。此外,Iterable
接口用于使用for-each循环迭代集合。集合和迭代器/ Iterable是不同的。
实现此接口允许对象成为“foreach”语句的目标
我很遗憾地说你要做的事情是不可能的。
.contains是接口Collection的一种方法而不是Iterable,所以也许你可以使用那个接口。