Olive Bassey Olive Bassey - 4 months ago 42
Java Question

ArrayList Calculate Average by dropping Smallest

I have two problems with my code. 1) It's not giving me the right average when I add values to my arraylist so I know my condition in my for loop is off and 2) It's not showing all the numbers in my arrayList. It specifically doesn't show the 0th integer.

Here is my code:

public class CalcAvgDropSmallest {

public static void main(String[] args) {
int lowNum = 0; // # of the lowest numbers to be dropped
double average; // calcuates the mean of the sum and the lowest numbers dropped
ArrayList<Double> inputs= getALInfo();
lowNum = getLowestnum();
average = calculateAvg(inputs, lowNum);
getAvg(inputs, lowNum, average);

}

public static ArrayList<Double> getALInfo() {
ArrayList<Double> inputs = new ArrayList<Double>();

// Read Inputs
Scanner in = new Scanner(System.in);
System.out.println("Please enter 5 - 10 integers, Q to quit: ");
Double vals = in.nextDouble();

while (in.hasNextDouble())
{
inputs.add(in.nextDouble());
}

return inputs;
}

public static int getLowestnum() {
int lowNum = 0;

// Reads Input value for # of lowest values dropped

System.out.println("How many of the lowest values should be dropped?");
Scanner in = new Scanner(System.in);
lowNum = in.nextInt();

return lowNum;

}

public static double calculateAvg(ArrayList<Double> inputs, int lowNum) {
double sum = 0;
double average = 0;
int i = 0;
// Calcuates the average of the array list with the lowest numbers dropped

for (i = 0; i < inputs.size(); i++)
{
if (inputs.get(i) > lowNum) {
sum = sum + inputs.get(i);
}
}
average = (sum / inputs.size());

return average;
}

public static void getAvg(ArrayList<Double> inputs,int n, double average) {
// It's adding all the values and dividing by the size of it, which is a problem
// Also, it's not showing the 0th integer aand just straight to the 1st integer
System.out.println("The average of the numbers " + inputs + " except the lowest " +n+ " is " +average);
}


}

Answer

First, please program to the List interface (instead of the ArrayList concrete type). Second, you should make sure you add each value you read to your List. Then, make sure you read the terminating value (and discard it); otherwise it will be pending in the buffer. Finally, I would pass the Scanner into the methods (instead of re-declaring it locally). Like,

public static List<Double> getALInfo(Scanner in) {
    List<Double> inputs = new ArrayList<>();
    System.out.println("Please enter 5 - 10 integers, Q to quit: ");
    while (in.hasNextDouble()) {
        inputs.add(in.nextDouble());
    }
    in.next();
    return inputs;
}

You could simplify getLowestnum like

public static int getLowestnum(Scanner in) {
    System.out.println("How many of the lowest values should be dropped?");
    return in.nextInt();
}

Then your calculateAvg should sort the List and take a subList (discarding lowNum values) and finally return the average. Something like,

public static double calculateAvg(List<Double> inputs, int lowNum) {
    Collections.sort(inputs);
    return inputs.subList(lowNum, inputs.size()).stream()
            .mapToDouble(Double::doubleValue).average().getAsDouble();
}

And then main to complete the example

public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    List<Double> inputs = getALInfo(in);
    int lowNum = getLowestnum(in);
    double average = calculateAvg(inputs, lowNum);
    System.out.printf("%.2f%n", average);
}
Comments