In the RangeData class I create an iterator, but how does it work?
Your explanation is exactly what it does:
I have read in the documentation that the hasnext returns true if there is a next element in the iterator and the next one returns the next element
That is hasNext
has to evaluate if it is already on the end date and next
has to return and move forward on the day. It is also important to realize how this fits with a foreach
normal. Looking at for example:
for (Data x : new RangeData(d[2], d[1]))
Internally Java will get the iterator returned by RangeData
and call next()
to get the value for x
on all iterations of for
. And it only ends for
when hasNext()
of that same iterator returns false
.
But how do I populate the iterator with these dates?
You will need to save the start and end dates you received in the constructor within the RangedData
class and use them in the iterator created within it. The iterator will be responsible for moving forward day by day and returning the appropriate day.
Example:
public class RangeData implements Iterable<Data>{
private Data inicio;
private Data fim;
public RangeData(Data inicio, Data fim) {
this.inicio = inicio;
this.fim = fim;
}
@Override
public Iterator<Data> iterator() {
return new Iterator<>() {
//data corrente do iterador começa como a data de inicio da RangeData
Data corrente = inicio;
@Override
public boolean hasNext() {
//se já chegou ao fim ou não. Tem próximo se a data corrente
//for menor ou igual à data de fim
return corrente.menorOuIgual(fim);
}
@Override
public Data next() {
Data atual = corrente; //data a devolver, a atual
corrente = corrente.proximoDia(); //corrente avança 1 dia
return atual;
}
};
}
}
Now we have to implement the menorOuIgual
and proximoDia
methods used in the iterator I exemplified above. For simplicity and even because the focus of the question is not this, consider the following implementation ( proximoDia
is not correct but serves to exemplify):
public class Data {
private int dia;
private int mes;
private int ano;
public Data(){ //para que o código que tinha não deixe de funcionar
}
public Data(int dia, int mes, int ano){
setData(dia, mes, ano);
}
public void setData(int dia, int mes, int ano){
this.dia = dia;
this.mes = mes;
this.ano = ano;
}
public boolean menorOuIgual(Data data) {
return ano < data.ano ||
(ano == data.ano && mes < data.mes) ||
(ano == data.ano && mes == data.mes && dia <= data.dia);
}
public Data proximoDia(){
//não está correto, mas exemplifica para as duas datas da pergunta
return new Data(dia + 1, mes, ano);
}
@Override
public String toString() { //para que o System.out que tem no main funcione
return String.format("%02d/%02d/%d",dia, mes, ano);
}
}
With this your main
will already work.
Output:
03/03/2006
04/03/2006
05/03/2006
06/03/2006
07/03/2006
08/03/2006
09/03/2006
10/03/2006
11/03/2006
12/03/2006
View execution on Ideone
As a small aside, I advise you to simplify the construction of dates in main
, using a constructor (the one I've exemplified) that receives the values you want directly instead of having to setData
for each date individually. / p>