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

Click For Summary
SUMMARY

The discussion centers on a Java programming issue where a user attempts to print an original array while performing operations on a copy. The user initially creates a shallow copy of the array, which leads to unintended modifications. The solution involves creating a deep copy of the original array using the constructor of the ArrayList class. Additionally, using the 'final' keyword in method parameters ensures the original array remains unchanged during calculations.

PREREQUISITES
  • Understanding of Java ArrayList and its methods
  • Knowledge of Java method parameters and variable scope
  • Familiarity with sorting algorithms in Java
  • Basic arithmetic operations in Java programming
NEXT STEPS
  • Learn about Java ArrayList deep copying techniques
  • Explore the use of the 'final' keyword in Java method parameters
  • Study sorting algorithms and their implementations in Java
  • Investigate best practices for managing variable scope in Java
USEFUL FOR

Java developers, programming students, and anyone looking to improve their skills in managing data structures and array manipulations in Java.

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);
       
    }
}
 
Technology news 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
 

Similar threads

  • · Replies 3 ·
Replies
3
Views
3K
Replies
1
Views
3K
  • · Replies 2 ·
Replies
2
Views
2K
Replies
2
Views
2K
  • · Replies 1 ·
Replies
1
Views
3K
  • · Replies 6 ·
Replies
6
Views
2K
Replies
9
Views
2K
  • · Replies 1 ·
Replies
1
Views
2K
  • · Replies 10 ·
Replies
10
Views
11K
  • · Replies 18 ·
Replies
18
Views
2K