Java- Printing an Original Array while Performing Operations on an Array Copy

Join the discussion
Ask a follow-up here, or get your own question answered by working scientists, mathematicians and engineers — people, not an autocomplete.
Real named experts · corrections over time · the nuance an AI answer skips
4 replies · 3K views
smilesofmiles
Messages
18
Reaction score
0
Hello mathhelpboards community! Please help! Thank you. :-)

I need my code to print out the user's original array that is to say the numbers in the way the user entered them. I tried making a copy of the original array and then did all of the arithmetic on it. I sorted the array copy in another method and used it to find the averages. I expected that this would allow me to keep the original numbers in tact. However, when I call the last method PrintResults to print the original array I get back the sorted array (the array copy). How do I fix this?:confused:
Code:
package calcavgdropsmallest;import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Collections;
import java.util.List;

public class CalcAvgDropSmallest {
    
   private static DecimalFormat df2 = new DecimalFormat(".00");

   public static ArrayList<Double> getArrayNumbers(){
       Scanner input = new Scanner(System.in);
       
       System.out.println("Please enter five to ten numbers separated by spaces on one line.");
       
       ArrayList<Double> userNumbers = new ArrayList<>();
       ArrayList<Double> numCopy = new ArrayList<>(userNumbers); //Created a copy of the array.
       
       String numbers = input.nextLine();
       String[] strHolder = numbers.split("\\s+"); 
       
       for(int counter = 0; counter < strHolder.length; counter++){
           userNumbers.add(counter, Double.parseDouble(strHolder[counter])); //Adding numbers to the array
        } 
       
       return userNumbers;
    }
   
   public static int getLowestNumber(){
       Scanner input = new Scanner(System.in);
       System.out.println("Please enter the amount of lowest numbers to drop."); 
       int n = input.nextInt();
       
       return n;
    }
  
   public static double calculateAverage(ArrayList<Double> numCopy, int n){
       double average;
       double sum = 0;
       
       Collections.sort(numCopy, Collections.reverseOrder()); //Sorting the array list in reverse.
       
       for(int counter = 0; counter < numCopy.size() - n; counter++){ 
           
                sum = sum + numCopy.get(counter);
        }
       
       average = sum / (numCopy.size() - n); //Finding the average of the array copy
       
       return average;
    }
  
   public static void printResults(ArrayList<Double> userNumbers, double average, int n){
       
      System.out.print("Given the numbers ");
                   
      for(int counter = 0; counter < userNumbers.size(); counter++){ //This should print out the original array.
          
           if(counter == userNumbers.size() - 1 ){ 
              System.out.print("and " + userNumbers.get(counter) + ", " );      
            }
           else{ 
              System.out.print(df2.format(userNumbers.get(counter)) + ", ");
            }
        }

      System.out.println("the average of all the numbers except the lowest " + n + " is " + df2.format(average) + ".");
         
    }
 
   public static void main(String args[]){
       
       ArrayList<Double> userNumbers = getArrayNumbers();
       int n = getLowestNumber();
       double average = calculateAverage(userNumbers, n);
       printResults(userNumbers, average, n);
       
    }
}
 
on Phys.org
numCopy = new ArrayList<>(userNumbers)

This does not make a deep copy. The numCopy still references the original ArrayList. To make a deep copy add the elements to both arrays separately.
 
Okay, I added elements to the second array. Is there something I'm missing? The program still won't display the original numbers. Thank you for the response!
Code:
package calcavgdropsmallest;import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Collections;

public class CalcAvgDropSmallest {
    
   private static DecimalFormat df2 = new DecimalFormat(".00");

   public static ArrayList<Double> getArrayNumbers(){
       Scanner input = new Scanner(System.in);
       
       System.out.println("Please enter five to ten numbers separated by spaces on one line.");
       
       ArrayList<Double> userNumbers = new ArrayList<>();
       ArrayList<Double> numCopy = new ArrayList<>(userNumbers); //Created a copy of the array.
       
       String numbers = input.nextLine();
       String[] strHolder = numbers.split("\\s+"); 
       
       for(int counter = 0; counter < strHolder.length; counter++){
           userNumbers.add(counter, Double.parseDouble(strHolder[counter])); //Adding numbers to the array
        } 
       for(int i = 0; i < strHolder.length; i++){
           numCopy.add(i, Double.parseDouble(strHolder[i])); //Adding numbers to the array copy
        }       
       
       return numCopy;
    }
   
   public static int getLowestNumber(){
       Scanner input = new Scanner(System.in);
       System.out.println("Please enter the amount of lowest numbers to drop."); 
       int n = input.nextInt();
       
       return n;
    }
  
   public static double calculateAverage(ArrayList<Double> numCopy, int n){
       double average;
       double sum = 0;
       
       Collections.sort(numCopy, Collections.reverseOrder()); //Sorting the array list in reverse.
       
       for(int counter = 0; counter < numCopy.size() - n; counter++){ 
           
                sum = sum + numCopy.get(counter);
        }
       
       average = sum / (numCopy.size() - n); //Finding the average of the array copy
       
       return average;
    }
  
   public static void printResults(ArrayList<Double> userNumbers, double average, int n){
       
      System.out.print("Given the numbers ");
                   
      for(int counter = 0; counter < userNumbers.size(); counter++){ //This should print out the original array.
          
           if(counter == userNumbers.size() - 1 ){ 
              System.out.print("and " + userNumbers.get(counter) + ", " );      
            }
           else{ 
              System.out.print(df2.format(userNumbers.get(counter)) + ", ");
            }
        }

      System.out.println("the average of all the numbers except the lowest " + n + " is " + df2.format(average) + ".");
         
    }
 
   public static void main(String args[]){
       
       ArrayList<Double> numbers = getArrayNumbers();
       int n = getLowestNumber();
       double average = calculateAverage(numbers, n);
       printResults(numbers, average, n);
       
    }
}
 
Hi smilesofmiles! ;)

You are creating two variables in getArrayNumbers()... and then you never use one of them nor pass it on. :eek:

Then you pass the original userNumbers to calculateAverage() giving it the different name numCopy within the function.
But that's not a copy - that is the original.
To fix it, we can use:
Code:
   public static double calculateAverage(final ArrayList<Double> userNumbers, int n){
       ArrayList<Double> numCopy = new ArrayList<Double>(userNumbers);
       ...
   }
That does make a proper copy of the list of Double's before changing it.
Note also the use of [m]final[/m] to ensure we don't accidentally try to change the original.
 
Thank you both! That last bit did the trick. :-) I think knowing how to do this will definitely help me with future projects. :D