2014-10-27 2 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, я не верьте, что есть прямые средства для этого. –

ответ

6

В 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); 
0

Iterator как указатель/ссылка на элемент в коллекции. Это не самой коллекции. Таким образом, вы не можете использовать iterator.contains(). Кроме того, интерфейс Iterable используется для итерации по коллекции с использованием для каждого цикла. Коллекция и Iterator/Iterable различны.

0

От JavaDoc for Iterable:

Реализация этого интерфейса позволяет объекту быть мишенью «Еогеасп» заявление

Я сожалею, чтобы сказать, что вы пытаетесь сделать, невозможно.

.contains - это метод интерфейса Collection, а не Iterable, поэтому, возможно, вы можете использовать этот интерфейс.

3

Итератор - это своего рода курсор, который можно перемещать по элементам любой коллекции элементов. Таким образом, его внутреннее состояние является главным образом указателем на текущий элемент. Если вы попытаетесь выяснить, содержит ли он «определенный элемент», вам придется перемещать курсор и, следовательно, изменять внутреннее состояние. Изменение состояния, просто задавая вопрос, конечно, плохо.

Это даже проблема с упомянутым Гуава. Он изменит объект итератора, просто вызов метод contains.

Итерабельность, с другой стороны, представляет собой просто интерфейс, сообщающий компилятору, что есть что-то, чтобы перебрать. В большинстве случаев итерируемый объект будет самой коллекцией. Если вы добавите такие методы, как «contains» в интерфейс Iterable, вы получите (упрощенную) версию интерфейса Collection, которая уже существует. Поэтому в этом нет необходимости.

Если вы застряли в своем коде в каком-либо месте, где у вас есть ссылка на итерируемую, но вам нужна функциональность коллекции, вы должны подумать о реорганизации своего кода. Либо вы должны последовательно использовать коллекцию интерфейсов, либо спросить себя, почему вам лучше не обращаться к методам сбора на данный момент. Таким образом, ваша проблема, скорее всего, является результатом субоптимального кода.

С другой стороны, я бы счел странным, что использовать Iterable как тип для параметров или переменных в любом случае. Технически вы можете это сделать, но я думаю, что он предназначен только для петель.

+0

Я получаю Iterable с помощью [Guava Splitter] (http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Splitter.html#split (java.lang.CharSequence)) , Я не могу использовать новый 'splitToList', потому что мы используем более старую версию здесь, в компании. – Roland

+1

Ну, тогда плохой дизайн кода от Google, и они уже поняли это сами ;-) –

+0

Я думаю, что класс Collections мог бы добавить метод contains, который принимает Iterable. Я говорю о коллекциях, а не о Коллекции. – Roland