Java - how to return two values from one method?

I need to have both high and low returned by this method below. But on the second for I’m getting the error “Unreachable statement”. Is that because after the first return it disregards everything after that? How can I get both values returned then? Thanks.

    public double getRainAt(int e) {
        double[] thisYear = {1.6, 2.1, 1.7, 3.5, 2.6, 3.7, 3.9, 2.6, 2.9, 4.3, 2.4, 3.7};
        double high = thisYear[0];
        double low = thisYear[0];

        for (int i = 0; i < thisYear.length; i++) {
            if (thisYear[i] > high) {
                high = thisYear[i];
            }
        }
        return high;

        for (int i = 0; i < thisYear.length; i++) {
            if (thisYear[i] <= low) {
                low = thisYear[i];
            }
        }
        return low;

You can only return from a function once. You need to return both values at the same time.

1 Like

Here’s what I just tried. The return statements are just my idea of what I wish were possible. Everything I’ve seen from googling says to use an array or some other means that is sort of beyond me at this point. Is there not a simpler way?

  public double getRainAt(int e) {
        double[] thisYear = {1.6, 2.1, 1.7, 3.5, 2.6, 3.7, 3.9, 2.6, 2.9, 4.3, 2.4, 3.7};
        double high = thisYear[0];
        double low = thisYear[0];

        for (int i = 0; i < thisYear.length; i++) {
            if (thisYear[i] > high) {
                high = thisYear[i];
            }
            if (thisYear[i] <= low) {
                low = thisYear[i];
            }
        }
        return high,return low;
    }

No, you can only return one value from a function. Once a return statement is reached the function is stopped. So that second return will never execute. I’m sure there are several ways to do what you want to do.

3 Likes

Returning them in (say) an array is a simpler way. How do you handle a function that returns two discrete things?

I realise it may seem simpler at this point to you, but in reality it doesn’t make sense. Note that there are languages that appear to allow multiple return values (Python for example), but they are just returning an array/tuple/similar thing

3 Likes

Below is the bit of code where the “high” and “low” values from the returns previously mentioned are getting called, r.getRainAt(high) and r.getRainAt(low). This is in the Main class. The method getRainAt is in a different class. I’m not allowed to change anything in the Main.java.

I should have mentioned that earlier, but does that change anything? Would one of the approaches in the references below still work?

https://www.baeldung.com/java-method-return-multiple-values

https://www.techiedelight.com/return-multiple-values-method-java/

   // Get and display the month with the highest rainfall.
        high = r.getHighestMonth();
        System.out.println(
                "The month with the highest amount of rain " + "is " + (high + 1) + " with "
                        + r.getRainAt(high) + " inches.");

        // Get and display the month with the lowest rainfall.
        low = r.getLowestMonth();
        System.out.println(
                "The month with the lowest amount of rain " + "is " + (low + 1) + " with "
                        + r.getRainAt(low) + " inches.");

I have tested getRainAt with separate if statements and made sure that they both worked to return the right element value to getRainAt(high) and getRainAt(low) when I returned each one at a time.

This code snippit makes it look like your getRainAt should be doing something completely different that what you are currently doing.

Where are you using e? An unused parameter is a sign that something is wrong.

This is the UML we were given to get us started:

It looked to me like the “e” was just the parameter. I was also not sure why it was there. But I have kind of ignored it since I just thought the parameter in the method definition is more or less just a place holder until an argument is used when the method gets called.

I suspect that you are not supposed to duplicate the work of getHighestMonth and getLowestMonth in getRainAt. I would assume that getRainAt should just get the amount of rainfall for a specific month.

I don’t know that I’m duplicating them. The getRainAt method is getting the rainfall amount for the month with highest/lowest amount. Here is my output so far when I only return “high” or “low” from getRainAt. It is all working except that I cannot return both “high” and “low”:

returning “high”:

returning “low”:

You are definitely repeating the work of finding the month with the highest or lowest rainfall.
I would assume that

month = 0; // or whatever in [0, 11]
month_rain = r.getRainAt(month);

should return the rainfall for the given month. Behavior should agree with the function name.


Also, why are you hard-coding thisYear? I would assume as you have written it that Rainfall is a type and that holds an array of doubles and you should be using this array inside the methods getTotalRainFall, getAverageRainFall, getHighestMonth, getLowestMonth, and getRainAt.

thisYear was used in Main so I just kept using it to get my Methods something to use. In the comments at the bottom of Main, the professor said not to change “RainfallDemo.java”. He renamed the Main class that for some reason. I still have it named Main because I’m using IntelliJ first rather than his replit. I’ll paste it into there when/if I get it to work all the way. Rainfall is a class that he said to create.

Please post your actual code instead of pictures. The pictures are very difficult for me to read.


I think that you have fundamentally missed the boat here on how this should work.

  1. Your constructor should store the annual rainfall data that is passed in as an array. You are doing this but never using the stored data.

  2. You should never hardcode an array in multiple places in your code. You don’t need to hard code anything.

  3. Your other methods on your object should use the annual rainfall data array that was passed into the constructor.

  4. Your getRainAt should not find the month of lowest or highest rainfall. It should instead just lookup (from the stored rainfall array) the amount of rainfall in the given month.

Here’s Main.java (same as professor’s “RainfallDemo.java”):

package academy.learnprogramming;

public class Main {
    public static void main(String[] args) {
        // Array with this year's rainfall data
        double[] thisYear = { 1.6, 2.1, 1.7, 3.5, 2.6, 3.7, 3.9, 2.6, 2.9, 4.3, 2.4, 3.7 };

        int high; // To hold the month with the highest amount
        int low; // To hold the month with the lowest amount

        // Create a Rainfall object initialized with
        // this year's data.
        Rainfall r = new Rainfall(thisYear);

        // Display the total rainfall.
        System.out.println("The total rainfall for this year is " + r.getTotalRainFall() );

       // Display the average rainfall.
        System.out.println("The average rainfall for this year is " + r.getAverageRainFall() );

        // Get and display the month with the highest rainfall.
        high = r.getHighestMonth();
        System.out.println(
                "The month with the highest amount of rain " + "is " + (high + 1) + " with "
                        + r.getRainAt(high) + " inches.");

        // Get and display the month with the lowest rainfall.
        low = r.getLowestMonth();
        System.out.println(
                "The month with the lowest amount of rain " + "is " + (low + 1) + " with "
                        + r.getRainAt(low) + " inches.");

    }
}


//    DO NOT MAKE ANY CHANGES TO RainfallDemo.java!!!!!!!!! This project uses .replit and run_button.sh
//    to configure RainfallDemo.java instead of RainfallDemo.java. When clicking the Run button it will run
//    RainfallDemo.java.
//
//        Write a Rainfall.java class that stores the total rainfall for each of 12 months into an array
//        of doubles. The program should have methods that return the following:
//
//        total rainfall for the year
//        the average monthly rainfall
//        the month with the most rain
//        the month with the least rain
//        return the amount of rain given the index number for the month.
//        total rainfall for the year
//        the average monthly rainfall
//        the month with the most rain
//        the month with the least rain
//        return the amount of rain given the index number for the month.
//
//        Demonstrate the class in a complete program called RainfallDemo.java.
//
//        Input Validation: Do not accept negative numbers for monthly rainfall figures.
//
//        Hint: The UML file image may help when building your class file.
//
//        Make sure you include a comment block at the top of your code with the following information:
//        Your name Date Project name a brief description of what the file does
//
//        Submit as described.

Here’s Rainfall.java:

package academy.learnprogramming;

public class Rainfall {
    private double[] rain;

    public Rainfall(double[] r) {  // This is a constructor.
        this.rain = r;
    }

    public double getTotalRainFall() {  // This and those below are methods.
        double[] thisYear = {1.6, 2.1, 1.7, 3.5, 2.6, 3.7, 3.9, 2.6, 2.9, 4.3, 2.4, 3.7};
        double sum = 0;
        for (int i = 0; i < thisYear.length; i++) {
            sum += thisYear[i];
        }
        return sum;
    }

    public double getAverageRainFall() {
        double[] thisYear = {1.6, 2.1, 1.7, 3.5, 2.6, 3.7, 3.9, 2.6, 2.9, 4.3, 2.4, 3.7};
        double sum = 0;
        for (int i = 0; i < thisYear.length; i++) {
            sum += thisYear[i];
        }
        return sum / (double) thisYear.length;
    }


    public int getHighestMonth() {
        double[] thisYear = {1.6, 2.1, 1.7, 3.5, 2.6, 3.7, 3.9, 2.6, 2.9, 4.3, 2.4, 3.7};
        int max = 1;

        for (int i = 0; i < thisYear.length; i++) {
            if (thisYear[i] > thisYear[max]) max = i;
        }
        return max;
    }


    public int getLowestMonth() {
        double[] thisYear = {1.6, 2.1, 1.7, 3.5, 2.6, 3.7, 3.9, 2.6, 2.9, 4.3, 2.4, 3.7};
        int min = 1;

        for (int i = 0; i < thisYear.length; i++) {
            if (thisYear[i] < thisYear[min]) min = i;
        }
        return min;
    }


    public double getRainAt(int e) {
        double[] thisYear = {1.6, 2.1, 1.7, 3.5, 2.6, 3.7, 3.9, 2.6, 2.9, 4.3, 2.4, 3.7};
        double high = thisYear[0];
        double low = thisYear[0];

        for (int i = 0; i < thisYear.length; i++) {
            if (thisYear[i] > high) {
                high = thisYear[i];
            }
            if (thisYear[i] <= low) {
                low = thisYear[i];
            }
        }
        return low;
    }

}
1 Like

These lines should not be in your methods.

This is what your getRainAt method should do.

When I remove those, I get errors at all mentions of thisYear saying "Cannot resolve symbol thisYear". I know it’s because the Rainfall class can’t “see” thisYear in the Main class. But I don’t what to do about that. I have read to use a getter. But the only getter available is for the rain[] declared at the beginning of Rainfall. I have no clue. I can’t do this.

In the constructor here, you set some internal data.

Here you call the constructor and pass in thisYear to be the data that is saved internally.

So, in order to use thisYear inside of your methods, you need to reference this.rain.

I appreciate the help. I just emailed my professor. I told him I don’t even care about the points anymore - I just need to know how to get it to work. I will understand it after I can actually see the solution.

Reading the solution unfortunately doesn’t teach you how to make the solution on your own. I get that this is frustrating, but we’re here if you want to work towards the answer.