Java creating a custom Map

dictionary, java

Solution

As the error says, the `put` signature is:

 V put(K key, V value)

That means that your method `put` should return `Integer` and not `void`:

public Integer put(String key, Integer value) { ... }

Concerning your first two questions, I would say that it is not a recommended practice to extend `HashMap`, because you are changing the way a Map is working when you override `put`. You should better use composition instead (a normal class which contains a private field `Map` for internal use).

For a whole code review of your code, you could ask at Code Review StackExchange.

Problem

I have two questions regarding my following code: 1) Is there any way I can `implement Map` 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? ExtremesMap.java ``` 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<String, Integer> { private Set<String> smallest; private int smallestValue; private Set<String> biggest; private int biggestValue; public ExtremesMap() { super(); smallest = new HashSet<>(); smallestValue = Integer.MAX_VALUE; biggest = new HashSet<>(); 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 < smallestValue) { smallest = new HashSet<>(); smallestValue = value; } else if (value == smallestValue) { smallest.add(key); } if (value > biggestValue) { biggest = new HashSet<>(); 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<String> getSmallestSet() { return smallest; } public List<String> 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<String> getBiggestSet() { return biggest; } public List<String> getBiggestList() { return Arrays.asList(getBiggestArray()); } public String[] getBiggestArray() { return biggest.toArray(new String[biggest.size()]); } } ``` Also there is one bug which I am unable to resolve in `put()`: method does not override or implement a method from a supertype ``` 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 ``` What exactly goes wrong here? Regards.

Original source