2014-10-27 60 views
7

有沒有一種簡單的方法來檢查一個元素是否包含在一個迭代器或迭代器中,類似於Collection.contains(Object o)方法?包含用於Iterable和Iterator的方法?

I.e.而不必寫:

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; 
} 

我真的很驚訝,有沒有這樣的事情。

+1

如果你被限制到JDK庫,我不相信有這樣做的直接手段。 – 2014-10-27 14:06:04

回答

6

在Java 8中,您可以在它打開IterableStream和使用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); 
0

Iterator就像是對集合中元素的指針/引用。它是而不是集合本身。所以,你不能使用iterator.contains()。而且,Iterable接口用於迭代通過集合使用for each每個循環。集合和迭代器/ Iterable是不同的。

0

JavaDoc for Iterable

實現此接口允許一個對象是「的foreach」語句

我很抱歉地說,你正在試圖做的是什麼目標不可能。

.contains是接口Collection的方法,而不是Iterable,所以也許你可以使用該接口。

3

迭代器是一種可以移動到任何元素集合的元素上的遊標。所以它的內部狀態主要是指向當前元素的指針。如果你試圖找出它是否「包含」某個元素,你將不得不移動光標,因此修改內部狀態。通過簡單地問一個問題來修改狀態肯定是一件壞事。

這甚至與提到的番石榴的問題。它將通過簡單地調用contains方法來修改迭代器對象。

另一方面,iterable只是一個告訴編譯器需要迭代的接口。在大多數情況下,可迭代對象將是集合本身。如果你想在接口Iterable中添加像「contains」這樣的方法,你會得到Collection接口的(簡化)版本 - 已經存在。所以這沒有必要。

如果您在某處引用了可迭代但需要集合功能的地方停留在代碼中,則應考慮重構代碼。要麼你應該一致地使用接口集合,要麼問自己爲什麼你最好不要在這個時候調用收集方法。所以你的問題很可能是代碼設計不理想的結果。

另一方面,我認爲使用Iterable作爲參數或變量的類型是一件很奇怪的事情。技術上你可以做到這一點,但我認爲它只用於循環。

+0

我使用[Guava Splitter]獲得一個Iterable(http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Splitter.html#split(java.lang.CharSequence)) ,我不能使用更新的'splitToList',因爲我們在公司使用的是舊版本。 – Roland 2014-10-27 14:48:18

+1

那麼糟糕的代碼設計是由谷歌,他們現在意識到它自己;-) – 2014-10-27 14:58:38

+0

我認爲集合類可以添加一個包含方法,接受一個I​​terable。我在談論收藏,而不是收藏。 – Roland 2014-10-30 09:20:18