3

次のコードに関して 2 つの質問があります。

1)implement Mapこの場合、インターフェイスの直接実装を1つだけ拡張するのではなく、できる方法はありますか? ただし、 Map 実装全体を書きたいわけではありません。しかし、私の実装が、基礎となる Map 実装が使用されているかどうかを気にしないことを確認できれば、それは素晴らしいことです。2) 悪い習慣はありますか?

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()]);
    }
}

また、解決できないバグが 1 つありますput()

メソッドは、スーパータイプのメソッドをオーバーライドまたは実装しません

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

ここで正確に何がうまくいかないのですか?

よろしく。

4

1 に答える 1

4

エラーが示すように、put署名は次のとおりです。

 V put(K key, V value)

つまり、あなたのメソッドputは返されるべきIntegerではなく、返されるべきvoidです:

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

HashMap最初の 2 つの質問に関しては、オーバーライドするときに Map の動作方法を変更しているため、拡張することはお勧めできませんputMap代わりにコンポジション (内部使用のためのプライベート フィールドを含む通常のクラス) を使用することをお勧めします。

コード全体のコード レビューについては、Code Review StackExchangeで質問できます。

于 2013-08-26T07:59:00.950 に答える