001package edu.pdx.cs410J;
002
003import java.util.*;
004
005/**
006 * This is the abstract superclass of an "LRU Map".  An LRU Map is a
007 * Java {@link Map} that has a bounded number of mappings.  If a new
008 * mapping is added to an LRU Map that already has the maximum number
009 * of mappings, then the least recently used mapping is removed.  An
010 * element is used when it is added to or gotten from the Map.
011 */
012public abstract class AbstractLRUMap<K, V> extends AbstractMap<K, V> {
013
014  /** The maximum number of mappings that this map can hold */
015  protected int capacity;
016
017  ///////////////////////  Constructors  ///////////////////////
018
019  /**
020   * Creates a new LRU Map that will hold a given number of mappings
021   *
022   * @param capacity The maximum number of mappings in this map
023   * @throws IllegalArgumentException
024   *         <code>capacity</code> is negative
025   */
026  protected AbstractLRUMap(int capacity) {
027    if (capacity < 0) {
028      String s = "Max mappings must be greater than 0";
029      throw new IllegalArgumentException(s);
030    }
031
032    this.capacity = capacity;
033  }
034
035  /**
036   * Returns the names of the students who implemented this LRU Map.
037   */
038  public abstract List<String> getStudentNames();
039
040  /**
041   * When a mapping is made in an LRU that already contains the
042   * maximum number of mappings, the Least Recently Used element is
043   * removed.
044   */
045  public abstract V put(K key, V value);
046
047  /**
048   * Getting an element from a map marks the mapping as "used".  Note
049   * that the type of <code>key</code> must be <code>Object</code>
050   * so that, after type erasure, it will be compatible with the
051   * pre-generic API.
052   */
053  public abstract V get(Object key);
054
055        /**
056         * Removes the given key from this map.  Note that the type of
057         * <code>key</code> must be <code>Object</code> so that, after type
058         * erasure, it will be compatible with the pre-generic API.
059         */
060  public abstract V remove(Object key);
061
062  public void putAll(Map<? extends K, ? extends V> map) {
063    for (K key : map.keySet()) {
064      V value = map.get(key);
065      this.put(key, value);
066    }
067
068    // I couldn't figure out how to use the entrySet().  Nasty.
069//    Iterator<Map.Entry<? extends K, ? extends V>> iter = map.entrySet().iterator();
070//     while (iter.hasNext()) {
071//       Map.Entry<? extends K, ? extends V> entry = iter.next();
072//       this.put(entry.getKey(), entry.getValue());
073//     }
074  }
075
076  public abstract void clear();
077
078}