A collection is an object that groups multiple object references into a single unit. You can think of a collection as representing a container for objects where each object is usually referred to as an element.
Because a collection groups multiple object references, it is an aggregation. Typically, a collection aggregates elements that form a natural group. For example:
Collection Of | Represents |
at most 23 hockey players | National Hockey League team roster |
at most 7 playing cards | Texas Holdem poker hand |
words | dictionary |
books | library |
Notice that some collections have a natural maximum capacity, whereas the size of other collections naturally grows and shrinks.
In the case of a collection with a known maximum capacity, it is possible to allocate enough memory to store the collection when the collection is created; this is called static allocation (where static means unchanging and is not related to the Java keyword).
In the case where the size of the collection can grow and shrink, memory is allocated as it is needed, which is called dynamic allocation. Many dynamically allocated collections have constructors that allow the client to set an initial size of the collection.
The Portfolio
class is an example of a statically
allocated collection. It represents a collection of Investment
objects.
// no name portfolio with capacity 100 Portfolio pf = new Portfolio(); // named portfolio with capacity 50 Portfolio myPf = new Portfolio("My Retirement Fund", 50);
Note that the capacity of a collection is different than its size. The capacity of a portfolio is the maximum number of investments that it can hold. The size of a portfolio is the actual number of investments in the portfolio.
GlobalCredit
is an example of a dynamically allocated
collection. It represents a collection of credit cards (presumably
distributed by a bank).
// an empty collection of credit cards GlobalCredit cards = new GlobalCredit();
Some collections have constructors where the client can specify
an initial capacity of the collection, but GlobalCredit
does not have such a constructor.
Most collections support adding elements to the collection through
a method named add
. Some
collections place limitations on what elements may be added. Adding an
element might fail if:
null
Failure to add an element is either indicated by the add
method returning false
or throwing an exception.
A portfolio lets a client add investments to it until it is full (reached its capacity); otherwise, there are no restrictions on the investments that may be added.
Portfolio pf = new Portfolio("Small Portfolio", 3); Stock stockA = new Stock("HR.A"); Stock stockB = new Stock("HR.B"); Stock stockC = new Stock("HR.C"); Stock stockD = new Stock("HR.D"); output.print( pf.add(new Investment(stockA, 1, 1.00)) ); output.println( " " + pf.size() ); output.print( pf.add(new Investment(stockB, 1, 2.00)) ); output.println( " " + pf.size() ); output.print( pf.add(new Investment(stockC, 1, 3.00)) ); output.println( " " + pf.size() ); output.print( pf.add(new Investment(stockD, 1, 4.00)) ); output.println( " " + pf.size() );
The above code fragment prints:
true 1 true 2 true 3 false 3
Try to read in a portfolio from a file as described in
eCheck08B. There is a test data file on the book CD-ROM
called lab8data.txt
, or you can
download here.
This is a good (but hard?) practice question for strings and loops.
GlobalCredit
CollectionA GlobalCredit
collection will only allow
unique credit cards to be added (it prevents duplicate
credit cards from being in the collection); otherwise there
are no restrictions on the credit cards that may be added.
If a client tries to insert a credit card that is already
in the collection, the add
method returns
false
and the credit card is not added.
GlobalCredit cards = new GlobalCredit(); CreditCard cardA = new CreditCard(111111, "John A"); CreditCard cardB = new CreditCard(222222, "John B"); CreditCard cardC = new CreditCard(111111, "John C"); // cardC.equals(cardA) == true CreditCard cardD = cardB; // cardD.equals(cardB) == true output.print( cards.add(cardA) ); output.println( " " + cards.size() ); output.print( cards.add(cardB) ); output.println( " " + cards.size() ); output.print( cards.add(cardC) ); output.println( " " + cards.size() ); output.print( cards.add(cardD) ); output.println( " " + cards.size() );
The above code fragment prints:
true 1 true 2 false 2 false 2
GlobalCredit
CollectionWrite a loop that repeatedly adds credit cards to a
GlobalCredit
Collection. Your program should
ask for the credit card number and a name each time, and
it should stop when the user enters a negative number.
For "fun" you should read in the number as a string.
Your program should print a warning if the credit card
is already in the collection.
GlobalCredit gcc = new GlobalCredit();
output.print("Credit card number and name : ");
int number = Integer.parseInt(input.next());
String name = input.next();
for (; number >= 0; )
{
if (!gcc.add( new CreditCard(number, name) ))
{
output.println("Card already exists, call police");
}
output.print("Credit card number and name : ");
number = Integer.parseInt(input.next());
name = input.next();
}
Many tasks require that the client do something with each element in a collection. This means that the collection must provide a mechanism for allowing the client to access each element.
Some collections provide indexed access. You can imagine
that each element can be identified by a unique non-negative
integer index between 0
and size - 1
where size
is the number of elements in the
collection (not the capacity). In Java, the client usually uses
a method named get
for indexed access:
Portfolio pf = Portfolio.getRandom();
Investment first = pf.get(0);
output.println( first.getStock() );
To perform a traversal, the client writes a loop:
Portfolio pf = Portfolio.getRandom();
double pfBookValue = 0.0;
double pfCurrentValue = 0.0;
for (int i = 0; i < pf.size(); i++)
{
Investment inv = pf.get(i);
double bookValue = inv.getQty() * inv.getBookValue();
double currentValue =
inv.getQty() * inv.getStock().getPrice();
pfBookValue += bookValue;
pfCurrentValue += currentValue;
}
output.printf("Book Value : $%.2f%n", pfBookValue);
output.printf("Current Value : $%.2f%n", pfCurrentValue);