title: Java creating a custom Map
body: <p>I have two questions regarding my following code:</p>
  
  <p>1) Is there any way I can <code>implement Map</code> in this case, rather than extend just one direct implementation of the interface? I do not wish to write a whole Map implementation though. But it could be nice seeing that my implementation does not care what underlying Map implementation is being used.
  2) Are there any bad practices?</p>
  
  <p>ExtremesMap.java</p>
  
  <pre><code>package ocr.util;
  
  import java.util.Arrays;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Set;
  
  /**
   *
   * @author student
   */
  public class ExtremesMap extends HashMap&lt;String, Integer&gt; {
      private Set&lt;String&gt; smallest;
      private int smallestValue;
  
      private Set&lt;String&gt; biggest;
      private int biggestValue;
  
      public ExtremesMap() {
          super();
          smallest = new HashSet&lt;&gt;();
          smallestValue = Integer.MAX_VALUE;
          biggest = new HashSet&lt;&gt;();
          biggestValue = Integer.MIN_VALUE;
      }
  
      @Override
      public void put(String key, Integer value) {
          if (value == null) {
              throw new IllegalArgumentException("ocr.util.ExtremesMap.put: value == null");
          }
          //TODO for real performance application implement own type of Map directly
          Integer retrieveValue = super.get(key);
          if (retrieveValue != null) {
              throw new IllegalStateException("ocr.util.ExtremesMap.put: Not allowed to modify existing value: key = " + key);
          }
          else if (retrieveValue == value) {
              return;
          }
          super.put(key, value);
          if (value &lt; smallestValue) {
              smallest = new HashSet&lt;&gt;();
              smallestValue = value;
          }
          else if (value == smallestValue) {
              smallest.add(key);
          }
          if (value &gt; biggestValue) {
              biggest = new HashSet&lt;&gt;();
              biggestValue = value;
          }
          else if (value == biggestValue) {
              biggest.add(key);
          }
      }
  
      public String getSmallestString() {
          if (smallest.size() != 1) {
              throw new IllegalStateException("ocr.util.ExtremesMap.getSmallest: smallest.size() != 1: smallest.size() = " + smallest.size());
          }
          return smallest.iterator().next();
      }
  
      public Set&lt;String&gt; getSmallestSet() {
          return smallest;
      }
  
      public List&lt;String&gt; getSmallestList() {
          return Arrays.asList(getSmallestArray());
      }
  
      public String[] getSmallestArray() {
          return smallest.toArray(new String[smallest.size()]);
      }
  
      public String getBiggestString() {
          if (biggest.size() != 1) {
              throw new IllegalStateException("ocr.util.ExtremesMap.getBiggest: biggest.size() != 1: biggest.size() = " + biggest.size());
          }
          return biggest.iterator().next();
      }
  
      public Set&lt;String&gt; getBiggestSet() {
          return biggest;
      }
  
      public List&lt;String&gt; getBiggestList() {
          return Arrays.asList(getBiggestArray());
      }
  
      public String[] getBiggestArray() {
          return biggest.toArray(new String[biggest.size()]);
      }
  }
  </code></pre>
  
  <p>Also there is one bug which I am unable to resolve in <code>put()</code>:</p>
  
  <p>method does not override or implement a method from a supertype</p>
  
  <pre><code>put(String,Integer) in ExtremesMap cannot implement put(K,V) in Map
    return type void is not compatible with Integer
    where K,V are type-variables:
      K extends Object declared in interface Map
      V extends Object declared in interface Map
  </code></pre>
  
  <p>What exactly goes wrong here?</p>
  
  <p>Regards.</p>