3

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.

1
  • AbstractMap provides typical map functionality (see JavaDoc). For your put method, it has to return an Integer, as the error clearly states. Commented Aug 26, 2013 at 7:59

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.