From: Simon Brooke on
I've been writing Java since Java 1.0, but three years ago I was switched
to the dark side, so I've been writing C# for a while; I'm refreshing my
Java skills and am certainly rusty. If this is a silly question please do
say so.

I'm trying to build a tiered map, such that when the map is searched for
a key, each tier is searched successively starting from the top one until
a value is found; in this way upper-tier key/value pairs can mask key/
value pairs in lower layers.

So I've started out:

/**
* A tiered map is a bit like a wedding cake. Each layer contains
* key/value pairs which mask key/value pairs in lower layers.
* @author simon
*
* @param <K> The class of which keys in this tiered map are members
* @param <V> The class of which values in this tiered map are members
*/
public class TieredMap<K,V> extends LinkedList<Map<K,V>> implements
Map<K,V>

Things all go swimmingly until I get to the method Remove(Object key).
The Map interface wants

public V remove(Object key)

but the superclass wants

public boolean remove( Object key)

Is there any way in which both can be satisfied?

Yes, I appreciate that the alternative would be to make TieredMap extend
Object and store the list of tiers a private instance variable; but that
seems a bit clunky. Is there a generic (pun intended) solution to this
problem?

--

;; Semper in faecibus sumus, sole profundam variat

From: Lew on
On 06/27/2010 05:55 PM, Simon Brooke wrote:
> I've been writing Java since Java 1.0, but three years ago I was switched
> to the dark side, so I've been writing C# for a while; I'm refreshing my
> Java skills and am certainly rusty. If this is a silly question please do
> say so.
>
> I'm trying to build a tiered map, such that when the map is searched for
> a key, each tier is searched successively starting from the top one until
> a value is found; in this way upper-tier key/value pairs can mask key/
> value pairs in lower layers.
>
> So I've started out:
>
> /**
> * A tiered map is a bit like a wedding cake. Each layer contains
> * key/value pairs which mask key/value pairs in lower layers.
> * @author simon
> *
> * @param<K> The class of which keys in this tiered map are members
> * @param<V> The class of which values in this tiered map are members
> */
> public class TieredMap<K,V> extends LinkedList<Map<K,V>> implements
> Map<K,V>
>
> Things all go swimmingly until I get to the method Remove(Object key) [sic].
> The Map interface wants
>
> public V remove(Object key)
>
> but the superclass wants
>
> public boolean remove( Object key)
>
> Is there any way in which both can be satisfied?
>
> Yes, I appreciate that the alternative would be to make TieredMap extend
> Object and store the list of tiers a private instance variable; but that
> seems a bit clunky. Is there a generic (pun intended) solution to this
> problem?

I don't think there's any way to inherit both List and Map; they're just too
different.

Instead of inheriting List, compose it. Your description indicates that you
want your type to /be-a/ Map, so don't have it /be-a/ List also.

The public shouldn't know that your type is a List, much less a LinkedList.
That should be a hidden detail of the implementation.

--
Lew
From: markspace on
Simon Brooke wrote:
>
> Is there any way in which both can be satisfied?


Not directly, no, I don't think so.

What you might consider is creating an object, then creating separate
List and Map views of that object.

public class TieredMap<K,V> // extends Object
{
....
public List<Map<K,V>> asList() { // gets a List interface
...

public Map<K,V> asMap() { // gets a Map interface
...

}

Theoretically best of both worlds here, although slightly inconvenient
to use.

From: Lew on
Roedy Green wrote:
>> Do you really want your object to behave directly as both a LinkedList
>> and a TierMap? That sounds like a very weird duck. LinkedList is a
>> detail of implementation, not likely something you want your clients to
>> fiddle with directly.

Simon Brooke wrote:
> No, it doesn't need to behave like a linked list at all, except that the
> caller needs to be able to add and remove tiers. In fact, a stack might
> be a better implementation than a linked list - the caller does not need
> to have direct access to lower level tiers.

This proves Roedy's point beautifully. If you do expose the 'List' (let alone
'LinkedList') detail of implementation, you commit to that as part of the
public contract and cannot easily change to 'Stack' when you realize that it
would improve things. Keep that part hidden as suggested.

Roedy Green wrote:
>> So create a class that does not extend LinkedList, but rather has
>> private field pointing to one. You can wrap some methods to fiddle with
>> the LinkedList externally if necessary.

Only expose publicly those aspects that are part of the public contract of the
type.

--
Lew