Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to prevent division by zero without handling exception java

I have two classes: Student and University.

public class University {

private String name;
private List<Student> students;

public University(String name) {    
    this.name = name;
    this.students = new ArrayList<Student>();
}

and there is a function to calculate the average score:

 public double average() {
    double average = 0;

    for(Student st: students) {
        average += st.getKnowledge();
    }

    try { 
        return average/students.size();
    }
    catch(ArithmeticException e) {
        System.out.println("Oops, there is no student studying");
        return 0.0;
    }
}

So if there is no students in the list, i get division by zero which i tried to handle with a try\catch block. And I wonder if there is any way to simplify this checking in order to avoid the try catch block? Of course, I could implement it like this:

public double average() {
    double average = 0;

    for(Student st: students) {
        average += st.getKnowledge();
    }

    if (students.size() == 0) 
        throw new IllegalArgumentException("Oops, there is no student studying");

    return average/students.size();
}

either

if (students.size() == 0) 
        System.out.println(""Oops, there is no student studying"");

Or probably there is no point in checking it because if students list is empty then it simply wont enter the loop?

I know the question is easy but I am only styudying so I'd like to know in the future which way is better to pick. And also perhaps there is a hidden problem or something? with boundaris values or whatever?

thanks in advance.


2 Answers

That's why if statements are there. Don't restrain yourselves from using them :) And the best would be to check in the beginning of the method. Something like:

public double average() {
    if(students.isEmpty())
        return 0.0;

    double average = 0;

    for(Student st: students) {
        average += st.getKnowledge();
    }            
    return average/students.size();
}

And if you want a fancier way to do it with streams you can do:

private double average(List<Student> students) {
    return students.stream()
            .mapToDouble(Student::getKnowledge)
            .average()
            .orElse(0.0);
}
like image 71
Veselin Davidov Avatar answered Nov 04 '25 18:11

Veselin Davidov


Another solution is to use summary statistics. https://docs.oracle.com/javase/8/docs/api/java/util/DoubleSummaryStatistics.html Additionally to average, it contains information about min, max, total values, their sum. It is widely used, if you need several summary values, but you don't want to make several streams of your collection:

public static double average() {
    return students.stream()
            .mapToDouble(Student::getKnowledge)
            .summaryStatistics()
            .getAverage();
}

It will return 0.0 by default, if your collection is empty.

It is faster if you need several summary values, but slower if you need only one.

like image 31
Dmitrii Cheremisin Avatar answered Nov 04 '25 19:11

Dmitrii Cheremisin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!