«^»
11.5 Defining our own parameterized type

Besides using the parameterized types that are in the APIs, we could define our own parameterized type. Suppose we want a collection object that remembers seven things: as soon as you add more than seven items, it forgets about something that has already been stored. Below there is a class called LimitedMemory that can be used to represent such an object.

It is assumed that all the objects that are to be stored in a LimitedMemory object are all of the same type. For this reason, it is written as a parameterized class type. Rather than use E, I have chosen to use the name GType.

One other thing: it is also assumed that each object has a value, and so each object is of a class that implements the Valuable interface. The code below introduces one type that meets these constraints; it is the type Name.

0914: public interface Valuable                                   // Valuable.java
0915: {
0916:    public int value();
0917: }

0918: public class Name implements Valuable                           // Name.java
0919: {
0920:    private String iString;
0921:    public Name(String pString)
0922:    {
0923:       iString = pString;
0924:    }
0925:    public String toString()
0926:    {
0927:       return iString;
0928:    }
0929:    public int value()
0930:    {
0931:       return iString.length();
0932:    }
0933: }

0934: import java.util.ArrayList;                            // LimitedMemory.java
0935: import java.util.Iterator;
0936: import java.util.Random;
0937: public class LimitedMemory <GType extends Valuable> 
0938:       implements Iterable<GType>
0939: {
0940:    private static final int iCapacity = 7; 
0941:    private ArrayList<GType> iArrayList;
0942:    private Random iRandom;
0943:    public LimitedMemory()
0944:    {
0945:       iArrayList = new ArrayList<GType>(iCapacity);
0946:       iRandom = new Random();
0947:    }
0948:    public void add(GType pGType)
0949:    {
0950:       if (iArrayList.size()<iCapacity)
0951:          iArrayList.add(pGType);
0952:       else
0953:          iArrayList.set(iRandom.nextInt(iCapacity), pGType);
0954:    }
0955:    public String toString()
0956:    {
0957:       return iArrayList.toString();
0958:    }
0959:    public int value()
0960:    {
0961:       int tSum = 0;
0962:       for (GType tGType : iArrayList)
0963:       {
0964:          tSum += tGType.value();
0965:       }
0966:       return tSum;
0967:    }
0968:    public Iterator<GType> iterator()
0969:    {
0970:       return iArrayList.iterator();
0971:    }
0972: }

Here are two fragments of code that use a LimitedMemory object:

0978:       LimitedMemory<Name> tLimitedMemory = new LimitedMemory<Name>();
0979:       tLimitedMemory.add(new Name("jim"));
0980:       tLimitedMemory.add(new Name("bert"));
1031:       iMyPrintln(tLimitedMemory);
1032:       System.out.println(" " + tLimitedMemory.value());
1033:       LimitedMemory<Name> tLimitedMemory2 = new LimitedMemory<Name>();
1034:       tLimitedMemory2.add(new Name("jim"));
1035:       tLimitedMemory2.add(new Name("bert"));
1036:       tLimitedMemory2.add(new Name("jill"));
1037:       System.out.println(iBiggestCost(tLimitedMemory, tLimitedMemory2));

The above code uses the following subsidiary methods:

1039:    private static void iMyPrintln(LimitedMemory<Name> pLimitedMemory)
1040:    {
1041:       System.out.print("+");
1042:       for (Name tName : pLimitedMemory)
1043:       {
1044:          System.out.print(tName + "+");
1045:       }
1046:       System.out.println();
1047:    }
1048:    private static 
1049:       <GType1 extends Valuable, GType2 extends Valuable> 
1050:          int iBiggestCost(
1051:             LimitedMemory<GType1> pLimitedMemory1,
1052:             LimitedMemory<GType2> pLimitedMemory2)
1053:    {
1054:       return Math.max(pLimitedMemory1.value(), pLimitedMemory2.value());
1055:    }