JMU JMU - Department of Computer Science
Help Tools
Lab: Experimenting with Arrays and References


Instructions: Answer the following questions one at a time. After answering each question, check your answer (by clicking on the check-mark icon if it is available) before proceeding to the next question.

Getting Ready: Before going any further, you should:

  1. Download the following files:
    to an appropriate directory/folder (e.g., the course downloads directory/folder). In most browsers/OSs, the easiest way to do this is by right-clicking/control-clicking on each of the links above and then selecting Save as... or Save link as....
  2. Add the appropriate files you downloaded to the directory/project you created for this lab.

    .java Files: In most IDEs, .java files (i.e., source files) can just be copied into the project. See the course "Help" page on your IDE for more information.

    .class and .jar Files: In some IDEs it is easier to use .class files and in others it is easier to use a .jar file that contains the .class files. Hence, you have been provided with both. See the course "Help" page on your IDE for more information.

    Resources: In some IDEs, resources (e.g., images, data files) need to be in a special directory whereas in others they need to be in the working directory. See the course "Help" page on your IDE for more information.

1. Getting Started: This part of the lab will get you started.
  1. Review the source code for the Account class.
2. Arrays of Primitive Types and Reference Types: This part of the lab will help you understand how to work with arrays of primitive types and arrays of reference types. Be careful! When a question begins with "What is printed by" you are starting a fragment from scratch. When a question begins with "Add the following" you are continuing an existing fragment.
  1. Review the following fragment (in a source file other than Account.java, for example, in the main() method of a source file named AccountDriver.java).
        Account[]          customers;
        int[]              sales;
        String[]           months;
    
        sales     = new int[12];
        months    = new String[12];
        
        customers = new Account[1000];
        
  2. Is sales a primitive type or a reference type?
    It is an array, so it is a reference type.
    Expand
  3. Is sales[0] a primitive type or a reference type?
    sales is an int[]. So, every element of sales is an int. Since int is a primitive/fundamental/atomic type it follows that sales[0] is a primitive type.
    Expand
  4. Is months a primitive type or a reference type?
    It is an array, so it is a reference type.
    Expand
  5. Is months[0] a primitive type or a reference type?
    months is a String[]. So, every element of months is a String. Since String is a class type, months[0] is a reference type.
    Expand
  6. Is customers a primitive type or a reference type?
    This is getting more than a little tedious. It's an array, so it is a reference type.
    Expand
  7. Is customers[0] a primitive type or a reference type?
    customers is an Account[]. So, every element of customers is a Account. Since Account is a class type, customers[0] is a reference type.
    Expand
  8. In some (but not all) situations, Java initializes primitive type variables automatically. What value is an int variable initialized to?
    0
    Expand
  9. In some (but not all) situations, Java initializes reference type variables automatically. What value is a reference type variable initialized to?
    null
    Expand
  10. Add the following code to the end of the above fragment.
           System.out.println(sales[0]);
    

    Will this statement compile? If so, will it execute properly? If so, what is printed by the additional statement?


    It will compile and execute properly. It will print 0.
    Expand
  11. Suppose you commented-out the statement that initializes (not the statement that declares) the variable named sales. Would the line you just added compile?


    No, because the variable named sales may not have been initialized (i.e., the compiler can't know for sure so concludes the worst).
    Expand
  12. Add the following code to the end of the above fragment.
           System.out.println(months.length);
    

    Will this statement compile? If so, will it execute properly? If so, what is printed by the additional statement?


    It will compile and will execute properly. months has been instantiated and its length attribute will have a value of 12. So, it will print 12.
    Expand
  13. Add the following code to the end of the above fragment.
           System.out.println(months[0].length());
    

    Will this statement compile? If so, will it execute properly? If so, what is printed by the additional statement?


    It will compile but will not execute properly. Specifically, it will throw a NullPointerException because the length() method is being called but the String object referred to by months[0] has not been instantiated (i.e., is null). Since null doesn't have a length() method, a NullPointerException is thrown.
    Expand
  14. What are the differences between length and length() in this fragment?


    length is an int attribute of the array named months. length() is a method of the String object identified by months[0] that returns an int.
    Expand
  15. Add the following code above the statement that prints months[0].length().
           months[0] = new String("December");
    

    Now what will be printed by the last statement?


    8
    Expand
  16. Add the following code to the end of the above fragment.
           System.out.println(customers[0].getBalance());
    

    Will this statement compile? If so, will it execute properly? If so, what is printed by the additional statement?


    It will compile but will not execute properly. It will throw a NullPointerException because customers[0] is null (hence, doesn't have a getBalance() method).
    Expand
  17. Add the following code above the statement that prints customers[0].getBalance().
           customers[0] = new Account();
    

    Now what will be printed by the last statement?


    0.0
    Expand
3. Understanding Arrays of Reference Types: This part of the lab will help you understand how to work with arrays of primitive types and arrays of reference types. You should build a model of memory to help you answer these questions.

Be careful! When a question begins with "What is printed by" you are starting a fragment from scratch (in a source file other than Account.java, for example, in a source file named ArrayDriver.java). When a question begins with "Add the following" you are continuing an existing fragment.

  1. What is printed by the following fragment?
           double      temp;
           double[]    balances;
           
           balances = new double[3];
           
           System.out.printf("\n\nDuring initialization:\n");
    
           // Balance 0
           temp = 0.00;
           balances[0] = temp;
           System.out.printf("0: %6.2f\n", balances[0]);
    
           // Balance 1
           temp = 100.00;
           balances[1] = temp;
           System.out.printf("1: %6.2f\n", balances[1]);
    
           // Balance 2
           temp = 200.00;
           balances[2] = temp;
           System.out.printf("2: %6.2f\n", balances[2]);
        


    During initialization:
    0:   0.00
    1: 100.00
    2: 200.00
    
    Expand
  2. To check to make sure that the values in elements 0 and 1 were not changed when a value was assigned to element 2, add the following code to the end of the above fragment.
           System.out.printf("\n\nBefore exiting:\n");
           for (int i=0; i<balances.length; i++)
           {
              System.out.printf("%1d: %6.2f\n", i, balances[i]);
              
           }
    

    What is printed by the additional statements?


    Before exiting:
    0:   0.00
    1: 100.00
    2: 200.00
    
    Expand
  3. Were the elements in the array "corrupted"? In other words, do any of the elements have an unintended value?


    No.
    Expand
  4. Now, let's try the same thing with an array of reference types (rather than an array of primitive types). Specifically, what is printed by the following fragment?
           Account        temp;       
           Account[]      accounts;
           
           accounts = new Account[3];
           
           System.out.printf("\n\nDuring initialization:\n");
    
           // Account 0
           temp = new Account();
           temp.setID("Iggy Azalea");
           temp.setBalance(0.00);       
           accounts[0] = temp;
           System.out.printf("0: %15s   %6.2f\n", 
                             accounts[0].getID(), accounts[0].getBalance());
    
           // Account 1
           temp.setID("Common");
           temp.setBalance(100.00);
           accounts[1] = temp;
           System.out.printf("1: %15s   %6.2f\n", 
                             accounts[1].getID(), accounts[1].getBalance());
    
           // Account 2
           temp.setID("Rihanna");
           temp.setBalance(200.00);
           accounts[2] = temp;
           System.out.printf("2: %15s   %6.2f\n", 
                             accounts[2].getID(), accounts[2].getBalance());
        


    During initialization:
    0:     Iggy Azalea     0.00
    1:          Common   100.00
    2:         Rihanna   200.00
    
    Expand
  5. As before, to make sure that things weren't changed somehow, add the following code to the end of the fragment.
           System.out.printf("\n\nBefore exiting:\n");
           for (int i=0; i<accounts.length; i++)
           {
              System.out.printf("%1d: %15s   %6.2f\n", i, 
                                accounts[i].getID(), accounts[i].getBalance());
           }
    

    What is printed by the additional statements?


    Before exiting:
    0:         Rihanna   200.00
    1:         Rihanna   200.00
    2:         Rihanna   200.00
    
    Expand
  6. One might expect the output to be the same during initialization and before exiting. Yet, this output seems to indicate that all of the Account objects in the array contain the same attribute values. Why is this happening?


    Only one Account object was ever created and the three elements in the accounts array are actually aliases (i.e., references to that single object).
    Expand
  7. The answer to the previous question explains why all of the IDs are the same. Why are all of the IDs "Rihanna" (rather than "Iggy Azalea" or "Common")?


    Because there is only one Account object and its ID was first set to "Iggy Azalea", then set to "Common", and finally set to "Rihanna" (after which the output is generated).
    Expand
  8. To fix this problem, we need to actually construct three Account objects as in the following fragment.
           Account        temp;       
           Account[]      accounts;
           
           accounts = new Account[3];
           
           System.out.printf("\n\nDuring initialization:\n");
    
           // Account 0
           temp = new Account();
           temp.setID("Iggy Azalea");
           temp.setBalance(0.00);       
           accounts[0] = temp;
           System.out.printf("0: %15s   %6.2f\n", 
                             accounts[0].getID(), accounts[0].getBalance());
    
           // Account 1
           temp = new Account();
           temp.setID("Common");
           temp.setBalance(100.00);
           accounts[1] = temp;
           System.out.printf("1: %15s   %6.2f\n", 
                             accounts[1].getID(), accounts[1].getBalance());
    
           // Account 2
           temp = new Account();
           temp.setID("Rihanna");
           temp.setBalance(200.00);
           accounts[2] = temp;
           System.out.printf("2: %15s   %6.2f\n", 
                             accounts[2].getID(), accounts[2].getBalance());
    
           System.out.printf("\n\nBefore exiting:\n");
           for (int i=0; i<accounts.length; i++)
           {
              System.out.printf("%1d: %15s   %6.2f\n", i, 
                                accounts[i].getID(), accounts[i].getBalance());
           }
        

    What is printed by this fragment?


    During initialization:
    0:     Iggy Azalea     0.00
    1:          Common   100.00
    2:         Rihanna   200.00
    
    
    Before exiting:
    0:     Iggy Azalea     0.00
    1:          Common   100.00
    2:         Rihanna   200.00
    
    Expand
  9. This code is now correct but inelegant. In particular, the variable temp is completely unnecessary. Without changing the constructor that is being used, change the following
                         
           temp = new Account();
           temp.setID("Iggy Azalea");
           temp.setBalance(0.00);       
           accounts[0] = temp;
    
                      

    to a more elegant implementation that does not use temp.


           accounts[0] = new Account();
           accounts[0].setID("Iggy Azalea");
           accounts[0].setBalance(0.00);       
    
    Expand
4. More on Array Elements as Aliases: This part of the lab will help ensure that you understand some of the issues raised in the previous part. You should build a model of memory to help you answer these questions.
  1. What is printed by the following fragment?
            Account      nelly;
            Account[]    accounts;
            
            accounts = new Account[10];
            
            nelly = new Account();
            nelly.setID("Nelly");
    
            accounts[0] = nelly;        
    
            System.out.printf("%15s  %15s\n", nelly.getID(), accounts[0].getID());
        


              Nelly            Nelly
    
    Expand
  2. Add the following to the end of the above fragment.
            nelly.setID("Lil Nelly");
            System.out.printf("%15s  %15s\n", nelly.getID(), accounts[0].getID());
        

    What is printed by the additional statements?


          Lil Nelly        Lil Nelly
    
    Expand
  3. Add the following to the end of the above fragment.
            accounts[0].setID("Nelly Dogg");
            System.out.printf("%15s  %15s\n", nelly.getID(), accounts[0].getID());
        

    What is printed by the additional statements?


         Nelly Dogg       Nelly Dogg
    
    Expand
  4. What is printed by the following fragment?
            Account      cordozar;
            Account[]    accounts;
            
            accounts = new Account[10];
    
            accounts[0] = new Account();
            accounts[0].setID("Snoop Dogggy Dog");
    
            cordozar = accounts[0];
    
            System.out.printf("%20s  %20s\n", cordozar.getID(), accounts[0].getID());
        


        Snoop Doggy Dogg      Snoop Doggy Dogg
    
    Expand
  5. Add the following to the end of the above fragment.
            cordozar.setID("Snoop Dogg");
            System.out.printf("%20s  %20s\n", cordozar.getID(), accounts[0].getID());
        

    What is printed by the additional statements?


              Snoop Dogg            Snoop Dogg
    
    Expand
  6. Add the following to the end of the above fragment.
            accounts[0].setID("Snoop Lion");
            System.out.printf("%20s  %20s\n", cordozar.getID(), accounts[0].getID());
        

    What is printed by the additional statements?


              Snoop Lion            Snoop Lion
    
    Expand
5. Arrays as Parameters: This part of the lab will help you understand how to pass arrays to methods. If we have not yet discussed parameter passing in lecture then you should come back and answer these questions after we have done so. You should build a model of memory to help you answer these questions.
  1. What do the terms "formal parameter" and "actual parameter" mean?


    A formal parameter is a parameter in the declaration of a method. So, for example, in the method:
        public static void process(int[] scores)
        {
          // Body Omitted
        }
    

    scores is a formal parameter. An actual parameter is a parameter that is passed to a method. So, for example, in the statement:

        process(creditScores);       
    

    creditScores is an actual parameter.

    Expand
  2. In Java, are parameters passed by value or by reference?


    By value
    Expand
  3. What is printed by the following application?
     
        public static void main(String[] args)
        {
           int[] creditScores = {650, 750};
           System.out.printf("Before process(): %3d %3d\n", 
                             creditScores[0], creditScores[1]);
           process(creditScores);       
           System.out.printf("After process():  %3d %3d\n", 
                             creditScores[0], creditScores[1]);
        }
    
        public static void process(int[] scores)
        {
           System.out.printf("In process():     %3d %3d\n", 
                             scores[0], scores[1]);
        }
        


    Before process(): 650 750
    In process():     650 750
    After process():  650 750
    
    Expand
  4. Add the following to the top of the process() method (i.e., before the call to printf()).
     
           scores[0] = 300;
        

    What is printed now?


    Before process(): 650 750
    In process():     300 750
    After process():  300 750
    
    Expand
  5. Why is a different value for element 0 printed in the "Before" line and the "After" line?


    Since the parameter is an array it is a reference type. Since all parameters are passed by value, the actual parameter, creditScores, is a reference type that is passed by value. This means that the formal parameter, scores, is a copy of the address in creditScores. So, scores is an alias for creditScores. That is, scores refers to the same array as creditScores. So, when an element of the the array referred to be scores is changed, it is the same array that is referred to by creditScores.
    Expand
  6. What is printed by the following application?
        public static void main(String[] args)
        {
           double      temp;
           double[]    balances;
           
           balances = new double[5];
           
           for (int i=0; i<balances.length; i++)
           {
              balances[i] = i * 100.0;          
           }
    
           System.out.printf("\n\nBefore reverse():\n");
           for (int i=0; i<balances.length; i++)
           {
              System.out.printf("%d: %6.2f\n", i, balances[i]);
           }       
        }
        
    
        public static void reverse(double[] a)
        {
           double     temp;       
           int        n;
           
           n = a.length;
           
           for (int i=0; i<n/2; i++)
           {
              temp     = a[i];
              a[i]     = a[n-i-1];
              a[n-i-1] = temp;          
           }
        }
    


    Before reverse():
    0:   0.00
    1: 100.00
    2: 200.00
    3: 300.00
    4: 400.00
    
    Expand
  7. Add the following to the end of main().
    
           reverse(balances);     
    
    
           System.out.printf("\n\nAfter reverse():\n");
           for (int i=0; i<balances.length; i++)
           {
              System.out.printf("%d: %6.2f\n", i, balances[i]);
           }       
    
        

    What is printed by the additional statements?


    After reverse():
    0: 400.00
    1: 300.00
    2: 200.00
    3: 100.00
    4:   0.00
    
    Expand
  8. Given what you know about arrays, the type of arrays, and the way parameters are passed, what is actually passed when an array is passed as a parameter?


    A reference to an array is really a reference to the 0th element of the array. That reference is passed by value. So, a copy of the address of the first element of the array is passed.
    Expand
  9. What is printed by the following application?
        public static void main(String[] args)
        {
           double[]    oneDigit, twoDigit;
    
           oneDigit = new double[5];
           twoDigit = new double[5];
           
           for (int i=1; i<oneDigit.length; i++)
           {
              oneDigit[i] = i;
              twoDigit[i] = i * 10;          
           }
           
    
           System.out.printf("%8s   %8s\n", "oneDigit", "twoDigit");
           for (int i=1; i<oneDigit.length; i++)
           {
              System.out.printf("%8.0f   %8.0f\n", oneDigit[i], twoDigit[i]);
           }
        }
        
    
        public static void swap(double[] a, double[] b)
        {
           double[]   temp;
           
           temp = a;
           a    = b;
           b    = temp;       
        }    
        


    oneDigit   twoDigit
           1         10
           2         20
           3         30
           4         40
    
    Expand
  10. Add the following statements to the end of the main() method:
           swap(oneDigit, twoDigit);
    
           System.out.printf("\n\nAfter call to swap()\n");       
           System.out.printf("%8s   %8s\n", "oneDigit", "twoDigit");
           for (int i=1; i<oneDigit.length; i++)
           {
              System.out.printf("%8.0f   %8.0f\n", oneDigit[i], twoDigit[i]);
           }
        

    What is printed by the additional statements?


    After call to swap()
    oneDigit   twoDigit
           1         10
           2         20
           3         30
           4         40
    
    Expand
  11. Why weren't the arrays swapped?


    They weren't swapped because the swap() method only swapped copies of the references.
    Expand
  12. To actually swap the contents of the arrays, we must use the same kind of technique we used in the reverse() method. That is, we must swap individual elements. To do so. change the swap() method to the following:
        public static void swap(double[] a, double[b])
        {
           double   temp;
           
           for (int i=0; i<a.length; i++)
           {
              temp = a[i];
              a[i] = b[i];
              b[i] = temp;       
           }       
        

    Now what is printed by the application?


    oneDigit   twoDigit
           1         10
           2         20
           3         30
           4         40
    
    
    After call to swap()
    oneDigit   twoDigit
          10          1
          20          2
          30          3
          40          4
    
    Expand

Copyright 2024