Итерируемый по умолчанию плюс другой итерируемый

Я хотел бы иметь класс с некоторыми методами, возвращающими разные Iterable, например:

public class MyClass<T extends Comparable<T>> {
  ...

  public Iterable<T> iterable1() {
    return new Iterable1<T>();
  }

  public Iterable<T> iterable2() {
    return new Iterable2<T>();
  }

  public Iterable<T> iterable3() {
    return new Iterable3<T>();
  }

}

Но мне также нужен Iterable по умолчанию для класса MyClass (скажем, Iterable1). Я знаю, что могу сделать так, чтобы MyClass расширял Iterable и реализовывал внутри него политику по умолчанию, но я не хочу этого делать, потому что мне нужен чистый интерфейс.

Я хочу иметь возможность писать:

for(T t : myClass) //Here it should use Iterable1
  //do something

or

for(T t : myClass.iterable1()) //Here it should use Iterable1 again
  //do something

и

for(T t : myClass.iterable2()) //Here it uses Iterable2
  //do something

и так далее. Однако я не могу придумать много шаблонов для этого.


person Kami    schedule 20.06.2014    source источник


Ответы (2)


Ваш класс верхнего уровня должен реализовать Iterable. Интерфейс Iterable определяет метод

Iterator<T> iterator();

который предоставит итератор по умолчанию в вашем случае.

Ваш класс должен выглядеть примерно так:

public class MyClass<T extends Comparable<T>> implements Iterable<T> {
  ...

  Iterator<T> iterator() {
    return new Iterable1<T>().iterator();
  }

  public Iterable<T> iterable1() {
   return new Iterable1<T>();
  }

  public Iterable<T> iterable2() {
   return new Iterable2<T>();
  }

  public Iterable<T> iterable3() {
   return new Iterable3<T>();
  }

}
person NickJ    schedule 20.06.2014
comment
Я думал использовать некоторые трюки с расширениями. MyClass расширяет Iterable1 или что-то в этом роде. - person Kami; 20.06.2014

Если вы хотите, чтобы это работало:

    MyClass myObject = ...
    for (T t : myObject) {
          ....

тогда MyClass должен реализовать Iterable<T>. JLS 14.14.2 говорит:

"Тип выражения должен быть Iterable или массивом (§10.1), иначе возникает ошибка времени компиляции."

где "выражение" относится к myObject.


Я знаю, что могу сделать MyClass extension (sic) Iterable и внедрить внутри него политику по умолчанию, но я не хочу этого делать, потому что мне нужен чистый интерфейс.

Извините, но это невозможно в Java. См. выше.


Я думал использовать некоторые трюки с расширениями. MyClass расширяет Iterable1 или что-то в этом роде.

Фактически это то же самое, что заставить MyClass реализовать Iterable... предполагая, что Iterable1 реализует Iterable.

person Stephen C    schedule 20.06.2014