简体   繁体   中英

How to find the average number in an array that has already been constructed

How could I write a method that returns the average weight of an array boxes. Assume that the array boxes has been constructed. Also can not assume that every element of the array has been constructed. If the array is empty the method should return 0.0. This is what I have at the moment but I am very lost.

public class Question03 {
    //The array of boxes to be used by the method "getAverageWeight()"
    //This property is public for testing purposes
    public Box[] boxes;
    
    public double getAverageWeight()
    {
        int h = boxes.length;
        double avg = 0.0;
        for(int i = 0;i<boxes.length;i++)
        {
            if(boxes[i] == null)
            {
                h--;
            }
        }
        return avg;
    }
}

Very easy if your using streams. average() returns an OptionalDouble so you can provide a default if the array is empty.

Box[] boxes =
        { new Box(10), new Box(20), null, null, new Box(30) };

double avg = Arrays.stream(boxes).filter(obj -> obj != null)
        .mapToDouble(Box::getWeight).average().orElse(0.);
System.out.println("Avg weight = " + avg);

Prints

Avg weight = 20.0

or more traditonally

double sum = 0;
int count = 0;
for (Box b : boxes) {
   if (b != null) {
      sum += b.getWeight();
      count++;
    }
}    
System.out.println("Avg weight = " + (sum/count));

Prints

Avg weight = 20.0

"Continue" if its not constructed and make sure that you sum the weights

Then you can simple return sum of all weights devided by the number of constructed boxes

I would also suggest that you make sure to avoid devide by 0 -> simple add check if h==0 and return 0 instead

public double getAverageWeight()
    {
        
        
        int h = boxes.length;
        double sumWeight=0.0;
        for(int i = 0;i<boxes.length;i++)
        {
            if(boxes[i] == null)
            {
                h--;
                continue;
            }
            sumWeight+=boxes[i].getWeight();
        }

        return sumWeight/h;
    }

if you prefer working with Streams over Loops, then this would be working implementation:

public double getAverageWeight(Box[] boxes) {

    Collection<Box> noNulls = Arrays.stream(boxes)
                                    .filter(b -> b != null)
                                    .collect(Collectors.toList());

    if (noNulls.isEmpty()) {
        return 0.0d;
    }
    
    double sum = noNulls.stream().map(b -> b.getWeight()).reduce(0.0d, (a,b) -> a+b);
    return sum / noNulls.size();
}

You can do it as follows:

  1. Return 0 if the array is null or empty.
  2. Initialize a variable (eg h in the code shown below) equal to the length of the array and another (eg sum in the code shown below) equal to 0 . Use the variable, h to keep track of non-null elements while sum to collect the weight of all non-null elements.
  3. While navigating the array, replace a null element with an instance of Box .
  4. Finally, return the average as sum / h .

Demo:

public double getAverageWeight() {
    // If the array is empty the method should return 0.0. 
    if(boxes == null || boxes.length == 0) {
        return 0;
    }

    double sum = 0;
    int h = boxes.length;
    for(int i = 0; i < boxes.length; i++) {
        if(boxes[i] != null) {
            sum += boxes[i].weight;// Add the weight of each box to sum
        } else {
            boxes[i] = new Box();// Replace the null element with a Box object
            h--;
        }
    }

    // Return the average by dividing the sum by the count of boxes
    return sum / h;
}

The shortest solution would be to use Streams

double avg = Arrays.stream(boxes)
    .filter(Objects::nonNull)
    .mapToDouble(Box::getWeight)
    .average()
    .orElse(0);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM