Como já foi dito, um Iterable pode ser chamado várias vezes, retornando um Iterator novo a cada chamada; um iterador é usado apenas uma vez. Portanto, eles estão relacionados, mas servem a propósitos diferentes. Frustrantemente, no entanto, o método "compactar para" funciona apenas com um iterável.
O que descreverei abaixo é uma maneira de obter o melhor dos dois mundos - retornando um Iterável (para uma sintaxe mais agradável), mesmo quando a sequência de dados subjacente é única.
O truque é retornar uma implementação anônima do Iterable que realmente aciona o trabalho. Portanto, em vez de fazer o trabalho que gera uma sequência pontual e, em seguida, retornar um Iterator sobre isso, você retorna um Iterable que, cada vez que é acessado, refaz o trabalho. Isso pode parecer um desperdício, mas muitas vezes você chamará o Iterable de qualquer maneira e, mesmo que o chame várias vezes, ele ainda terá uma semântica razoável (ao contrário de um invólucro simples que faz com que um Iterador "pareça" um Iterável, isso é válido ' t falhar se usado duas vezes).
Por exemplo, digamos que eu tenho um DAO que fornece uma série de objetos de um banco de dados e desejo fornecer acesso a ele por meio de um iterador (por exemplo, para evitar a criação de todos os objetos na memória, se não forem necessários). Agora eu poderia simplesmente retornar um iterador, mas isso torna feio o uso do valor retornado. Então, em vez disso, envolvo tudo em um Iterable anon:
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();
}
};
}
}
isso pode ser usado em código como este:
class DaoUser {
private MetricDao dao;
for (Metric existing : dao.loadAll()) {
// do stuff here...
}
}
o que me permite usar o loop for compacto, mantendo o uso incremental de memória.
Essa abordagem é "preguiçosa" - o trabalho não é feito quando o Iterable é solicitado, mas somente mais tarde quando o conteúdo é repetido - e você precisa estar ciente das consequências disso. No exemplo com um DAO, isso significa iterar sobre os resultados na transação do banco de dados.
Portanto, existem várias advertências, mas isso ainda pode ser um idioma útil em muitos casos.