// Constructor templates for IMapList: // new IMapList (rktList) // new IMapList () // Interpretation: // rktList is a RacketList // containing the key/value pairs of the IMap // where no key is the key for two different key/value pairs // if rktList is omitted, creates an empty map import java.util.Map; import java.util.Map.Entry; import java.util.AbstractMap.SimpleImmutableEntry; import java.util.List; import java.util.ArrayList; import java.util.Iterator; // Strategy: extends IMapBase final class IMapList extends IMapBase { RacketList> entries; // set of key/value pairs // Java constructors IMapList () { this.entries = RacketLists.empty(); } IMapList (RacketList> entries) { this.entries = entries; } // abstract methods listed by Map interface public int size () { return RacketLists.length (entries); } // abstract methods listed by IMap interface // Returns an IMap like this one except the given key is associated // with the given value. The extend operation does not modify this // IMap. public IMap extend (K key, V value) { Entry entry = new SimpleImmutableEntry (key, value); return new IMapList (extended (entries, entry)); } // abstract methods declared in IMapBase // Returns true iff this map has a mapping for the given key. protected boolean hasKey (K key) { RacketList> lst = entries; while (! (lst.isEmpty())) { if (lst.first().getKey().equals (key)) return true; lst = lst.rest(); } return false; } // Returns the value associated with the given key. protected V getVal (K key) { RacketList> lst = entries; while (! (lst.isEmpty())) { if (lst.first().getKey().equals (key)) return lst.first().getValue(); lst = lst.rest(); } String badKeyMsg = "key not found in IMap: "; throw new IllegalArgumentException(badKeyMsg + key); } // Returns an iterator for the keys of this IMap. protected Iterator keyIterator() { RacketList> lst = entries; List keys = new ArrayList(); while (! (lst.isEmpty())) { keys.add (lst.first().getKey()); lst = lst.rest(); } return keys.iterator(); } // all other public methods are defined by AbstractMap // private help methods // Given a RacketList of entries and an entry with key k, // returns a RacketList in which the given entry replaces // any entry with key k or, if the given RacketList of entries // contains no entry with key k, returns a RacketList with // the given entry added to it. // // This method has no side effects. private RacketList> extended (RacketList> entries, Entry entry) { if (entries.isEmpty()) { return entries.cons (entry); } if (entries.first().getKey().equals (entry.getKey())) { return entries.rest().cons (entry); } else return extended (entries.rest(), entry).cons (entries.first()); } }