How to loop through every row, calculate difference and then average everything?

Viewed 77

I have a model called Client that has these info :

private Long int;
@OneToMany(mappedBy = "client", cascade = CascadeType.ALL)        
private List<Results> results;

and The model Results has these info :

@ManyToOne
@JoinColumn(name='client_id') 
private Client client;
@OneToOne
private Scores score;
private Date submittedDate;

What I'm trying to achieve is this :

For every user get the score of their first result and the score of their last result, find the difference. And then average out everyone's differences. How do I write this function that calculates it?

The Client returns a list of all results, and then for difference : results[last] - results[0] and then a loop :

for (int i=0; i <= client.count(); i++)
    difference = results[last] - results[0];
    sum += difference;
    average = sum/client.count();`

I just have difficulty into turning this into code that works in Spring. Do I write this in the ClientServiceImplementation and then have the queries in ClientRepository ? Any help is appreciated!!!

the Score class has :

  private Long id;
  private Double score;
1 Answers

You could do something like this:

List<Client> clients = clientRepository.findAll();

Double meanDiff = clients.stream()
    .map(client -> {
        List<Result> results = client.getResults();
        if (results.size() >= 2) {
            Score first = results.get(0);
            Score last = results.get(results.size() - 1);
            return last.value - first.value;
        } else {
           return 0.0;
        }
    })
    .collect(Collectors.averagingDouble(it -> it));

Note: you did not specify what is the Score class, so I assumed it has a value field of type Double.

Update: this is another example but ignoring clients with numberOfResults < 2:

Double meanDiff = clients.stream()
    .map(client -> client.getResults())
    .filter(results -> results.size() >= 2) // <-- keep these only
    .map(results -> {
        Score first = results.get(0);
        Score last = results.get(results.size() - 1);
        return last.value - first.value;
    })
    .collect(Collectors.averagingDouble(it -> it));
Related