Title: Generics
Course: CPS 261: Advanced Java Concepts ~ DL & MM MASTER

Generics

To cover the concepts of how to work with the concept of Generics, I have borrowed some examples from the book and made some modifications.

Sample.java


package generics;

public class Sample<T>
{
    private T data;

    public void setData(T newData)
    {
        data = newData;
    }

    public T getData( )
    {
        return data;
    }

    public static void main(String[] args)
    {
        Sample<String> sample1 = new Sample<String>();

        sample1.setData("HI");
        String s = sample1.getData();
        System.out.println(" sample1="+ s);

        Sample<Integer> sample2 = new Sample<Integer>();
        sample2.setData(78);
        int x = sample2.getData();
        System.out.println(" sample2=" + x);

        /*

         Logically we  have "Manufactured 2 classes":

         class Sample<String>
         {
             String data;

            public void setData(String newData)
            {
                data = newData;
            }

            public String getData( )
            {
                return data;
            }
         }


         AND



         class Sample<Integer>
         {
             Integer data;

            public void setData(Integer newData)
            {
                data = newData;
            }

            public Integer getData( )
            {
                return data;
            }
         }


         */
    }
}


Pair.java


package generics;


public class Pair<T>
{
    private T first;
    private T second;

    public Pair()
    {
        first = null;
        second = null;
    }

    public Pair(T firstItem, T secondItem)
    {
        first = firstItem;
        second = secondItem;
    }

    public void setFirst(T newFirst)
    {
        first = newFirst;
    }

    public void setSecond(T newSecond)
    {
        second = newSecond;
    }

    public T getFirst()
    {
        return first;
    }

    public T getSecond()
    {
        return second;
    }

    public String toString()
    {
        return ( "[first:" + first.toString() + " second:" + second.toString() +"]");
    }

    public boolean equals(Object otherObject)
    {
        if (otherObject == null)
            return false;
        else if (getClass( ) != otherObject.getClass( ))
            return false;
        else
        {
            Pair<T> otherPair = (Pair<T>)otherObject;
            return (first.equals(otherPair.first)
               && second.equals(otherPair.second));
        }
    }

    public static void main(String[] args)
    {
        Pair<String> name = new Pair<String>("Kim", "Tom");
        Pair<String> name2 = new Pair<String>("Tom", "Kim");


        System.out.println("first=" + name.getFirst());
        System.out.println("second=" + name.getSecond());
        if (name.equals(name2))
            System.out.println(name.toString() + " is the same as " + name2.toString());
        else
            System.out.println(name.toString() + " is NOT the same as " + name2.toString());



        Pair<Integer> numbers = new Pair<Integer>(1,2); // Automatic Boxing
        Pair<Integer> numbers2 = new Pair<Integer>(2,1); // Automatic Boxing

        System.out.println("first=" + numbers.getFirst());
        System.out.println("second=" + numbers.getSecond());
        if (numbers.equals(numbers2))
            System.out.println(numbers.toString() + " is the same as " + numbers2.toString());
        else
            System.out.println(numbers.toString() + " is NOT the same as " + numbers2.toString());



    }
}



UnorderedPair.java


package generics;




public class UnorderedPair<T> extends Pair<T>
{
    public UnorderedPair()
    {
        setFirst(null);
        setSecond(null);
    }

    public UnorderedPair(T firstItem, T secondItem)
    {
        setFirst(firstItem);
        setSecond(secondItem);
    }

    public boolean equals(Object otherObject)
    {
        if (otherObject == null)
            return false;
        else if (getClass( ) != otherObject.getClass( ))
            return false;
        else
        {
            UnorderedPair<T> otherPair =
                            (UnorderedPair<T>)otherObject;
            return (getFirst( ).equals(otherPair.getFirst( ))
               && getSecond( ).equals(otherPair.getSecond( )))
               ||
                   (getFirst( ).equals(otherPair.getSecond( ))
               && getSecond( ).equals(otherPair.getFirst( )));
        }
    }

    public static void main(String[] args)
    {
        UnorderedPair<String> name = new UnorderedPair<String>("Kim", "Tom");
        UnorderedPair<String> name2 = new UnorderedPair<String>("Tom", "Kim");


        System.out.println("first=" + name.getFirst());
        System.out.println("second=" + name.getSecond());
        if (name.equals(name2))
            System.out.println(name.toString() + " is the same as " + name2.toString());
        else
            System.out.println(name.toString() + " is NOT the same as " + name2.toString());



        UnorderedPair<Integer> numbers = new UnorderedPair<Integer>(1,2); // Automatic Boxing
        UnorderedPair<Integer> numbers2 = new UnorderedPair<Integer>(2,1); // Automatic Boxing

        System.out.println("first=" + numbers.getFirst());
        System.out.println("second=" + numbers.getSecond());
        if (numbers.equals(numbers2))
            System.out.println(numbers.toString() + " is the same as " + numbers2.toString());
        else
            System.out.println(numbers.toString() + " is NOT the same as " + numbers2.toString());



    }
}



TwoTypePair.java


package generics;



public class TwoTypePair<T1, T2>
{
    private T1 first;
    private T2 second;

    public TwoTypePair()
    {
        first = null;
        second = null;
    }

    public TwoTypePair(T1 firstItem, T2 secondItem)
    {
        first = firstItem;
        second = secondItem;
    }

    public void setFirst(T1 newFirst)
    {
        first = newFirst;
    }

    public void setSecond(T2 newSecond)
    {
        second = newSecond;
    }

    public T1 getFirst()
    {
        return first;
    }

    public T2 getSecond()
    {
        return second;
    }

    public String toString()
    {
        return ( "[first: " + first.toString() + " second: " + second.toString() +"]" );
    }

    public boolean equals(Object otherObject)
    {
        if (otherObject == null)
            return false;
        else if (getClass( ) != otherObject.getClass( ))
            return false;
        else
        {
            TwoTypePair<T1, T2> otherPair =
                        (TwoTypePair<T1, T2>)otherObject;
            return (first.equals(otherPair.first)
                && second.equals(otherPair.second));
        }
    }


    public static void main(String[] args)
    {
        TwoTypePair<String, Integer> name = new TwoTypePair<String, Integer>("Kim", 30);
        TwoTypePair<String, Integer> name2 = new TwoTypePair<String, Integer>("Kim", 25);


        System.out.println("first=" + name.getFirst());
        System.out.println("second=" + name.getSecond());
        if (name.equals(name2))
            System.out.println(name.toString() + " is the same as " + name2.toString());
        else
            System.out.println(name.toString() + " is NOT the same as " + name2.toString());




    }
}



Pair2 (using extends syntax)


package generics_bounded;



public class Pair2<T extends Comparable>
{
    private T first;
    private T second;

    public T max( )
    {
        if (first.compareTo(second) >= 0)
            return first;
        else
            return second;
    }

    public Pair2()
    {
        first = null;
        second = null;
    }

    public Pair2(T firstItem, T secondItem)
    {
        first = firstItem;
        second = secondItem;
    }

    public void setFirst(T newFirst)
    {
        first = newFirst;
    }

    public void setSecond(T newSecond)
    {
        second = newSecond;
    }

    public T getFirst()
    {
        return first;
    }

    public T getSecond()
    {
        return second;
    }

    public String toString()
    {
        return ( "[first:" + first.toString() + "  second:" + second.toString() +"]");
    }

    public boolean equals(Object otherObject)
    {
        if (otherObject == null)
            return false;
        else if (getClass( ) != otherObject.getClass( ))
            return false;
        else
        {
            Pair2<T> otherPair = (Pair2<T>)otherObject;
            return (first.equals(otherPair.first)
               && second.equals(otherPair.second));
        }
    }

    public static void main(String[] args)
    {
        Pair2<String> words = new Pair2<String>("chucky", "cheese");
        System.out.println(words.toString() + " max=" + words.max());


        Pair2<Integer> numbers = new Pair2<Integer>(50, 21);
        System.out.println(numbers.toString() + " max=" + numbers.max());
    }
}


AnimalCollection.java


package generics_bounded;

import java.util.ArrayList;

public class AnimalCollection<X extends Animal> {
    ArrayList<X> collection = new ArrayList<X>();


    void add(X animal)
    {
        collection.add(animal);
    }
    void makeAllNoises()
    {
        for (int i=0; i < collection.size(); i++)
        {
            X animal = collection.get(i);
            animal.makesNoise();
        }
    }

    public static void main(String[] args) {

        System.out.println("Dairy:");
        AnimalCollection<Cow> dairy = new AnimalCollection<Cow>();
        dairy.add(new Cow("Molly"));
        dairy.add(new Cow("Bess"));
        dairy.makeAllNoises();

        System.out.println("***********************");
        System.out.println("SnakePit:");

        AnimalCollection<Snake> snakePit = new AnimalCollection<Snake>();
        snakePit.add(new Snake("Judas"));
        snakePit.add(new Snake("Benedict"));
        snakePit.makeAllNoises();

        //dairy.add(new Snake("Jezebel"));


        System.out.println("***********************");
        System.out.println("Zoo:");
        AnimalCollection<Animal> zoo = new AnimalCollection<Animal>();
        zoo.add(new Horse("Prince"));
        zoo.add(new Cow("Molly"));
        zoo.add(new Snake("Judas"));
        zoo.makeAllNoises();

        //snakePit.add(new Horse("Gettup"));

    }

}



Animal.java


package generics_bounded;

public abstract class Animal {
    String name;

    Animal(String name)
    {
        this.name = name;
    }
    abstract void makesNoise();

}

class Cow extends Animal
{
    Cow(String name)
    {
        super(name);
    }
    void makesNoise()
    {
        System.out.println("Moooo");
    }
}

class Snake extends Animal
{
    Snake(String name)
    {
        super(name);
    }
    void makesNoise()
    {
        System.out.println("Hiss");
    }
}

class Horse extends Animal
{
    Horse(String name)
    {
        super(name);
    }
    void makesNoise()
    {
        System.out.println("Whinny");
    }

}



MyArrayList.java




public class MyArrayList<E> {
    Object[] container;
    int numElements =0;

    public MyArrayList(int initialSize)
    {
        container = new Object[initialSize];
    }
    public MyArrayList()
    {
        this(10);
    }

    public int size()
    {
        return numElements;
    }
    public void add(E ob)
    {
        if (numElements >= container.length)
        {
            resize();
        }
        container[numElements++] = ob;
    }
    public E get(int index)
    {
        if (index < 0 || index >= numElements)
            throw new IndexOutOfBoundsException("Index out of bounds");
        return (E)container[index];
    }

    private void resize()
    {
        int currSize = container.length;
        Object[] nextContainer = new Object[currSize*2];
        for (int i=0; i < numElements; i++)
            nextContainer[i] = container[i];

        container = nextContainer;
    }
    public E set(int index, E ob)
    {
        if (index < 0  || index >= numElements)
            throw new IndexOutOfBoundsException("Index out of bounds: "+ index);
        E replacedObject = (E)container[index];
        container[index] = ob;

        return replacedObject;
    }
    // Inserts object at desired location
    public void add(int index, E ob)
    {
        if (index < 0  || index > numElements)
            throw new IndexOutOfBoundsException("Index out of bounds: "+ index);
        add(ob); // This will increase our size by 1
        // Shift objects to make room for the new addition
        for (int i= numElements-1; i > index; i--)
        {
            container[i] = container[i-1];
        }
        container[index] = ob;
    }

    // For this to work, the objects need to implement equals
    public int indexOf(E ob)
    {
        for (int i=0; i < numElements; i++)
        {
            if (ob.equals(container[i]))
                return i;
        }
        return -1;
    }

    public E remove(int index)
    {
        if (index < 0  || index >= numElements)
            throw new IndexOutOfBoundsException("Index out of bounds: "+ index);

        // Shift everything down
        E removedObject = (E)container[index];
        for (int i= index; i < numElements-1; i++)
        {
            container[i] = container[i+1];
        }
        numElements -= 1;
        return removedObject;
    }

    // for this to work, the objects need to implement equals
    public boolean remove (E ob)
    {
        int index = indexOf(ob);
        if (index < 0)
            return false;

        remove(index);
        return true;
    }

    public String toString()
    {
        StringBuilder sb= new StringBuilder();
        sb.append("[ ");
        for (int i=0; i < numElements; i++)
        {
            sb.append(container[i].toString());
            if (i < numElements-1)
                sb.append(",");
        }
        sb.append(" ]");
        return sb.toString();
    }

}


ArrayListDemo2.java


public class ArrayListDemo2 {


    public static void main(String[] args) {
        MyArrayList<String> arr = new MyArrayList<String>(20);

        arr.add("one");
        arr.add("three");

        arr.add(1, "two");
        System.out.println("after 3 adds: " + arr);

        arr.add("abc");
        System.out.println("after adding abc: " + arr);
        arr.set(3, "four");
        System.out.println("after set(3,four): " + arr);

        try
        {
            arr.set(4, "five");
        }
        catch (IndexOutOfBoundsException e)
        {
            System.out.println("Can't do a set on an index that doesn't exist yet: "+e);
        }

        arr.add(4, "five");
        System.out.println("after 5 adds: " + arr);

        try
        {
            arr.add(6, "seven");
        }
        catch (IndexOutOfBoundsException e)
        {
            System.out.println("Can't do an add in such a way as to leave a gap: "+e);
        }
        System.out.println("after all successful adds: " + arr);

        // Note that using indexOf requires implementing "equals".
        // If we were adding our dog class, we would need an equals method otherwise it
        // won't find what we are looking for.
        int index = arr.indexOf("three");
        System.out.println("The index of three is :" + index);

        index = arr.indexOf("seven");
        System.out.println("The index of seven is :" + index);

        // The following will require the implementation of "equals"
        arr.remove("two");
        System.out.println("after removing two: " + arr);

        arr.remove(0);
        System.out.println("after removing index 0: " + arr);

        System.out.println("Final size="+ arr.size());

    }

}



Last Updated: 23 October, 2013 0:11 AM