views:

244

answers:

3

Lasty, I tried to implements an hybrid structure in Java, something that looks like:

public class MapOfSet<K, V extends HasKey<K>> implements Set<V>, Map<K, Set<V>>

Where HasKey is the following interface:

public interface HasKey<K> {
    public K getKey();
}

Unfortunately, there are some conflicts between methos signature of the Set interface and the Map interface in Java. I've finally chosen to implements only the Set interface and to add the Map method without implementing this interface.

Do you see a nicer solution?

In response to the first comments, here is my goal:

Have a set structure and be able to efficiently access to a subset of values of this set, corresponding to a given key value. At the beginning I instantiated a map and a set, but I tried to joined the two structures to optimize performances.

A: 

I would say that something that is meant to be sometimes used as a Map and sometimes as a Set should implement Map, since that can be viewed as a set of keys or values as well as a mapping between keys and values. That is what the Map.containsKey() and Map.containsValue() methods are for.

Avi
Yep, but as yo can see, in my case, the signature of containsValue is containsValue(Set<V> s) but what I need to check and easily access to members of the V class.
Nicolas
+3  A: 

What are you trying to accomplish? Map already exposes its keys as a Set via its keySet() method. If you want a reliable iteratior order, there's LinkedHashMap and TreeMap.

UPDATE: If you want to ensure that a value has only been inserted once, you can extend one of the classes I mentioned above to create something like a SingleEntryMap and override the implementation of put(K key, V value) to do a uniqueness check and throw an Exception when the value has already been inserted.

UPDATE: Will something like this work? (I don't have my editor up, so this may not compile)

public final class KeyedSets<K, V> implements Map<K,Set<V>> {
    private final Map<K, Set<V>> internalMap = new TreeMap<K, Set<V>>;
    // delegate methods go here
    public Set<V> getSortedSuperset() {
        final Set<V> superset = new TreeSet<V>();
        for (final Map.Entry<K, V> entry : internalMap.entrySet()) {
            superset.addAll(entry.getValue());
        }
        return superset;
    }
}
Hank Gay
The use of hte generics should show you what I expect to do : sort a set of values according to a key and use a map to easily access to a given subset of values.
Nicolas
So can you guarantee that any arbitrary subset only has one key?
Hank Gay
Yep, When I create the subset accordingly, usign the getKey method of the HasKey interface desribed in the original post.
Nicolas
+1  A: 

Perhaps you could add more information which operations do you really want. I guess you want to create a set which automatically groups their elements by a key, right? The question is which operations do you want to be able to have? How are elements added to the Set? Can elements be deleted by removing them from a grouped view? My proposal would be an interface like that:

public interface GroupedSet<K, V extends HasKey<K>> extends Set<V>{
    Set<V> havingKey(K k);
}

If you want to be able to use the Set as map you can add another method

Map<K,Set<V>> asMap();

That avoids the use of multiple interface inheritance and the resulting problems.

jrudolph
I do not really need the interface in my case but I like the asMap idea... Think I'm gonna borrow this one. Thanks.
Nicolas