Montei esse exemplo aqui para exemplificar a ideia que postei antes:
Num primeiro momento, pode parecer muito código apenas para controlar uma lista de pontos por data, mas dependendo do tamanho do sistema, pode trazer grandes benefícios ao evoluir ou corrigir algo. Sem falar que facilita na hora de criar testes unitários.
Qualquer dica para melhorar a ideia no código é sempre muito bem vinda!
public static void main(String[] args) throws Exception {
// Lista de pontos para testes
List<Ponto> pontos = new ArrayList<>();
// Experimente colocar datas diferentes e alterar a ordem dos horários
// O código está preparado para tratar pontos de datas diferentes e manter a ordem do horário do ponto
pontos.add(new Ponto(1, LocalDate.parse("2021-07-01"), LocalTime.parse("08:00"), 1));
pontos.add(new Ponto(2, LocalDate.parse("2021-07-01"), LocalTime.parse("12:00"), 1));
pontos.add(new Ponto(3, LocalDate.parse("2021-07-01"), LocalTime.parse("14:00"), 1));
pontos.add(new Ponto(4, LocalDate.parse("2021-07-01"), LocalTime.parse("18:00"), 1));
PontoDiaFactory pontoDiaFactory = new PontoDiaFactory();
PontoDia pontoDia = pontoDiaFactory.create(pontos);
// Esse é um exemplo de método utilitário que foi abstraído na classe PontoDia
// além dele, vc pode criar outros que possam ser úteis ao manipular os pontos de um determinado dia
System.out.println(pontoDia.getData() + " -> " + pontoDia.getHorariosAsText());
}
/**
* Classe responsáve apenas por criar o ponto de dia, deixando essa lógica de criação separada
* Essa lógica poderia ser dentro da própria classe PontoDia, se preferir
*/
static class PontoDiaFactory {
public PontoDia create(List<Ponto> pontos) {
Map<LocalDate,List<Ponto>> map = pontos.stream().collect(groupingBy(Ponto::getDataPonto));
if (map.size() > 1) {
throw new IllegalStateException("Não é possível criar um ponto do dia para pontos de datas diferentes: " + map.keySet());
}
Map.Entry<LocalDate, List<Ponto>> entry = map.entrySet().iterator().next();
return new PontoDia(entry.getKey(), entry.getValue());
}
}
/**
* Classe que representa os pontos de um determinado dia
*/
static class PontoDia {
private final LocalDate data;
private final List<Ponto> pontos;
public PontoDia(LocalDate data, List<Ponto> pontos) {
this.data = data;
this.pontos = pontos;
this.pontos.sort(Comparator.comparing(Ponto::getHoraPonto));
}
public LocalDate getData() {
return data;
}
public List<Ponto> getPontos() {
return pontos;
}
public String getHorariosAsText() {
return pontos.stream().map(p -> p.getHoraPonto().toString()).collect(Collectors.joining(", "));
}
}
/**
* Classe ponto que é uma entidade que representa a tabela Ponto do banco
*/
static class Ponto {
private final int idPonto;
private final LocalDate dataPonto;
private final LocalTime horaPonto;
private final int pisPonto;
public Ponto(int idPonto, LocalDate dataPonto, LocalTime horaPonto, int pisPonto) {
this.idPonto = idPonto;
this.dataPonto = dataPonto;
this.horaPonto = horaPonto;
this.pisPonto = pisPonto;
}
public int getIdPonto() {
return idPonto;
}
public LocalDate getDataPonto() {
return dataPonto;
}
public LocalTime getHoraPonto() {
return horaPonto;
}
public int getPisPonto() {
return pisPonto;
}
}