In the Rangedata class I create an iterator, but how it works?
Your explanation is exactly what you do:
I’ve read in the documentation that hasnext returns true if there is a next element in the iterator and next returns the next element
That is to say hasNext
has to assess whether it is already at the final date and the next
has to return and advance on the day. It is also important to understand how this fits with a foreach
normal. Looking for example at:
for (Data x : new RangeData(d[2], d[1]))
Internally Java will get the iterator returned by RangeData
and call next()
to obtain the value for x
in all iterations of for
. And just ends the for
when the hasNext()
of that same iterator return false
.
but how I fill the iterator with those dates ?
You will need to store the initial and final date received in the constructor within the class RangedData
and uses them in the iterator created within it. The iterator will be responsible for moving forward day by day and return 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 need to implement the methods menorOuIgual
and proximoDia
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.
Exit:
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 in Ideone
As a small aside, I advise to simplify the construction of the dates in the main
, using a constructor (the one I exemplified) that receives the values you want directly instead of having to do setData
for each date individually.
The
RangeData
would spend each day between the two chosen dates ? Your classData
is implemented by hand or is based on the implementation ofDate
and derivatives ?– Isac
Exactly that, Rangedata will go through every day between the two, and my date class is implemented by hand even, it simply tests whether the date exists taking into account leap year, amount of days of each month and such things.
– pksasso