Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/bhoffman0/CSAwesome
Browse files Browse the repository at this point in the history
  • Loading branch information
actions-user committed Jan 7, 2024
2 parents abb6f4c + 75b32b7 commit c802fcd
Show file tree
Hide file tree
Showing 4 changed files with 370 additions and 153 deletions.
188 changes: 148 additions & 40 deletions _sources/Unit7-ArrayList/topic-7-1-arraylist-basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,35 @@ Intro to ArrayLists

Figure 1: A couple of lists

In the last unit, we learned about arrays to hold collections of related data. But arrays have limitations. The size of an array is established at the time of creation and cannot be changed. What if you don't know how big the collection of data will be? What if you want to add and remove items from the collection and change the size of the collection while the program is running? For example, if you wanted to represent a shopping list, you might add to the list throughout the week and remove things from the list while you are shopping. You probably would not know how many items will be on the list at the beginning of the week.
In the last unit, we learned about using arrays to hold collections of related
data. However arrays are not very flexible. Most notably, the size of an array
is established at the time of creation and cannot be changed. What if you don't
know how big the collection of data will be? What if you want to both add and
remove items from a collection? For example, if you wanted to represent a
shopping list, you might add to the list throughout the week and remove things
from the list while you are shopping. You probably would not know how many items
will be on the list at the beginning of the week.

For cases like this, Java has a class called ``ArrayList`` which is a re-sizable
list. It is called ``ArrayList`` because it stores the items that have been
added to it in an underlying array. But it also takes care of keeping track of
how many items have been added to the array and it will create a new bigger
array under the covers when needed to hold more items.

You can use ``ArrayList`` instead of arrays whenever you don't know the size of
the array you need or you know that you will add and remove items and may need
to change the array’s size dynamically during run time. An ``ArrayList`` is
**mutable**, meaning it can change during run time by adding and removing objects
from it.

.. note::

Luckily, Java has a class called **ArrayList** which is a re-sizable array. An ArrayList has an underlying array that grows or shrinks as needed. You can use ArrayList instead of arrays whenever you don't know the size of the array you need or you know that you will add and remove items and may need to change the array's size dynamically during run time. An ArrayList is **mutable**, meaning it can change during runtime by adding and removing objects from it.

An ArrayList is often called just a **list** on the CSA exam. In past AP CSA exams, the interface **List** is often used to declare an ArrayList. Interfaces are no longer on the exam, but if you see List being used, just assume it's an ArrayList.
An ``ArrayList`` is often called just a list on the CSA exam. Prior to 2020
the AP CSA curriculum included **interfaces** which are somewhat like classes
and the interface ``List`` was often used to declare a variable that would
refer to an ``ArrayList``. Interfaces are no longer on the exam, but if you
see ``List`` being used in an old exam question just assume it’s an
``ArrayList``.

.. mchoice:: qloopList
:answer_a: A list will always use less memory than an array.
Expand All @@ -43,32 +66,55 @@ An ArrayList is often called just a **list** on the CSA exam. In past AP CSA exa



Import Package
Packages and imports
------------------------

.. index::
single: import statement

The ``ArrayList`` class is in the ``java.util`` package. A **package** is a set or library of related classes. The java.lang package is the main Java language classes that you get automatically without importing it. The java.util package has a lot of utility classes that you can use if you import the package. If you want to use any class other than those in ``java.lang`` you will need to either use the full name (packageName.ClassName) like (``java.util.ArrayList``) or use one or more import statements to import in that package.

Import statements have to be the first code in a Java source file. An import statement tells Java which class you mean when you use a short name (like ``ArrayList``). It tells Java where to find the definition of that class.

You can import just the classes you need from a package as shown below. Just provide an ``import`` statement for each class that you want to use.
The ``ArrayList`` class is in the ``java.util`` package. A **package** is a set
or library of related classes. The classes we have used until now, such as
``String`` and ``Math``, are in the special package ``java.lang`` whose classes
are always available in any Java program. Other packages, such as ``java.util``,
provide classes that can only be used either by **importing** them or (much more
rarely) by referring to them by their full name which includes the package as a
prefix. The full name of ``ArrayList`` is thus ``java.util.ArrayList`` but
rather than type that out all the time, in any class where we want to use
``ArrayList`` we will usually import it with an ``import`` statement.

Import statements have to come before the class definition in a Java source file
and serve to tell Java which class you mean when you use a short name like
``ArrayList``. To import just one class we use a single ``import`` of the
fully-qualified name of the class like this:

.. code-block:: java
// import just the ArrayList class
// Import just the ArrayList class from java.util
import java.util.ArrayList;
.. index::
single: package
pair: statement; import

Another option is to import everything at the same level in a package using ``import packageName.*``.

After such an import statement, anywhere ``ArrayList`` is used as a class name
in the file it will be taken to mean ``java.util.ArrayList``.

Another option is to import all the classes in a package with a “wildcard” import:

.. code-block:: java
import java.util.*; // import everything in package including ArrayList
// Import everything in java.util including ArrayList
import java.util.*;
This import statement will also cause, ``ArrayList`` to refer
``java.util.ArrayList``. But many other names of classes defined in the
``java.util`` package will also be available whether you use them or not. (One
that you have probably used by now is ``Scanner`` which can be used to read
input a user types at the command line.) Using wildcard imports can cause
conflicts if you import all the classes from two different packages and they
have class names in common but usually that’s not a problem, at least with
packages that are part of Java itself.

.. note::

Expand All @@ -92,9 +138,15 @@ Another option is to import everything at the same level in a package using ``im
Declaring and Creating ArrayLists
----------------------------------

To declare a ArrayList use ``ArrayList<Type> name`` Change the *Type* to be whatever type of objects you want to store in the ArrayList, for example ``String`` as shown in the code below. You don't have to specify the **generic type** ``<Type>``, since it will default to ``Object``, but it is good practice to specify it to restrict what to allow in your ArrayList. Using a type ArrayList<Type> is preferred over just using ArrayList because it allows the compiler to find errors that would otherwise be missed until run-time.


To declare a ArrayList use ``ArrayList<Type> name`` where *Type*, called a
**type parameter** is the type of objects you want to store in the ArrayList.
For example a variable naming an ``ArrayList`` meant to hold ``String``\ s is
declared as ``ArrayList<String>`` as shown in the code below. You can declare a
variable to just be of type ``ArrayList``, with no type parameter, and it’ll be
approximately the same as if you had declared ``ArrayList<Object>``, but it is
good practice to specify the type of objects you intend to store in an
``ArrayList`` as it allows the compiler to find errors that would otherwise be
missed until run time.

.. code-block:: java
Expand All @@ -104,7 +156,13 @@ To declare a ArrayList use ``ArrayList<Type> name`` Change the *Type* to be wha
.. note::

ArrayLists can only hold objects like String and the wrapper classes Integer and Double. They cannot hold primitive types like int, double, etc.
``ArrayList``\ s can only hold reference types like ``String``. Since they
can’t hold primitive types like ``int`` and ``double``, if we want a
collection of numbers we need to use the wrapper classes ``Integer`` or
``Double``. However, because of autoboxing, if you declare an
``ArrayList<Integer>`` or ``ArrayList<Double>`` you can mostly treat the
elements of the ``ArrayList`` as if they were in fact ``int``\ s or
``double``\ s.

|CodingEx| **Coding Exercise**

Expand All @@ -113,7 +171,10 @@ To declare a ArrayList use ``ArrayList<Type> name`` Change the *Type* to be wha
:language: java
:autograde: unittest

In the code below we are declaring a variable called ``nameList`` that can refer to a ArrayList of strings, but currently doesn't refer to any ArrayList yet (it's set to ``null``).
In the code below we are declaring a variable called ``nameList`` that can
refer to a ``ArrayList`` of strings, but currently doesn't refer to any
``ArrayList`` yet as it’s set to ``null``.

~~~~
import java.util.*; // import for ArrayList

Expand Down Expand Up @@ -151,16 +212,22 @@ To declare a ArrayList use ``ArrayList<Type> name`` Change the *Type* to be wha
}
}

Declaring a ArrayList doesn't actually create a ArrayList. It only creates a variable that can refer to a ArrayList. To actually create a ArrayList use ``new ArrayList<Type>()``. If you leave off the ``<Type>`` it will default to ``Object``.
As with other reference types, declaring a ``ArrayList`` variable doesn't
actually create a ``ArrayList`` object. It only creates a variable that can
refer to a ``ArrayList`` or ``null``. To actually create a ``ArrayList`` we must
invoke a constructor such as ``new ArrayList<String>()``.

You can get the number of items in a ArrayList using the ``size()`` method. Notice that an empty ArrayList has a size of 0 because the ArrayList constructor constructs an empty list. Also notice that you can't get the size of a ArrayList that is currently set to ``null`` on line 9. You will get a ``NullPointerException`` instead, which means that you tried to do something with an object reference that was ``null`` (doesn't exist).
You can get the number of items in a ``ArrayList`` using the ``size()`` method.
Notice that a newly constructed ``ArrayList`` is empty and thus has a size of 0.
Also remember that you can’t call methods on ``null`` so trying to call ``size``
on the value of ``list2`` at line 10 below causes a ``NullPointerException``.

.. activecode:: ArrayListCreateStr
:language: java
:autograde: unittest
:practice: T

The following code demonstrates a NullPointerException. Change the list2 declaration so that it creates a new Arraylist to remove the NullPointerException.
The following code demonstrates a NullPointerException. Change the list2 declaration so that it creates a new ArrayList to remove the NullPointerException.
~~~~
import java.util.*; // import needed for ArrayList

Expand Down Expand Up @@ -200,16 +267,25 @@ You can get the number of items in a ArrayList using the ``size()`` method. Not
}
}

You can also create ArrayLists of integer values. However, you have to use ``Integer`` as the type because ArrayLists can only hold objects, not primitive values. All primitive types must be **wrapped** in objects before they are added to an ArrayList. For example, ``int`` values can be wrapped in ``Integer`` objects, ``double`` values can be wrapped in ``Double`` objects. You can actually put in any kind of Objects in an ArrayList, even for a class that you wrote in Unit 5 like Student or Person or Pet.
You can also create ArrayLists of integer and double values. However, you have
to use ``Integer`` or ``Double`` as the type parameter because ``ArrayList``\ s
can only hold objects, not primitive values. All primitive types must be
**wrapped** in objects before they are added to an ArrayList. For example,
``int`` values can be wrapped in ``Integer`` objects, ``double`` values can be
wrapped in ``Double`` objects. However this normally happens automatically
thanks to autoboxing.

You can actually put in any kind of objects in an ``ArrayList``, including
instances of classes that you write, such as the ``Student``, ``Person``, or
``Pet`` classes from Unit 5.

.. activecode:: ArrayListCreateInt
:language: java
:autograde: unittest

Here's an example of a Integer ArrayList.
~~~~
import java.util.*; // import everything at this level
import java.util.*;

public class ArrayListCreateInt
{
Expand Down Expand Up @@ -264,7 +340,7 @@ You can also create ArrayLists of integer values. However, you have to use ``In

Although it is not on the AP exam, you can convert an array to a ``List`` using
the static method ``asList`` from the ``Arrays`` helper class:
``Arrays.asList(arrayname)``. Note that ``ArrayList` has a ``toString`` method
``Arrays.asList(arrayname)``. Note that ``ArrayList`` has a ``toString`` method
that is automatically called to print the list in a nice format.

.. activecode:: ArrayListFromArray
Expand Down Expand Up @@ -312,7 +388,13 @@ that is automatically called to print the list in a nice format.

|CodingEx| **Coding Exercise**

You can add values to an ArrayList by using its **add** method, described in detail in the next lesson. Try the code below. Note that the type of the ArrayList, String or Integer, also determines the type of parameters and return types for all of its methods, so add and print work for any type of ArrayList.
You can add values to an ``ArrayList`` using its **add** method, described in
detail in the next lesson. Try the code below. Note that the type of the
``ArrayList``, ``String`` or ``Integer``, also determines the type of parameters
and return types for all of its methods, so add and print work for any type of
``ArrayList``. And when the ``ArrayList`` is a list of ``Integer``\ s,
autoboxing takes care of wrapping the ``int`` arguments like ``2`` and ``4``
into instances of ``Integer`` for us.

.. activecode:: listAdd
:language: java
Expand Down Expand Up @@ -383,9 +465,18 @@ You can add values to an ArrayList by using its **add** method, described in det

<a href="https://apcentral.collegeboard.org/pdf/ap-computer-science-a-frq-2017.pdf?course=ap-computer-science-a" target="_blank">2017 Free Response Question</a>

This programming challenge is based on the |FRQ 2017| part 1a on the 2017 AP CSA exam. In this question, you are asked to write a constructor for a class called Digits. This constructor takes an integer number as its argument and divides it up into its digits and puts the digits into an ArrayList. For example, new Digits(154) creates an ArrayList with the digits [1, 5, 4].
This programming challenge is based on the |FRQ 2017| part 1a on the 2017 AP CSA
exam. In this question, you are asked to write a constructor for a class called
``Digits``. This constructor takes an integer number as its argument and divides
it up into its digits and puts the digits into an ``ArrayList``. For example,
``new Digits(154)`` creates an ArrayList with the digits [1, 5, 4].

First, let's discuss how to break up a number into its digits. Try the code below. What happens if you divide an integer by 10? Remember that in integer division the result truncates (cuts off) everything to the right of the decimal point. Which digit can you get by using ``% 10`` which returns the remainder after dividing by 10? Try a different number and guess what it will print and then run to check.
First, let’s discuss how to break up a number into its digits. Try the code
below. What happens if you divide an integer by 10? Remember that in integer
division the result truncates (cuts off) everything to the right of the decimal
point. Which digit can you get by using ``% 10`` which returns the remainder
after dividing by 10? Try a different number and guess what it will print and
then run to check.

.. activecode:: divideby10
:language: java
Expand Down Expand Up @@ -430,14 +521,21 @@ First, let's discuss how to break up a number into its digits. Try the code belo
}
}

We can use a while loop to print out each digit in reverse order starting from the right (4, 5, 1 for the number 154) while dividing it by 10. You can try it in the active code above. Here is the pseudocode:
We can use a while loop to print out each digit in reverse order starting from
the right (4, 5, 1 for the number 154) while dividing it by 10. You can try it
in the active code above. Here is the pseudocode:

- while number is greater than 0
- while number is greater than 0

- print out the last digit using %
- change the number to cut off the last digit using /
- print out the last digit using %
- change the number to cut off the last digit using /

Now, let's write a constructor for the Digits class that uses this loop and adds each found digit to the ArrayList instead of printing it out. You can use a special method called **Collections.reverse(digitsList);** to reverse the order of the digits in the ArrayList after the loop to get them in the right order. In the next lesson, we will also learn how to use a different add method that adds in elements at any index instead of the end.
Now, let’s write a constructor for the ``Digits`` class that uses this loop and
adds each found digit to the ``ArrayList`` instead of printing it out. You can
use a special method called ``Collections.reverse(digitsList);`` to reverse the
order of the digits in the ``ArrayList`` after the loop to get them in the right
order. In the next lesson, we will also learn how to use a different ``add``
method that adds in elements at any index instead of the end.

.. activecode:: challenge-7-1-digits
:language: java
Expand Down Expand Up @@ -515,18 +613,28 @@ Now, let's write a constructor for the Digits class that uses this loop and adds
Summary
-----------

- ArrayList are re-sizable arrays that allow adding and removing items to change their size during run time.
- ``ArrayList``\ s are re-sizable lists that allow adding and removing items to
change their size during run time.

- The ArrayList class is in the java.util package. You must import java.util.* to use it.
- The ``ArrayList`` class is in the ``java.util`` package. You must import
``java.util.ArrayList`` or ``java.util.*`` to use it.

- An ArrayList object contains object references and is mutable, meaning it can change (by adding and removing items from it).
- An ``ArrayList`` object contains object references and is mutable, meaning it
can change (by adding and removing items from it).

- The ArrayList constructor ArrayList() constructs an empty list of size 0.
- The ``ArrayList`` constructor ``ArrayList()`` constructs an empty list of size 0.

- Java allows the generic type ArrayList<E>, where the generic type E specifies the type of the elements, like String or Integer. Without it, the type will be Object.
- Java allows the generic type ``ArrayList<E>``, where the generic type ``E``
specifies the type of the elements, like ``String`` or ``Integer``. Without
it, the type will be ``Object``.

- ArrayList<E> is preferred over ArrayList because it allows the compiler to find errors that would otherwise be found at run-time.
- ``ArrayList<E>`` is preferred over ``ArrayList`` because it allows the
compiler to find errors that would otherwise be found at run time.

- When ArrayList<E> is specified, the types of the reference parameters and return type when using its methods are type E.
- When ``ArrayList<E>`` is specified, the types of the reference parameters and
return type when using its methods are type ``E``.

- ArrayLists cannot hold primitive types like int or double, so you must use the wrapper classes Integer or Double to put numerical values into an ArrayList.
- ``ArrayList``\ s cannot hold primitive types like ``int`` or ``double``, so
you must use the wrapper classes ``Integer`` or ``Double`` to put numerical
values into an ``ArrayList``. However autoboxing usually takes care of that
for you.
Loading

0 comments on commit c802fcd

Please sign in to comment.