Як говорили інші, Ітерабельний може викликатися кілька разів, повертаючи свіжий Ітератор під час кожного дзвінка; ітератор використовується лише один раз. Так вони пов’язані між собою, але служать різним цілям. Розчаровує, однак, "компактний для" метод працює лише з ітерабельним.
Що я опишу нижче, це один із способів отримати найкраще з обох світів - повернення Iterable (для кращого синтаксису), навіть коли основна послідовність даних є одноразовою.
Хитрість полягає в тому, щоб повернути анонімну реалізацію Iterable, яка фактично запускає роботу. Отже, замість того, щоб виконувати роботу, яка генерує одноразову послідовність, а потім повертаючи Ітератор над цим, ви повертаєте Iterable, який кожного разу, до якого звертаєтесь, повторює роботу. Це може здатися марним, але часто ви будете називати Ітерабельний лише один раз, і навіть якщо ви називаєте його кілька разів, він все ще має розумну семантику (на відміну від простої обгортки, яка робить Ітератор "схожим на" Ітерабельний, це переміг " t не вдасться, якщо використовується два рази).
Наприклад, скажіть, що у мене є DAO, який забезпечує серію об'єктів із бази даних, і я хочу надати доступ до цього за допомогою ітератора (наприклад, щоб уникнути створення всіх об'єктів у пам'яті, якщо вони не потрібні). Тепер я міг би просто повернути ітератор, але це робить використання повернутого значення в циклі некрасивим. Тож замість цього я загортаю все в необоснований Ітерабельний:
class MetricDao {
...
/**
* @return All known metrics.
*/
public final Iterable<Metric> loadAll() {
return new Iterable<Metric>() {
@Override
public Iterator<Metric> iterator() {
return sessionFactory.getCurrentSession()
.createQuery("from Metric as metric")
.iterate();
}
};
}
}
це може бути використане у такому коді:
class DaoUser {
private MetricDao dao;
for (Metric existing : dao.loadAll()) {
// do stuff here...
}
}
що дозволяє мені використовувати компакт для циклу, зберігаючи при цьому додаткове використання пам'яті.
Такий підхід є "ледачим" - робота робиться не тоді, коли запитується Ітерабельна, а лише пізніше, коли вміст переглядається, - і вам потрібно знати про наслідки цього. У прикладі з DAO, що означає повторення результатів в рамках транзакції бази даних.
Отже, існують різні застереження, але це все ще може бути корисною фразою у багатьох випадках.