6

整数型を使用すると、次のことができます。

int lowest = Integer.MIN_VALUE;

ジェネリックを使用した場合はどうすればよいですか?

K lowest = <...>;

PriorityQueueに似たものを実装するためにこれが必要です。キューから削除したいノードにアクセスできますが、最小値ではありません。

1. I need to make it the min by decreasing the key of that node,
2. And then remove the min.

私は最初のステップで立ち往生しています。私ができる唯一のことは、ノードのキーを現在の最小値に設定することです。十分かどうかはわかりません。

4

10 に答える 10

5

私は、どのようなシナリオでそのような動作が必要になるかを想像しようとしています。これは私が思いつくことができる最高です...

警告:このコードは危険です。そのような忌まわしきものを投稿してくれて、私を憐れんでください。これは概念実証にすぎません。

public class Lowest<K> implements Comparable<K> {
    public int compareTo(K other) {
        return -1;
    }
}

その後...

public class Test {
    public <K extends Comparable<K>> K findMaximum(List<K> values) throws Exception {
        K lowest = (K) new Lowest<K>(); /// XXX DANGER! Losing compile-time safety!!!

        K maximum = lowest;
        for (K value : values) {
            if (maximum.compareTo(value) < 0) {
                maximum = value;
            }
        }

        if (maximum == lowest) {
            throw new Exception("Could not find a maximum value");
        } else {
            return maximum;
        }
    }
}
于 2009-04-29T18:33:32.013 に答える
5

MIN_VALUEすべての比較可能なタイプの、またはすべての比較可能なタイプの一般的な形式はありませんMAX_VALUE

Time同等のものを実装するクラスについて考えてみてください。MAX_VALUE比較可能であるにもかかわらず、時間はありません。

于 2009-04-29T18:15:50.683 に答える
4

これは意味がありません...

その時点でKが何であるかがわからない場合(つまり、一般的にKを実装している場合は...ええと!)、Kの最小/最大境界を指定することはできません。

Kがint、long、string ORオブジェクトである可能性がある場合、使用することを賢明に推測することはできませんでした

Integer.MIN_VALUE、""またはNULL。

あなたが探しているのはK.MIN_VALUE_OF_EVENTUAL_TYPEだと思いますが、それは存在しません。

于 2009-04-29T18:15:41.557 に答える
4

すべてのタイプに最小値と最大値を「追加」するラッパークラスを作成できます。最小値と最大値を表す2つの静的インスタンスがあり、他のインスタンスはあるタイプの他の値をラップします。比較を行うときは、いずれかが最小か最大かを確認し、適切な結果を返します。それ以外の場合は、基になるタイプと同じ比較を行います。このようなもの:

class Extended<T extends Comparable<? super T>> implements Comparable<Extended<T>> {
    private Extended() { }

    private static Extended min = new Extended();
    private static Extended max = new Extended();

    @SuppressWarnings("unchecked")
    public static <T extends Comparable<? super T>> Extended<T> getMin() {
        return (Extended<T>)min;
    }
    @SuppressWarnings("unchecked")
    public static <T extends Comparable<? super T>> Extended<T> getMax() {
        return (Extended<T>)max;
    }

    public T value;

    public Extended(T x) { value = x; }

    public int compareTo(Extended<T> other) {
        if (this == other) return 0;
        else if (this == min || other == max) return -1;
        else if (this == max || other == min) return 1;
        else return this.value.compareTo(other.value);
    }
}
于 2009-04-29T21:41:43.107 に答える
2

Kジェネリックを作成するのではなく、プリミティブラッパー(ダブルラッパー!)をラップするインターフェイスを使用することを検討してください。

import java.util.HashMap;


public class NodeWrapper<K extends Comparable<K>> implements Comparable<NodeWrapper<K>> {

    private static HashMap<Class, NodeWrapper> minVals = new HashMap<Class, NodeWrapper>();

    private K value;

    private NodeWrapper() {
        super();
    }

    public NodeWrapper(K value, Class<K> clazz) {
        super();
        this.value = value;

        if (minVals.get(clazz)==null) {
            minVals.put(clazz, new NodeWrapper<K>());
        }
    }

    public K getValue() {
        return value;
    }

    public static NodeWrapper getMinValue(Class clazz){
        return minVals.get(clazz);
    }

    public void setValue(K value) {
        this.value = value;
    }

    @Override
    public int compareTo(NodeWrapper<K> o) {
        NodeWrapper min = minVals.get(this.getClass());
        if (this==min && o==min)  {
            return 0;
        } else if (this==min){
            return -1;
        } else if (o==min){
            return 1;
        } else {
            return this.value.compareTo(o.value);
        }
    }

}

簡単に言うと、新しいクラスがインスタンス化されるたびに、最小値が作成され、各クラスの最小値を格納する静的ハッシュマップに配置されるという考え方です。(実際、これらの値はまったく何もありません。センチネルオブジェクトだけですが、オブジェクトの等価性を使用して、何かが最小値であるかどうかを判断するため、これはまったく問題ありません。)必要なのは、ラップされたオブジェクトが比較可能であることだけです。一般的にそれ自体の他のインスタンスに。

1つの欠点はgetMinValue、return型には一般的な情報がないため、呼び出すときにコンパイラの警告が表示されることです。これを回避するためのよりエレガントな方法があるかもしれませんが、私は今それを考えることができません。

この一般的な考え方は、全体的にかなり良いかもしれません。ただし、私は本当に強調する必要があります。これは、ポリモーフィズムまたは相互に比較可能なクラスの混合で試してみると、絶対に壊れます。 同じツリー内のLongsとsは完全にあなたを破壊します。Integer

于 2009-04-29T20:08:28.790 に答える
2

えーと…また何が問題なの?

PriorityQueueを使用すると、すべてのコレクションと同様に、オブジェクトのインスタンスを使用してコレクションからオブジェクトを削除できます。

于 2009-04-29T20:47:29.460 に答える
1

ええと、これはタイプKが何であるかに依存しませんか?

Genericsのポイントは、Kは任意のタイプ(または特定のタイプの任意のサブクラス)である可能性があるということです。Kのメソッドを呼び出したり、Kのプロパティにアクセスしたりできるようにするには、ワイルドカードを使用してその型の境界を制限する必要があります。

于 2009-04-29T18:05:33.857 に答える
1

オブジェクトが比較可能であるからといって、それが最小値を持っている必要があるという意味ではありません。intの最小値が-(2 ^(31))である理由は、符号に1ビットが必要なためです。したがって、2 ^ 31は、格納できる最大(または最小)の整数です。文字列のようなものについては、可能な最大/最小の文字列がないため、それは意味がありません。それはメモリにバインドされています。

于 2009-04-29T18:16:24.767 に答える
1

インターフェイス「IInfinity」を作成し、KでIInfinityを拡張し、IInfinityでメソッド「getInfinityValue()」を作成してから、IInfinityを実装するクラスでInteger、Double、BigDecimalなどをラップ/拡張する必要がある場合があります。そして、うーん!

于 2009-04-29T18:16:32.957 に答える
1

基本的に、任意のタイプKに、標準の数学的特性に従う最低および最高などの静的関数を実装する必要があります。

この最低(または最高)の感覚を使用できるようにするには、Comparableオブジェクトにこれらのメソッドを持たせる必要があると思います。(または静的フィールド)。独自のカスタムオブジェクトのみに関心がある場合、これを行う方法は、MINVALUEおよびMAX_VALUEの静的フィールドを宣言した抽象データ型からすべてを継承することです。その後、型変数はになります。他のクラスでこの機能が必要な場合は、さまざまなクラスのこれらのプロパティを追跡するある種の外部ハッシュマップを作成する必要があります(ただし、かなり醜くなります)

于 2009-04-29T18:17:07.107 に答える