Question

I am practicing programming with generic classes. I want to implement a class for a list element that holds a reference on an object of generic type and a reference on the next list element.

So I came up with this class:

class List<T>{
    T val;
    List next:
}

How would you define the constructor for this class? Any other advice to understand generic classes and their use?

Was it helpful?

Solution

you can leave it with default constructor and then use it List<String> list = new List<String>(); - now val in your class will be String. Another way:

public class List<T>{
    T val;
    List<T> next;

    public List(T val, List<T> next) {
        this.val = val;
        this.next = next;
    };

    public T getVal() {
        return val;
    }
}

And then you can use it this way:

List<String> strList = new List<String>("test", null);
System.out.println( strList.getVal() );

as result "test" should be printed

As for advice, I think the best thing is to read this book: Java Generics and Collections it contains good description and a lot of examples how to use it.

OTHER TIPS

This is a great resource for helping you get your head round generics:

http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html

It maybe helpful for you to look at a LinkedList for what you're trying to do.

Javadoc: http://download.oracle.com/javase/6/docs/api/java/util/LinkedList.html Both the source and the Java API docs can be downloaded here: http://www.oracle.com/technetwork/java/javase/downloads/index.html

You'll be able to look through the source and see how it is actually implemented with Generics in Java.

At first glance, I thought you were going for more of a LISP style collection where you'd have a "head" element and a "tail" list. Tossing together some code gave me this:

package generic.list;

import java.util.List;

public class GenericList<T>
{
    private T head;

    private GenericList<T> tail;

    public GenericList(List<T> initialList)
    {
        if ( !initialList.isEmpty() )
        {
            head = initialList.get(0);

            if ( initialList.size() > 1 )
            {
                tail = new GenericList<T>(initialList.subList(1, initialList.size()));
            }
        }
    }

    public T getHead()
    {
        return head;
    }

    public GenericList<T> getTail()
    {
        return tail;
    }
}

While this sort of structure can lead to some really great investigations of recursive algorithms, it really doesn't do a whole heck of a lot for you when you're trying to learn generics. That said, here's a quick test bed I wrote to make sure this actually worked:


package generic.list;

import static org.junit.Assert.*;

import java.util.Arrays;

import org.junit.Test;

public class GenericListTest
{
    private GenericList l;

    @Test
    public void testConstructorNoElements()
    {
        l = new GenericList(Arrays.asList(new String[] {}));

        assertNull(l.getHead());
        assertNull(l.getTail());
    }

    @Test
    public void testConstructorOneElement()
    {
        l = new GenericList(Arrays.asList("One"));

        assertNotNull(l.getHead());
        assertEquals("One", l.getHead());
        assertNull(l.getTail());
    }

    @Test
    public void testConstructorMultipleElements()
    {
        l = new GenericList(Arrays.asList("One", "Two", "Three"));

        assertNotNull(l.getHead());
        assertEquals("One", l.getHead());

        assertNotNull(l.getTail());
        assertEquals(l.getTail().getHead(), "Two");
        assertEquals(l.getTail().getTail().getHead(), "Three");
        assertNull(l.getTail().getTail().getTail());
    }
}

That should at least give you a better idea of how to instantiate and utilize a generic class.

You can find an online lesson at http://download.oracle.com/javase/tutorial/java/generics/index.html.

The biggest thing to understand about generics is that, when you list "T" in the name of the class (as in "GenericList"), T becomes a class for the scope of this class. No classes outside of GenericList know what T is and GenericList doesn't even really know what it is - all it knows is that, everywhere you see a T, it'll be the same type as a T somewhere else. So, while GenericList doesn't necessarily know what it's storing, it does know that the type of "head" (T) is the same type as the objects being passed in via initialList.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top