Olá pessoal, bom dia !
Estou com um problema de lógica.
É o seguinte, tenho uma lista de ControleCombustivel
public class ControleCombustivel {
private long idControle;
private Equipamento placa;
private LocalDateTime data;
private double litros;
private double quilometragem;
private BigDecimal valorUnitario;
/*... Getters e Setters ...*/
}
Dado uma lista de ControleCombustivel, tenho que montar um gráfico que mostra a média de consumo por registro, por dia, por mês e etc.
Por registro eu consegui implementar
public class MediaPorRegistro implements IndicadorMediaCombustivel{
public List<Media> calcula(List<ControleCombustivel> lista) {
List<Media> media = new ArrayList<Media>();
for (int i = 0; i < lista.size(); i++) {
double kmAnterior = i == 0 ? 0 : lista.get(i-1).getQuilometragem();
double km = lista.get(i).getQuilometragem() - kmAnterior;
double m = km / lista.get(i).getLitros();
media.add(new Media(lista.get(i).getData(), m));
}
return media;
}
}
Já a média por dia, eu não consegui. E é justamente nela que estou com problemas.
Comecei implementando da seguinte maneira
public class MediaPorDia implements IndicadorMediaCombustivel {
public List<Media> calcula(List<ControleCombustivel> lista) {
List<Media> media = new ArrayList<Media>();
LocalDateTime dataInicial = lista.get(0).getData();
double somaKM = 0;
double somaLITRO = 0;
for (int i = 0; i < lista.size(); i++) {
ControleCombustivel cc = lista.get(i);
if(dataInicial.getDayOfYear() == cc.getData().getDayOfYear()){
somaKM += cc.getQuilometragem();
if(i > 1){
somaLITRO += cc.getLitros();
}
if(i == 0 && cc.getData().getDayOfYear() != lista.get(i+1).getData().getDayOfYear()){
double m = somaKM / somaLITRO;
media.add(new Media(cc.getData(), m));
dataInicial = cc.getData();
}
}else{
double m = somaKM / somaLITRO;
media.add(new Media(cc.getData(), m));
dataInicial = cc.getData();
}
}
return media;
}
}
Escrevi 3 testes, e 2 deles não passaram.
Se eu passo uma lista com 3 objetos, ele retorna 3 objetos na lista.
Mas, se eu passo 1 objeto o JUnit aponta java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
E, se eu passo 2 objetos, ele me retorna 10 :shock:
public class MediaPorDiaTest {
/* Não passa, retorna IndexOutOfBoundsException */
@Test
public void testaMediaComUmItem(){
List<ControleCombustivel> lista = new ArrayList<ControleCombustivel>();
LocalDateTime d = new LocalDateTime();
ControleCombustivel cc = new ControleCombustivel();
cc.setData(d);
cc.setLitros(10);
cc.setQuilometragem(1);
lista.add(cc);
List<Media> media = new MediaPorDia().calcula(lista);
assertEquals(1, media.size());
}
/* Não passa, retorna 10, ao invés de 2 */
@Test
public void testaMediaComDoisItens(){
List<ControleCombustivel> lista = new ArrayList<ControleCombustivel>();
LocalDateTime d = new LocalDateTime();
for (int i = 1; i <= 10; i++) {
ControleCombustivel cc = new ControleCombustivel();
cc.setData(d.plusDays(i));
cc.setLitros(10);
cc.setQuilometragem(i+1);
lista.add(cc);
}
List<Media> media = new MediaPorDia().calcula(lista);
assertEquals(2, media.size());
}
/* Passa */
@Test
public void testaMediaComTresItens(){
List<ControleCombustivel> lista = new ArrayList<ControleCombustivel>();
LocalDateTime d = new LocalDateTime();
for (int i = 1; i <= 3; i++) {
ControleCombustivel cc = new ControleCombustivel();
cc.setData(d.plusDays(i));
cc.setLitros(10);
cc.setQuilometragem(i+1);
lista.add(cc);
}
List<Media> media = new MediaPorDia().calcula(lista);
assertEquals(3, media.size());
}
}
Com o JodaTime tem alguma maneira mais simples de implementar isso ?
Ou então, alguém pode me ajudar com esse algoritmo ?
Desde já agradeço!