Use Collection classes or create wrappers for them?

L

Lucas White

Hi,

Is it considered good practice to wrap the Collection implementation
classes? For example, if I have a list of animals, should I just
have:

List animals = new ArrayList();
animals.add(new Animal("Cat"));
....

Or should I have an AnimalCollection class which encapsulates the
list's workings. That way I could make sure every object added to my
animal list was an Animal object, whereas any object could be added to
a List that isn't wrapped.

Any ideas on the positives and negatives of both approaches? If I'm
not being clear, let me know and I'll explain further.

Thanks,
Lucas
 
M

Matt Humphrey

Lucas White said:
Hi,

Is it considered good practice to wrap the Collection implementation
classes? For example, if I have a list of animals, should I just
have:

List animals = new ArrayList();
animals.add(new Animal("Cat"));
...

Or should I have an AnimalCollection class which encapsulates the
list's workings. That way I could make sure every object added to my
animal list was an Animal object, whereas any object could be added to
a List that isn't wrapped.

Any ideas on the positives and negatives of both approaches? If I'm
not being clear, let me know and I'll explain further.

Thanks,
Lucas

For me, whether to use a collection directly or to wrap depends on several
factors
1) if the collection is a main application object or is used from several
locations, I will probably wrap it.
2) if the collection has special semantics (uniqueness, multple indexes,
etc) I will wrap it.
3) if wrapping makes the design clearer, I will wrap it.
4) if the wrapping serves no purpose (as is often the case--the collection
is internal to another class and has no special semantics) I will not wrap
it.

Cheers,
 
S

Sajjad Lateef

Hi,

Is it considered good practice to wrap the Collection implementation
classes? For example, if I have a list of animals, should I just
have:

List animals = new ArrayList();
animals.add(new Animal("Cat"));
...

Or should I have an AnimalCollection class which encapsulates the
list's workings. That way I could make sure every object added to my
animal list was an Animal object, whereas any object could be added to
a List that isn't wrapped.

The answer is: it depends.

Some general guidelines:

If you are writing something that will be used as is, then you could
get away with just using the classes.

If you are writing something that will be extended later (perhaps
you will want to have a collection class for mammals and birds),
you will want to have a AnimalCollection class. If you feel that your
code will be re-used and should support easy re-use, then you could
extend the collection class.

I guess it all depends on your project's particulars. Please consult
with your senior team members and decide what works best for
your project and future expectations of the code.

Sajjad
 
H

Harald Hein

Lucas White said:
Or should I have an AnimalCollection class which encapsulates the
list's workings.

I have given up encapsulation some time ago. If you encapsulate a
collection in an own class, not derived from the collection you
encapsulate, the collection is no longer type compatible with the
collection classes. So you can't use any existing method that expects
such a collection.

You can make the encapsulation class type compatible by implementing
the necessary interfaces. If you do it, you are back to square one. You
have just added the methods you want to get rid of :-(

Alternatively you can implement conversion methods that return a copy
of the collection's content in a normal collection. If you have large
collections you might have to do a lot of copying. You could use such a
class e.g. for sorting, but then you have the problem of geting the
result back into your encapsulation class. You would have to code some
checks to prevents feeding back collections containing other objects
than the ones you want.

If you directly derive the encapsulation class from some collection
class you anyhow inherit the interface implementations. So you have the
same problems, too.

If you really want type save collections, look at and wait for Java
1.5.
 
A

Anand

Hi,

Is it considered good practice to wrap the Collection implementation
classes? For example, if I have a list of animals, should I just
have:

List animals = new ArrayList();
animals.add(new Animal("Cat"));
...

Or should I have an AnimalCollection class which encapsulates the
list's workings. That way I could make sure every object added to my
animal list was an Animal object, whereas any object could be added to
a List that isn't wrapped.

Any ideas on the positives and negatives of both approaches? If I'm
not being clear, let me know and I'll explain further.

Thanks,
Lucas

Java 1.5 will support generics.

http://developer.java.sun.com/developer/technicalArticles/releases/generics/

That should solve the static type checking problem. It may be some
time before you migrate to Java 1.5 but it's good to know what's
coming. Basically create wrappers if you think it adds a significant
value and improves clarity.

LinkedList<String> stringList = new LinkedList<String>();
stringList.add(new String("I am a String"));
stringList.add(new Integer(1)); // causes a compilation error
 
S

Sudsy

Anand said:
(e-mail address removed) (Lucas White) wrote in message news:<[email protected]>...


Java 1.5 will support generics.

http://developer.java.sun.com/developer/technicalArticles/releases/generics/

That should solve the static type checking problem. It may be some
time before you migrate to Java 1.5 but it's good to know what's
coming. Basically create wrappers if you think it adds a significant
value and improves clarity.

LinkedList<String> stringList = new LinkedList<String>();
stringList.add(new String("I am a String"));
stringList.add(new Integer(1)); // causes a compilation error

Another mechanism worthy of consideration involves simply extending
the base class and overriding the add method. Here's a basic example
using Vector:

class CustomVector extends Vector {
public boolean add( Object obj ) {
if( ! ( obj instanceof REQUIRED_CLASS ) )
throw( new IllegalArgumentException() );
return( super.add( obj ) );
}
}

Just replace REQUIRED_CLASS with the specific class desired.
Granted, it won't get caught at compile-time and will throw a run-
time exception, but at least you'll know what you've got insofar
as elements.
Just an addition to your bag of tricks.
(Yes, I know it'll accept subclasses...)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top