I've been bouncing back and forth with myself and different people with different opinions on this, so I ask the opinions of my fellow javaranchers to help me come to a conclusion.
I have a situation where I am retrieving records from a database that have a unique composite key. These records are then stored into a Map by the composite key and the object that represents the fields in the record (which also includes the composite key fields).
I implemented this as a collection by extending AbstractCollection and using the Map as the internal structure. The difference between this collection and any other collection though is that is works primarily by the composite key. For example:
coll.contains(obj) returns true is the composite key of obj is found in the Map
coll.remove(obj) removes the object from the collection where the composite key of obj is found in the Map.
I also added some other methods such as:
removeAllValue(Collection c) that removes all the objects from the collection where the objects in c are found by value in the Map (containsValue).
This works real well for set operations where I am comparing a collection from a flat file to what is already in the database. With these operations and the combination of cloneing I can do things like this:
process(Collection fileCollection, Collection dbCollection)
{
Collection updateCollection = fileCollection.clone();
updateCollection.retainAll(dbCollection);
updateCollection.removeAllValue(dbCollection);
update(updateCollection);
Collection insertCollection = fileCollection.clone();
insertCollection.removeAll(dbCollection);
insert(insertCollection);
Collection deleteCollection = dbCollection.clone();
deleteCollection.removeAll(fileCollection);
delete(deleteCollection);
}
This code essentially does 3 things:
1) Keep all the objects in the file collection that are contained (by compositekey) in the db collection, and remove all those where the objects are equal by value. This will leave only the objects in the collection that need updating in the database.
2) Remove all the objects in the file collection that are contained (by compositekey) in the db collection. This will leave only the objects in the collection that need inserting into the database.
3) Remove all the objects from the db collection that are contained (again by compositekey) in the file collection. This will leave only the objects in the collection that need to be deleted from the database.
This functionality seems so common that I'm surprised no one has come up with a common collection class or
pattern that does this.
Has anyone else come up with, or has the need for, a hybrid Collection-backed-by-Map-using-keys solution?
Am I breaking all the rules for a Collection implementation by doing this (because the behavior of contains and other collection methods are different)?
Some have told me I should almost never implement or extend Collection or Map, but use the concrete versions available (HashSet, ArrayList, HashMap,etc) with helper classes. Others have said that I should create a collection type object but not implement or extend Collection and only implement the methods needed for the requirements.
I mainly am looking for any other similar examples or experiences so I can draw info from them.
Thanks,
John Brown