1

I work on a Java application.
There is a Getter that corresponds to a integer field (score).
My goal is to calculate the average on that field. I decided to make an array, then to caculate the count and the sum of that array.
But I'm really getting stuck in both that Java syntax and "state of mind"..

Here is my snippet :

    public void setPersonData2(List<Person> persons2) {
        // Try to make a count of the array
        int[] scoreCounter = new int[100]; // 100 is by default since we don't know the number of values
        for (Person p : persons2) {
            int score = p.getScoreTheo(); // Getter
            Arrays.fill(scoreCounter, score);
            // Try to delete all values equal to zero
            int[] scoreCounter2 = IntStream.of(scoreCounter).filter(i -> i != 0).toArray();
            // Calculate count
            int test = scoreCounter2.length;
            System.out.println(test);
        } 
}

Could you help me ?

Julien
  • 45
  • 1
  • 3
  • 15
  • 2
    For the state of mind part : don't rush into writing code, first do it by hand. Find what algorithm you need to use and what variables it's based on. – Aaron Oct 24 '19 at 14:47
  • Can't understand you. You want to calculate the average of score in the list? What about this: https://stackoverflow.com/a/10791597/379173 – Enrico Giurin Oct 24 '19 at 14:50
  • As a side note the standard plural of "person" is "people", not "persons" (which is used in legislative lingo and a few other specific contexts) – Aaron Oct 24 '19 at 15:17

3 Answers3

4

Why is it too complex to calculate the simple average? Moreover, I don't understand why you need array whatsoever.

int count = 0;
int sum = 0;
for (Person p : persons2) {
   ++count;
   sum += p.getScoreTheo();
}

double average = sum / (double)count;
2

Using streams :

public void setPersonData2(List<Person> persons2) {
    double average = persons2.stream().mapToInt(p -> p.getScoreTheo()).average().getAsDouble();
    //[...]
}

It raises a NoSuchElementException for an empty list.

Aaron
  • 24,009
  • 2
  • 33
  • 57
  • Better to use `persons2.stream().collect(Collectors.averagingInt(Person::getScoreTheo));` which will also not throw an exception. For an empty list the value will be 0.0 – Eritrean Oct 24 '19 at 15:18
  • @Eritrean I find raising an exception is more useful than yielding an incorrect value : an empty collection has no meaningful average. The currently accepted answer raises a ArithmeticsException (division by 0). Plus this is already Thomas Martin's answer – Aaron Oct 24 '19 at 15:19
  • Note that yielding 0 can be useful in some contexts (e.g. are my collection's values "balanced" around 0? there's nothing to balance in an empty collection, seems fair to answer yes), but it will also be harmful in some (e.g. comparing the average value of two collections : does it make sense to say that the empty collection has greater average value than a collection of negative numbers?) – Aaron Oct 24 '19 at 15:23
  • @Aaron no worry about "extraordinary" cases for now, the code is not for ISRO, NASA or JAXA. IMHO, using streams is a good practice as well as its needlessness for an average calculation. The important idea behind it is to have him do comprehend how the procedure makes progress. By the bye, if you need (more) reputation, I have already given it. – Soner from The Ottoman Empire Oct 24 '19 at 15:33
  • we can argue about what makes more sense. But as always the answer will probably be: It depends. – Eritrean Oct 24 '19 at 15:35
  • @snr Note that I find raising an ArithmeticsException is a good thing. Saying this is not something OP should think about seems reductive though. Empty lists happen often enough. As per the stream vs for loop debate I'm glad your answer is the accepted one because OP obviously struggled on the algorithmics part and it should be well understood before using more high-level APIs, but I thought it could be interesting to showcase some API goodies. – Aaron Oct 24 '19 at 15:36
  • @Aaron Let him to run into the problems on his way. I believe it will be best-practice for him. You cannot use Java and its mechanisms like try-catch in a device related to space or defense industry due to being fast. – Soner from The Ottoman Empire Oct 24 '19 at 15:41
1

Stream API has a built-in function to average.

double average = persons2.stream().collect(Collectors.averagingInt(person -> person.getScore()));
Thomas Martin
  • 678
  • 8
  • 19